Skip to content
All strategies

Strategies

SOL Spot Vol-Scaled Step-Ladder Trend Exposure: Add One 25% Equity Slice per +1-Sigma Move from the Last Rebalance Price, Remove One Slice per -1-Sigma Move, Flat at Zero Slices, Long-Only, No Leverage (SOLUSDT.BINANCE_SPOT 4H, pure OHLCV)

Outcome: Abandoned

SolSpotVolScaledStepLadder

Outcome Summary

SolSpotVolScaledStepLadder restated an FMZ price-step ladder as a vol-scaled, 25%-slice, long-only SOL spot trend follower on 4H bars. Its base backtest over about 5.7 years showed a large +2581% return, but with Sharpe 0.33, a 78.7% max drawdown, beta 0.63 and an information ratio of -0.54, meaning it underperformed simply holding SOL. After 2 iterations the analyst abandoned it at backtest review as beta without a trend edge, so optimization, analysis and risk review were never reached. The analyst also flagged a -7.43% avg_trade_return_pct that disagrees in sign with the positive PF and USD PnL, and asked for a harness check.

Hypothesis

Adapted from the FMZ digest article 'Python版追涨杀跌策略' by 发明者量化-小小梦 (https://www.fmz.com/digest-topic/4908, sections '策略代码' and '策略简单分析', 2020-01-11). This is a restatement from first principles, not a faithful port (L167). The source is a price-step ladder with no indicators. It keeps an anchor price. When price rises more than 5% above the anchor it buys a slice; when price falls more than 5% below the anchor it sells a slice. After either trade the anchor moves to the current price. We keep that ladder and change……Show moreShow less

Adapted from the FMZ digest article 'Python版追涨杀跌策略' by 发明者量化-小小梦 (https://www.fmz.com/digest-topic/4908, sections '策略代码' and '策略简单分析', 2020-01-11). This is a restatement from first principles, not a faithful port (L167). The source is a price-step ladder with no indicators. It keeps an anchor price. When price rises more than 5% above the anchor it buys a slice; when price falls more than 5% below the anchor it sells a slice. After either trade the anchor moves to the current price. We keep that ladder and change three things. (1) Signals are checked on the 4H bar close instead of a 500 ms ticker loop. (2) Each slice is a fixed 25% of equity, with at most 4 slices. The source sizes each order as a share of the remaining balance, so it never reaches flat; here, zero slices is a true flat state. (3) The step is scaled to volatility instead of a fixed 5%: s = 1.0 x the trailing 30-day stdev of daily returns, clamped to [3%, 12%]. Economically this is a discrete trend follower. On a random walk it expects zero before fees, so it only makes money if SOL spot returns keep going in the same direction over days to weeks at about the 1-sigma scale (the crypto time-series momentum horizon). It trades SOL spot because the source is long-only on a cash account, spot is under its quota (10.6% vs >=15%), and SOL is not one of the over-concentrated BTC/ETH series. The catalog holds SOL spot 4H history from 2020-08-11. There is no regime gate and no supplementary feed.

Iteration 2 fixes only the critical sizing defect QA found. On the CASH account, get_account_equity() returns the USDT balance, which already excludes the SOL held. The old _slice_qty subtracted held*price from that balance a second time, which capped exposure near 56%. Now mtm = usdt + held*close and each slice is min(0.25*mtm, usdt*0.99). A guard requires held_value + notional <= mtm, so the CASH account is never over-asked. Four slices now reach about 100% of equity, as the hypothesis specifies. Signal, ladder and anchor logic are unchanged. On QA's ledger warning: adds and trims net into one position, so avg_trade_return_pct measures a whole multi-slice episode, not one slice. Judge the result on the equity curve and on fills-level fees instead. QA's edge concern still stands: a ladder has zero expectancy on a random walk. Any result depends on SOL trends persisting and may come mostly from the 2021 and 2023-24 bull runs.

premise_falsified: on an adequate sample (109 ladder episodes over 5.7 years), the vol-scaled step ladder on SOL spot shows no trend edge beyond scaled-down beta. Beta is 0.63, correlation 0.85, exposure 85%, average position 95% of equity, and the information ratio is -0.54, so it underperforms buy-and-hold SOL. Max drawdown is 78.7% over 773 days, about 0.8x SOL's own ~95% cycle drawdown (lesson 170 beta screen), against a 15% spot default. Sharpe is 0.33 with a 95% CI of -0.40 to 1.11 (PSR 0.77), and PF is……Show moreShow less

premise_falsified: on an adequate sample (109 ladder episodes over 5.7 years), the vol-scaled step ladder on SOL spot shows no trend edge beyond scaled-down beta. Beta is 0.63, correlation 0.85, exposure 85%, average position 95% of equity, and the information ratio is -0.54, so it underperforms buy-and-hold SOL. Max drawdown is 78.7% over 773 days, about 0.8x SOL's own ~95% cycle drawdown (lesson 170 beta screen), against a 15% spot default. Sharpe is 0.33 with a 95% CI of -0.40 to 1.11 (PSR 0.77), and PF is 1.36 on a 13.8% win rate with up to 25 losses in a row. Profit comes almost entirely from the 2021 and 2023 SOL bull runs, and every crisis stress window except April 2025 loses money. The base run is far below the optimize bar, and optimization can only lower it. QA's concern is borne out. Separately flagged: avg_trade_return_pct (-7.43%) disagrees in sign with PF 1.36 and a positive avg USD PnL. This is likely a per-position notional denominator problem when slices are scaled in; the cause is not verified, so please send it for a harness check. First-report failure code: no_edge (beta, not a fee problem).

Implementation

Long-only SOL spot 4H step ladder. It keeps an anchor price. Each +1 volatility step above the anchor adds a slice worth 25% of mark-to-market equity, up to 4 slices. The step is 1x the 30-day stdev of daily returns, clamped to 3-12%. Each -1 step below the anchor removes one slice, and zero slices means flat. The anchor resets to the close after every step.

Verification Results

Either return a small min_bars_required (e.g. 2) and gate trading on len(self._closes) == maxlen inside calculate_signal (return 0.0 until full), or compute the daily returns from the base template's self._bars buffer, which is already filled during warmup.

The vol buffer warms up twice. min_bars_required() returns 182, and the base template does NOT call calculate_signal() while len(self._bars) < min_bars (_maybe_process_primary returns early). So self._closes only starts filling on bar 183. For the next ~2 days, _daily_stdev() returns 0 and the step is clamped to step_min=3%. For about 30 more days after that, the step comes from fewer than 30 daily returns, not the 30-day window the hypothesis states. Ladder decisions in that stretch use a noisy or floored step. This happens once per backtest, and again after every paper-node restart, because the deque is not persisted.

Derive the slice count from the filled position (e.g. round(held*price / slice notional at add time)), or increment _slices in on_order_filled instead of at submit time.

Slice bookkeeping is optimistic in live trading. In should_exit the add path runs self._slices += 1 right after _submit_entry_instrument(), but that helper can silently drop the order (in-flight guard, market not ready, warmup). should_enter likewise sets _slices=1 and moves the anchor before the base template checks size and min notional. In the backtest, market orders fill in-event, so this does not change these results. Live, a dropped add leaves _slices ahead of what is actually held, and later trims then sell held/_slices, which is too small.

Analyst: judge on the equity curve and fills-level costs, not avg_trade_return_pct. Do not compare that field to the fee floor for this design.

The ledger shows a sign disagreement: avg_trade_return_pct is -7.43% while total_return is +2581% and PF is 1.36 (L116). I checked the dollar ledger and it reconciles exactly: 15 wins x $645.6k = $9.68M, 94 losses x $75.6k = $7.10M, net = $2.58M = 2581% of $100k, and PF 9.68/7.10 = 1.36. So this is not an accounting defect in the strategy. The negative pct mean comes from compounding (winners occur at much larger equity) and from multi-slice netting: one ledger 'trade' is a whole add/trim episode, with trades_count 938 fills vs 109 positions. avg_holding_bars=0.0 against a 15.8-day holding period is a harness metric artifact.

None required beyond the warm-up fix.

Static analysis flags min_bars_required as shadowing the base method. The override is deliberate and allowed by the base contract ('Override as needed'), but see the warm-up interaction above.

The sandbox numbers look more like leveraged-down SOL beta than a trend edge. Beta is 0.63 with correlation 0.85 to buy-and-hold, and the information ratio is -0.54, so the strategy underperforms simply holding SOL. Max drawdown is 78.7% (CI 72-99.8%), far above any spot drawdown floor, and it lasted 773 days. Every crisis stress window is negative: china_ban -48%, rate_shock -55%, FTX -44%. The results rest on 15 winning episodes out of 109, with up to 25 losses in a row, and a single winner of +$2.43M. Per-trade dollar PnL depends on compounding: the winners came when equity was large. For the analyst: (1) compare against a 95%-exposure buy-and-hold on the same span; (2) check per-year concentration in 2021 and 2023-24; (3) the drawdown floor is the likely binding gate, not fees. The steps are 3-12% against a ~0.2% spot round trip, so fee viability is not the issue.

Backtest Review

Sharpe
0.33
Total return
2581.22%
Max drawdown
78.68%
Trades
109
Win rate
13.8%
Profit factor
1.36

The mechanism is implemented as the hypothesis describes: long-only, a 25% slice ladder, vol-scaled steps, and a true flat state. entry_diag shows 109 entries, none dropped.

Fees are not the issue. Commission is 5.2% of gross and impact 12.1%, and 3-12% steps sit well above the ~0.2% spot round trip.

The trade sample is adequate: 109 episodes (938 fills) over 2,069 days.

The return looks like leveraged-down SOL beta, not a trend edge. Beta is 0.63, correlation to buy-and-hold 0.85, exposure 85%, average position 95% of equity, and the information ratio is -0.54, so it underperforms simply holding SOL. QA's concern is borne out.

Max drawdown is 78.7% (CI 72-99.8%) and lasted 773 days. Against SOL buy-and-hold's ~-95% 2021-22 drawdown that is about 0.8x, which triggers the beta screen (lesson 170). It is also far above the 15% spot default.

The Sharpe is not significant: 0.33, 95% CI -0.40 to 1.11, PSR 0.77. That is far below the base bar for optimizing (Sharpe >= 1.0 and PF >= 1.5; PF here is 1.36).

Profit is concentrated in a few years: +1834% in 2021 and +940% in 2023. 2020, 2022, 2025 and 2026 are all negative. Every crisis stress window is negative except the 2025 tariff window.

The payoff depends on rare wins: 13.8% win rate, up to 25 losses in a row, and 15 winning episodes carry the book, with the largest win alone at $2.43M.

The ledger does not agree with itself: avg_trade_return_pct is -7.43% while PF is 1.36 and avg_trade_pnl_usd is +$23.7k. This is probably a per-position denominator problem when slices are scaled in; the mechanism is not verified. Either way, the pct number fails the viability floor.

Iteration History

Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] A discrete ladder trend follower has zero expectancy on a random walk. In the sandbox, the stressed-vol tercile carries the result (+422% of +772%), the 2022 stress windows are all negative, and there is a 770-day drawdown duration, so a few SOL bull legs may dominate. After the sizing fix, check the per-year concentration and whether the result survives without 2021 and 2023-24. - [critical] Slice sizing subtracts the held position……Show moreShow less

Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] A discrete ladder trend follower has zero expectancy on a random walk. In the sandbox, the stressed-vol tercile carries the result (+422% of +772%), the 2022 stress windows are all negative, and there is a 770-day drawdown duration, so a few SOL bull legs may dominate. After the sizing fix, check the per-year concentration and whether the result survives without 2021 and 2023-24. - [critical] Slice sizing subtracts the held position from cash twice, so the hypothesis's change #2 (a fixed 25%-of-equity slice, up to 4 slices) is not implemented. On a BINANCE_SPOT CASH account, get_account_equity() goes through resolve_account_equity and returns only the USDT balance. SOL already bought has left that balance. _slice_qty then computes free_cash = equity - held_qty*price, subtracting the held SOL a second time, and slice = min(USDT*0.25, free_cash*0.99). Worked through from equity E: slice 1 = 0.25E; slice 2 = 0.1875E (25% of the remaining USDT, which is the source's 'share of remaining balance' sizing the hypothesis explicitly replaced); slice 3 is about 0.12E (free cash is binding); slice 4 has free_cash <= 0, so it is never placed. Maximum exposure is therefore about 56% of equity, not 100%, and it falls further when price rises between adds, because held*price grows. The sandbox's avg_position_pct of 54.7% matches this ceiling. Trims then sell 1/slices of a position built from unequal slices. The tested strategy's exposure ladder is not the one the hypothesis describes. (line 105) — fix: Compute mark-to-market equity as mtm = usdt_balance + held_qty*close. Size each slice as notional = slice_frac * mtm (or slice_frac * the equity at the first entry, if slices should be fixed-dollar), capped by the free cash actually available: notional = min(slice_frac*mtm, usdt_balance*cash_buffer). Do not subtract held*price from the USDT balance again. Assert (held_qty*close + notional) <= mtm before submitting, so the CASH account is never over-asked. - [warning] The trade ledger does not reconcile (L116/L140). avg_trade_return_pct is -5.93% on 137 'trades' while total_return is +772% and PF is 1.51, avg_holding_bars is 0.0, and trades_count (878 fills) is different from total_trades (137). Adds and trims go into one NETTING position, so each 'trade' is a whole multi-slice episode, and the per-trade denominator is not the notional deployed. Per-trade economics cannot be compared to the ~0.20% spot round trip until the ledger books each slice against its own notional. (line 137) — fix: No strategy change is strictly needed. The analyst should evaluate the result on the equity curve and on fills-level fees (commission_pct_of_gross 4.7%, impact 5.3%), not on avg_trade_return_pct. - [warning] min_bars_required overrides the base method (static-analysis base_shadow). Here it only sets a warmup of 30*6+2 bars, which is reasonable. The _closes deque is bounded (maxlen), so the unbounded-growth warning is a false positive. The vol computation is O(30) per bar with no per-bar history rescan. (line 60) — fix: Keep the override if the base contract allows it.

