trading2026-08-10Β·8 minΒ·62/68

TRIX Backtest on BTC/USDT: Triple-Smoothing Momentum and the 25bp Cliff

The TRIX oscillator on real hourly BTC/USDT 2023: +111.94% naive, +64.74% with fees/funding, -39.65% at 25bp across 201 trades. A momentum line smooth enough to catch trends and active enough to pay for it.

TRIX Backtest on BTC/USDT (2023, hourly, real fees)

TRIX takes the triple-EMA idea from the TEMA post and applies it to momentum: triple-smooth the price, then take the percentage change of the smoothed line, then run a signal EMA over that. The result is a clean oscillator with almost none of the wiggle of a raw price-rate. Long when TRIX sits above its signal line β€” that was my rule, with the standard 15/9 periods. It posted the second-best naive momentum return of the lab (+111.94%), a solid +64.74% after fees and funding, and then a textbook 25bp cliff to -39.65%. The momentum family keeps telling the same story: smooth enough to be right, active enough to be expensive. Strategy Lab #32.

Results

StrategyCategoryTotal returnCAGRMaxDDSharpeTrades
trixmomentum+64.74%+64.97%-18.44%1.75201

TRIX vs buy & hold (2023, hourly, BTC/USDT)

The zero-cost run, +111.94% with a Sharpe of 2.56, is the momentum family's best β€” closer to buy & hold's +154.94% than anything in that family, with a tighter drawdown (-14.32%). TRIX's triple smoothing removes so much noise that its crosses genuinely mark the big swings of 2023. The problem is that it also marks them repeatedly: 201 trades.

The fee bill

| Scenario | Cost/leg | Total return | MaxDD | Sharpe | Trades | |---|---:|---:|---:|---:|---:|---:| | naive (zero cost) | 0.00% | +111.94% | -14.32% | 2.56 | 201 | | taker fee 0.05%/leg | 0.05% | +73.43% | -17.25% | 1.92 | 201 | | + funding 0.01%/8h | 0.05% | +64.74% | -18.44% | 1.75 | 201 | | + slippage 10bp/leg | 0.15% | +10.27% | -29.49% | 0.47 | 201 | | + slippage 25bp/leg | 0.30% | -39.65% | -50.47% | -1.43 | 201 |

TRIX cost scenarios (2023, hourly, BTC/USDT)

+111.94% β†’ -39.65%. The descent is gentle until the last column, then sudden: 401 legs at 25bp is ~25% of principal a year. Win rate 44.8% (90/201) β€” the same low-hit/high-payoff shape as every trend-family strategy. The honest reading of this table: TRIX is the best gross momentum strategy in the lab, and it still needs slippage under ~15bp to be worth running. That's not a criticism of TRIX; it's the fee reality every high-frequency idea meets.

The momentum family scoreboard (all hourly BTC, 2023)

StrategyTradesNaiveFees+funding25bp
MACD (post 15)333+79.08%+22.21%-76.89%
OBV (post 16)734+63.78%-24.95%-98.10%
ROC (post 31)700+97.20%-6.61%-97.19%
TRIX (this)201+111.94%+64.74%-39.65%
Awesome (post 34)216+84.99%+41.14%-52.04%
Momentum (post 35)785+74.31%-24.00%-98.51%

The ranking at every column follows trade count almost perfectly. TRIX trades the least and survives the best; Momentum and ROC trade constantly and collapse. Within one family, the strategy's frequency is a better predictor of survival than its indicator logic.

What this does NOT prove

  • 15/9 is the classic TRIX pair; the signal-period and the source (using log changes is common) are real knobs.
  • One strong-trend year is TRIX's ideal habitat β€” its triple smoothing is a trend tool wearing an oscillator costume.
  • The 201-trade churn suggests a filter (e.g., only long when ADX > 20, post 06) is the natural upgrade. That's the combination post 41 of this series explores.

Code

from backtest_base import fetch, backtest_signal, metrics

df = fetch("BTCUSDT", "binance", "2023-01-01", "2023-12-31", "1h")
c = df["close"]
e1 = c.ewm(span=15, adjust=False).mean()
e2 = e1.ewm(span=15, adjust=False).mean()
e3 = e2.ewm(span=15, adjust=False).mean()
trix = e3.pct_change().fillna(0.0)
sig  = trix.ewm(span=9, adjust=False).mean()

signal = (trix > sig).fillna(False)
res = backtest_signal(df, signal, cost_per_leg=0.0005,
                      funding_per_bar=0.0001 / 8.0)
print(metrics(res, 8760))

Reproduce it

cd blog-drafts/scripts
python backtest_base.py --strategy trix --symbol BTCUSDT --interval 1h \
    --start 2023-01-01 --end 2023-12-31 --fee 0.0005 --funding 0.0000125

Data: Binance public API, hourly OHLCV, 8,735 bars. The tables above reproduce exactly from this command.

This is a backtest on historical data, not investment advice. Past performance does not predict future results.