Overview
What this is and how the pieces fit together.
This is a backtest engine for rules-based Bitcoin trading strategies, with a dashboard to run and read the results. It ships with five strategies you can test as they are, or reconfigure through the controls: every parameter that defines a strategy is adjustable, so you can build your own variant without writing code. Signals come only from price, never from external inputs or discretion, so the same inputs always produce the same trades.
On top of that sits a live paper-trading bot. It runs one of these strategies, BB Channel Rider, continuously against real market data on a server, placing no real orders but logging every trade it takes. The Live Bot tab is its record. The distinction matters throughout: the backtest is a model of what a strategy would have done, the bot is a record of what one actually did.
The five strategies
BB Channel RiderMean reversion. Buys the lower Bollinger Band and sells the upper one, treating the channel as a range to trade across. The only validated strategy, and the one running live.
Bollinger BounceAlso mean reversion on the same bands, but waits for confirmation: price must close back inside the band after breaching it, rather than entering on the touch itself.
MA CrossTrend following. Enters when a fast moving average crosses a slow one, taking the crossover as a change of direction.
Price vs MATrend following, simpler. Enters when price closes through a single moving average, using it as the dividing line between up and down.
RSI ReversalMean reversion on momentum rather than price. Enters when RSI leaves oversold or overbought territory, on the view that the move has exhausted itself.
Only BB Channel Rider has been through full validation. The other four share the same engine and are there to test ideas against, not to be trusted as they stand, and results from them should be read in that light.
MA Cross
Trend following. Two moving averages over different lookbacks: the fast one reacts quickly to recent price, the slow one lags. When the fast crosses above the slow, recent prices have pulled decisively above the longer-run average, which is read as an uptrend beginning; the reverse is read as a downtrend. The intent is to hold a direction for as long as the trend persists and accept that turning points are always identified late, since a crossover can only be confirmed after the move has started.
Long signalFast MA crosses above slow MA (golden cross).
Short signalFast MA crosses below slow MA (death cross).
Fast / Slow periodLookback candles for each MA. Fast default 20, Slow default 50.
MA typeEMA (more weight on recent candles) or SMA (equal weight).
Best for trending markets with clear momentum shifts. Produces false signals in choppy, sideways conditions.
Price vs MA
Trend following, in its simplest form. A single moving average acts as the dividing line between an uptrend and a downtrend, and the strategy holds whichever side price closes on. It reacts faster than MA Cross because it needs only one line to be crossed rather than two to change order, which is an advantage in a clean trend and a liability in a choppy range, where price crosses back and forth repeatedly. Useful mainly as a baseline: any more complex trend strategy ought to beat it.
Long signalClose crosses above the MA.
Short signalClose crosses below the MA.
PeriodMA lookback window (default 50).
MA typeEMA or SMA.
Simpler and faster-reacting than MA Cross. More signals, more noise. Works well as a trend filter on higher timeframes.
Bollinger Bounce
Mean reversion, with confirmation. Bollinger Bands sit a set number of standard deviations either side of a moving average, so they widen when the market is volatile and contract when it is calm. Price reaching a band is unusual by construction. This strategy treats a breach as a stretched move likely to snap back, but does not act on the breach itself: it waits for price to close back inside the band first, taking that recovery as evidence the move is exhausted rather than continuing.
That confirmation is the whole difference between this and BB Channel Rider, which enters the moment price touches the band. Waiting costs a worse entry price, since the recovery has already begun, and it means missing moves that never close back inside. In exchange it avoids entering in front of a breakout that keeps going. Which trade-off is better is exactly the sort of question this engine exists to test.
Long signalPrevious close below lower band AND current close back above it (bounce).
Short signalPrevious close above upper band AND current close back below it (rejection).
PeriodRolling window for the mid-band SMA (default 20).
Std DevBand width multiplier. 2.0 covers ~95% of price action (default 2.0).
Mean-reversion strategy. Works in ranging markets; loses in strong trends where price walks the band.
BB Channel Rider
Mean reversion, taken at the touch. This treats the Bollinger channel as a range to be traded across: buy the lower band, sell the upper one, and take the width of the channel as the profit target. Where Bollinger Bounce waits for price to close back inside the band, this enters the instant the band is reached, on the view that the band level itself is where the edge is and waiting gives it away.
Because the target is the opposite band rather than a fixed distance, the strategy adapts to volatility automatically: a wide channel means a bigger target and a wider stop, a narrow one means both shrink. A trend filter keeps it from buying dips in a falling market, and when a position closes at target with price still at the band, it reverses immediately rather than sitting idle. Everything below is the exact specification, frozen on 2026-05-10 and running live since.
Entry
Long entryThe low of the forming candle reaches the lower band as computed from the last closed candle. The band is fixed before the candle opens, so the level is known in advance.
Short entryThe high of the forming candle reaches the upper band as computed from the last closed candle.
Entry priceThe band level itself, lower for longs and upper for shorts. Because that level is known before the candle opens, it can be resting as a limit order rather than chased.
Take Profit (tracking)
Long TPThe high reaches the upper band as of the last closed candle. The target is recomputed at every candle close, so it moves with the channel while the position is open.
Short TPThe low reaches the lower band as of the last closed candle, recomputed at every candle close.
Flip on TPTP hit → immediately opens opposite position (long→short or short→long) with no cooldown. The flip is skipped if the trend filter blocks the new direction.
Stop Loss & SL Snap
SL %Fixed percentage from entry. Set via the SL % slider in the sidebar.
SL Snap thresholdOnce price moves threshold % of the mid→band distance toward TP, the SL jumps to the mid-band. It then keeps trailing the mid-band on every later candle for the life of the trade — the trigger fires once, the trailing does not stop. Monotone throughout (never lowers a long SL, never raises a short SL).
Example — Long at $79,000, mid=$82,000, upper=$85,000, threshold=95% (the frozen value):
snap_trigger = $82,000 + 0.95 × ($85,000 − $82,000) = $84,850
When high ≥ $84,850 → SL jumps from $78,210 up to $82,000, then trails the mid-band from there
Worth noticing: at 95% the trigger ($84,850) sits only $150 below the take-profit ($85,000, the upper band). In any fast move the snap fires seconds before the exit and does nothing. Its real value is the stalled case — price loiters near the band, the bands recompute, the mid rises, and the SL trails up behind it.
Cooldown after SL
Cooldown NSet to 2 on the live bot. After a stop-loss, that direction waits for 2 candles to close back on the correct side of the entry band before it may re-enter. The other direction is unaffected. No stop-loss has occurred in live trading so far, so this has not yet been triggered.
Long cooldownN candles closing above the lower band. Wicks below do not reset the count.
Short cooldownN candles closing below the upper band.
Trend Filter (optional)
Trend EMAConfigurable EMA period. Default 150, matching the frozen live spec. Long entries only when close > EMA (uptrend context). Short entries only when close < EMA (downtrend context).
On chartYellow EMA line overlaid on the price chart when trend filter is enabled.
When to use this strategy
Best in ranging, sideways markets where price repeatedly bounces between bands. Avoid or enable the trend filter in strong directional trends, as price can walk the band and cause repeated stop-outs on the counter-trend side.
BB Channel Rider — Validation
A strategy has to clear two separate hurdles before it is trusted to run. They answer different questions.
Gate 1 — is it correct?
Run the strategy exactly as deployed over real data and check the results are what we think they are. The audit script imports the live strategy module directly, so it cannot measure anything other than what actually runs. Result in the spec card below.
Gate 2 — is it fragile?
Vary everything and see whether the result survives. Funding costs, position sizing, and 16,200 parameter combinations. If it only works at exact magic numbers, it is a fluke rather than an effect. Sections 1–3 below.
Gate 2 research completed 2026-05-10, before the live bot was built. Gate 1 re-run 2026-08-12.
Validated Strategy Spec (post grid search)
InstrumentBTC/USDT Perp · MEXC
Timeframe15m
BB Period / Std Dev20 / 3.0σ
Trend Filter EMA150 ↑ from 200
SL1.0% from entry
SL Snap Threshold95% ↑ from 85%
Cooldown Candles2
Leverage10×
Gate 1: 437 trades · 12 months · live-accurate fees · 25% sizing
53.8% WR · -$683.90 net · 72.8% max DD · out-of-sample since freeze: 57.8% WR, +$5.62 (breakeven)
1 · Funding Fees
MEXC settles perpetual funding every 8 hours (00:00 · 08:00 · 16:00 UTC). Longs pay at the prevailing rate; shorts receive.
Avg funding rate+0.003% per 8h period over the 11-month backtest window
Avg hold time~2.1h — most positions close before the next 8h settlement window
Total drag−$47.84 — measured on the superseded 100%-sizing baseline; scales with sizing, so ≈−$12 at the frozen 25%
✓ Verdict: negligible — funding does not materially affect the strategy at ~2h hold times. Taker fees, not funding, are the cost that matters: they consume roughly three quarters of the gross edge.
2 · Sizing Sweep
Compounding amplifies both gains and losses. The Calmar ratio (P&L ÷ Max DD) measures return per unit of worst-case pain — negative here at every sizing level, since the full-period figure (see above) is a net loss under the corrected evaluation. Doubling position size roughly doubles the loss along with the drawdown; there is no sizing level that turns a negative-EV full-period result positive.
| Sizing mode |
Net P&L |
Max DD |
Calmar |
| 10% of capital per trade |
-$352.49 |
39.44% |
-0.89 |
| 25% — frozen spec, live bot |
-$683.90 |
72.81% |
-0.94 |
| 50% of capital per trade |
-$919.70 |
93.72% |
-0.98 |
| 100% of capital per trade |
-$997.35 |
99.80% |
-1.00 |
This sweep uses the full-period backtest, which overlaps the parameter search and is the pessimistic figure for the same reason the out-of-sample result above is the honest one. It is shown to illustrate that compounding does not rescue a negative-EV period, not as a sizing recommendation — the out-of-sample window is roughly breakeven regardless of sizing.
3 · Parameter Grid Search
16,200 combinations across 6 dimensions: std_dev (2.0–4.0 step 0.25), sl_pct (0.5–2%), sl_thresh (55–95%), cooldown (1–4), EMA period (100–300), direction. Window 2025-06-01 → 2026-05-09; the spec was frozen the following day.
Read the rank correctly. The pre-search config (thresh 85%, EMA-200) ranked #242. Two parameters were then changed to the values ranking #14, and the spec was frozen the next day — so #14 is the result of choosing on this window, not independent evidence about it. The 67.5%-profitable figure and the #14/#242 ranks below predate a 2026-08-28 fix to two look-ahead bugs in the backtest itself (a band computed from the candle it was tested against, and a stop-loss threshold frozen at entry) and have not been re-run under the corrected simulate() — treat them as provisional, not current evidence, until Gate 2 is re-run. The actual validation is the out-of-sample period after the freeze, which the parameters never saw: 116 trades, 57.8% win rate, +$5.62, 18.1% max DD — essentially breakeven.
67.5%
of 16,200 combos profitable
#14
frozen params rank — a selection, not a validation
103/s
simulation speed (156s total)
Heatmap — Net P&L ($) by std_dev × SL%
Other dims fixed at original baseline: thresh=85%, cd=2, ema=200, both directions.
Negative
$1 – $1,999
$2,000 – $3,499
≥ $3,500
⭐ current params
| std \ SL% |
0.50% |
0.75% |
1.00% |
1.25% |
1.50% |
2.00% |
| 2.00 |
−4,319 |
−4,690 |
−4,480 |
−3,566 |
−4,396 |
−4,211 |
| 2.25 |
−1,197 |
−128 |
−184 |
−108 |
−772 |
−982 |
| 2.50 |
+1,561 |
+2,365 |
+1,864 |
+1,385 |
+1,904 |
+1,838 |
| 2.75 |
+3,455 |
+4,036 |
+2,345 |
+2,028 |
+2,911 |
+2,600 |
| 3.00 ⭐ |
+4,351 |
+3,603 |
+3,900 ⭐ |
+3,646 |
+4,335 |
+3,478 |
| 3.25 |
+3,669 |
+4,078 |
+3,568 |
+3,258 |
+2,543 |
+3,232 |
| 3.50 |
+2,284 |
+2,354 |
+2,400 |
+1,841 |
+948 |
+1,410 |
| 3.75 |
+1,361 |
+1,034 |
+604 |
+158 |
−784 |
−568 |
| 4.00 |
+1,732 |
+1,817 |
+1,199 |
+1,162 |
+789 |
+1,176 |
std=3.0 sits at the center of a wide green plateau (std 2.5–3.5, all SL values viable). Shifting ±0.25 std stays robustly positive — not an isolated spike.
Robustness by Parameter
Average net P&L when that value is fixed; all other dimensions are free. Higher = broadly good regardless of other settings.
| Parameter |
Value |
Avg P&L |
% Profitable |
Verdict |
| std_dev |
3.0 ⭐ |
+$2,116 |
83% |
Peak of smooth hill — keep |
| others |
varies |
— |
Drops off symmetrically on both sides |
| sl_pct |
1.0% ⭐ |
+$745 |
75% |
Marginal diff vs tighter — kept (overfitting risk on bull data) |
| 0.75% |
+$913 |
76% |
Best on 11-month window — may not generalise |
| sl_thresh |
95% ↑ adopted |
+$896 |
76% |
✓ Adopted — mechanically justified |
| 85% (prev) |
+$797 |
73% |
Previous default |
| ema_period |
150 ↑ adopted |
+$732 |
67% |
✓ Adopted — consistent outperformance |
| 200 (prev) |
+$620 |
65% |
Previous default |
| direction |
both ⭐ |
+$925 |
75% |
Kept — shorts avg −$144 but 11mo insufficient to cut permanently |
Parameter Changes Adopted (2026-05-10)
sl_thresh
85% → 95%
Later snap = fewer premature SL exits on volatile candles. Mechanically justified — not data-mined.
trend_period
200 → 150
Consistent outperformance across all tested window sizes. Faster EMA still filters the macro trend correctly.
RSI Reversal
Mean reversion on momentum rather than price. RSI measures how one-sided recent price action has been on a 0 to 100 scale: low readings mean sellers have dominated, high readings mean buyers have. Rather than entering while a reading is extreme, which can persist far longer than expected, this waits for RSI to leave the extreme, treating that exit as the point at which the one-sided pressure has run out. The sub-plot below the price chart shows the RSI line and its thresholds.
Long signalRSI crosses above the oversold threshold (default 30).
Short signalRSI crosses below the overbought threshold (default 70).
PeriodRSI lookback (default 14). Shorter = more reactive, more noise.
Oversold / OverboughtZone thresholds. Crossing the oversold line upward = long; crossing overbought downward = short.
Counter-trend / mean-reversion. RSI can stay extreme for many candles in strong trends, causing frequent stop-outs.
Backtest Controls
Every control that shapes a run, and what changing it does. Values marked live are the frozen BB Channel Rider settings the paper bot actually runs, so leaving them alone reproduces the live configuration.
Market & period
Candle TimeframeHow much time each candle covers. Shorter candles mean more signals and more fee-paying trades; longer ones mean fewer, larger positions. 15m is live. Changing this changes the strategy's behaviour completely, since every indicator is measured in candles, not hours.
Date RangeThe window to test. Leave both empty to use all cached history. A short window can show almost anything, so treat small samples with suspicion.
SymbolWhich market to test. BTC, ETH and SOL are one click; any other perpetual can be typed in. The live bot trades BTC only, and results on other symbols are exploratory.
Strategy parameters
StrategyWhich rule set to run. The parameters below the selector change to match, since each strategy is defined by different inputs.
BB PeriodHow many candles the Bollinger average and standard deviation are measured over. Longer is smoother and slower to react. 20 is live.
Std devHow far the bands sit from the average, in standard deviations. Wider bands mean rarer but more extreme entries. 3.0 is live, which is unusually wide and is what makes a band touch meaningful.
SL snap thresholdHow far price must travel toward the target before the stop jumps to the middle band and starts trailing. Lower values protect profit sooner but get stopped out by noise more often. 95% is live.
Cooldown candlesAfter a stop-loss, how many candles that direction waits before it may re-enter. 2 is live.
Evaluation modelSignal basis picks which candle's bands a wick is tested against. Last closed candle is what the bot does: bands come from candles that have already closed, so the level is known before the candle opens and can rest as a limit order. Same candle tests the wick against a band computed from that candle's own close, which is not knowable at the moment of the fill; it is kept only to reproduce previously published figures. Fill books the trade at the band, or at the candle close once the touch is confirmed. Stop-losses are unaffected, since a stop rests at a level fixed when the trade opened. Both default to the live bot. These change what the backtest measures, not the strategy.
Trend filter (EMA)When on, longs are only allowed above the EMA and shorts only below it, which stops the strategy buying every dip in a falling market. On, period 150, is live.
Fast / Slow periodFor the moving-average strategies: the two lookbacks being compared. The gap between them sets how often crossovers happen.
RSI period / thresholdsFor RSI Reversal: the lookback, and the oversold and overbought levels an exit from which triggers a trade. Defaults are 14, 30 and 70.
Risk & costs
SL %Stop distance from entry, before leverage. 1.0% is live, which at 10x is 10% of the money committed to the trade.
TP %Only used by strategies with a fixed target. BB Channel Rider ignores it, because its target is the opposite band and therefore moves with volatility.
LeverageMultiplies both the gain and the loss on every move, and the fees with them. 10x is live. It does not change the win rate, only the size of each outcome.
FeesWhich cost model to charge. None shows the gross edge, useful only for comparison. Maker assumes every order rests on the book; Taker assumes every order crosses it. Real trading falls between the two, and the difference is not small: on this strategy fees consume roughly three quarters of the gross edge.
Capital
Starting capitalThe balance the run begins with. Profits compound into later position sizes, so this affects the shape of the equity curve and not just its scale.
Per tradeHow much to commit per position, either a fixed dollar amount or a percentage of current capital. 25% of capital is live. A percentage compounds; a flat amount does not.
Changing any of these produces a valid backtest but no longer describes the deployed bot. Only the values marked live do that.
Indicator Backtest — Chart Controls
ZoomCtrl + scroll wheel to zoom in/out. Both price chart and sub-plot zoom in sync.
PanScroll wheel (no Ctrl) pans left/right. Click and drag also pans. Both charts move together.
Reset ZoomButton top-right of the price chart restores the full view.
B markersGreen circle = trade entry (resolved). Grey circle = open trade (no exit yet).
S markersRed circle = trade exit (TP or SL hit). Hover for tooltip with direction, outcome, and P&L.
Sub-plot syncRSI sub-plot x-axis is locked to the price chart. Zooming or panning one moves both. Vertical grid lines are mirrored exactly.
Indicator Backtest — Trade Table
Entry DateTimestamp of the signal candle — when the trade opens.
Entry / SL / TPPrices used. For BB Channel, TP shows "—" (band-based, not fixed).
Move %Raw price move before leverage. Positive = moved in trade direction.
P&LNet dollar profit or loss: the price move, multiplied by leverage, applied to the capital deployed on that trade, minus every cost. On the Live Bot tab that also includes funding, charged every 8 hours a position stays open. The Fees and Funding columns show those costs separately, so this column is what actually reached the balance, not a gross figure.
OutcomeTAKE PROFIT, STOP LOSS, or OPEN (still running at end of data).
Exit DateCandle where SL or TP was hit. Blank for open trades.