Outcome Summary

A long-only spot trend ladder that sits about 85% invested mostly carries the underlying's beta and drawdown, so check the information ratio against buy-and-hold before trusting headline returns. The avg_trade_return_pct sign mismatch on scaled-in positions should also go to a harness check.

At backtest review the analyst chose to abandon before optimization (premise_falsified / no_edge): the returns looked like scaled-down SOL beta rather than a trend edge, and the strategy missed every optimize-bar criterion (Sharpe, PF, Sharpe CI, drawdown vs the 15% spot default, information ratio, avg trade return). Profit came mostly from the 2021 and 2023 bull runs, and every crisis stress window except April 2025 lost money.

A long-only, unleveraged SOL spot 4H step ladder adapted from an FMZ chase-up/kill-down strategy: add one 25%-of-equity slice (max 4) for each +1-sigma move from the last rebalance price and remove one for each -1-sigma move, with the step set to the trailing 30-day daily-return stdev clamped to 3-12%, betting on multi-day SOL trend persistence.

Over 2,069 days (Aug 2020-Apr 2026) the base backtest ran 109 ladder episodes (938 fills) for a +2581% total return, but Sharpe was only 0.33 (95% CI -0.40 to 1.11), PF was 1.36, the win rate was 13.8% and max drawdown was 78.7% over 773 days. Beta was 0.63, correlation to buy-and-hold was 0.85, the information ratio was -0.54, and the reported avg_trade_return_pct was -7.43%.

Backtest and paper results are hypothetical. Trading involves risk of loss.