Skip to content
All strategies

Strategies

Freqtrade 'FSupertrendStrategy' by @juankysoriano (Juan Carlos Soriano), faithful port: triple-Supertrend long entry, Supertrend(18,3) exit, ROI ladder 10%/5%/2.5%, 26.5% trailing-from-high stop, LINKUSDT.BINANCE_SPOT 1h

Outcome: Abandoned

FSupertrendStrategyLinkSpot

Outcome Summary

FSupertrendStrategyLinkSpot was a line-for-line port of an open-source Freqtrade triple-Supertrend strategy, run long-only at leverage 1 on LINK spot 1h bars because the source never enables shorting. It went through 3 iterations and never got past code verification. Each time it failed the Layer 1.5 hypothesis/config consistency check, which flagged that the optimization_plan fixes leverage at 1.0, and it was then abandoned as a verification loop. No backtest, optimization or analyst review took place, so the strategy's edge was never measured.

Hypothesis

Faithful line-for-line translation of the open-source Freqtrade strategy FSupertrendStrategy (https://github.com/freqtrade/freqtrade-strategies/blob/f3340ce11f5bdf62f598522e64d1f5638eaa13f5/user_data/strategies/futures/FSupertrendStrategy.py, GPL-3.0). Credit goes to the author, @juankysoriano (Juan Carlos Soriano). Any performance the source claims is unverified; our fee-inclusive backtest decides. IMPORTANT FIDELITY NOTE (verified against the source at that commit): the class does NOT set `can_short = True`,……Show moreShow less

Faithful line-for-line translation of the open-source Freqtrade strategy FSupertrendStrategy (https://github.com/freqtrade/freqtrade-strategies/blob/f3340ce11f5bdf62f598522e64d1f5638eaa13f5/user_data/strategies/futures/FSupertrendStrategy.py, GPL-3.0). Credit goes to the author, @juankysoriano (Juan Carlos Soriano). Any performance the source claims is unverified; our fee-inclusive backtest decides. IMPORTANT FIDELITY NOTE (verified against the source at that commit): the class does NOT set `can_short = True`, and IStrategy defaults to `can_short = False`. Freqtrade's backtester zeroes the `enter_short`/`exit_short` columns when can_short is False, so the strategy as written trades LONG ONLY, at leverage 1 (there is no leverage() callback), even though it sits in the futures folder and computes short signals. A faithful port is therefore long-only and unlevered. Our routing rule puts long-only, no-leverage strategies on BINANCE_SPOT, so the port runs there. The source's short-entry rule is documented below for completeness but must NOT trade. Instrument choice: the source names no pair. Its hyperopt ran on 1h bars from 2021-01-01. BTC is over-concentrated in the corpus (and BtcAtrChannelSuperTrendRegimeFilteredLS is already in the pipeline), so this port runs on LINKUSDT.BINANCE_SPOT 1-HOUR. The catalog holds continuous LINK spot 1h bars from 2019-01-16 to 2026-10-01, about 7.7 years. BINANCE_SPOT has a 10.7% share against its ≥15% target. SUPERTREND INDICATOR (technical.indicators.supertrend, freqtrade/technical; port exactly; the developer must NOT substitute a Wilder/EMA ATR). Inputs are period p and multiplier m, over arrays high, low and close of length N. 1. tr = talib TRANGE(high, low, close): tr[0] = NaN; tr[i] = max(high[i]-low[i], |high[i]-close[i-1]|, |low[i]-close[i-1]|). 2. atr = SIMPLE rolling mean of tr over p bars (pandas rolling(p).mean()). It is NaN until index p, because index p-1 still includes tr[0] = NaN. 3. basic_ub = (high+low)/2 + m*atr; basic_lb = (high+low)/2 - m*atr. 4. final_ub and final_lb start as zeros. For i in range(p, N): final_ub[i] = basic_ub[i] if (basic_ub[i] < final_ub[i-1] or close[i-1] > final_ub[i-1]) else final_ub[i-1]. final_lb[i] = basic_lb[i] if (basic_lb[i] > final_lb[i-1] or close[i-1] < final_lb[i-1]) else final_lb[i-1]. 5. st starts as zeros. For i in range(p, N): if st[i-1] == final_ub[i-1], then st[i] = final_ub[i] if close[i] <= final_ub[i] else final_lb[i]. Elif st[i-1] == final_lb[i-1], then st[i] = final_lb[i] if close[i] >= final_lb[i] else final_ub[i]. Otherwise st[i] stays 0. Bootstrap: at i = p, st[p-1] = 0 == final_ub[p-1] = 0, so the first branch fires. 6. Direction stx[i] = 'down' if st[i] > 0 and close[i] < st[i]; 'up' if st[i] > 0 and close[i] >= st[i]; otherwise none (the strategy fills it with '' = neither up nor down). This is a recursive state machine. Implement it INCREMENTALLY: keep a deque of the last p TR values plus the previous final_ub, final_lb, st and close for each of the 6 distinct (p, m) instances, updated O(1) per bar. Do not recompute over history on every bar; the recent sandbox timeouts were caused by exactly that. Exact equality comparisons are safe because st is always assigned from final_ub or final_lb. ACTIVE PARAMETERS. The hyperopted buy_params and sell_params override the IntParameter defaults; these are the values the code trades. - Buy set: ST1 = (p=8, m=4), ST2 = (p=9, m=7), ST3 = (p=8, m=1). - Sell set: ST1 = (p=16, m=1), ST2 = (p=18, m=3), ST3 = (p=18, m=6). The IntParameter defaults (14/1, 10/3, 10/4) are NOT used. RISK, ROI AND EXIT SETTINGS AS WRITTEN: timeframe 1h; startup_candle_count 18; minimal_roi = {0: 0.10, 30: 0.75, 60: 0.05, 120: 0.025} (minutes since entry); stoploss -0.265; trailing_stop True; trailing_stop_positive 0.05; trailing_stop_positive_offset 0.10; trailing_only_offset_is_reached False; use_exit_signal True (default); exit_profit_only False (default). There is one position at a time.

The source is a tradeable strategy, so this is a faithful port. Venue and instrument: the code as written is long-only and unlevered (can_short is never set), so per the routing rule it belongs on BINANCE_SPOT (under target at 10.7%). LINK was chosen instead of BTC to avoid the over-concentrated BTC series and the BTC Supertrend variant already in the pipeline. The data span was verified in the catalog: LINKUSDT.BINANCE_SPOT-1-HOUR covers 2019-01-16 to 2026-10-01. The tunable set is empty because a faithful port must test the author's hyperopted values, and the corpus overfits whenever it re-optimizes. All six Supertrend states must be maintained incrementally (O(1) per bar) to avoid the Layer-3 sandbox timeouts seen recently.

verification_loop: Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]: - optimization_plan fixes leverage at 1.0

Implementation

Stratmill translation of Freqtrade FSupertrendStrategy (@juankysoriano, GPL-3.0) on LINKUSDT spot 1h: long when buy Supertrends (8,4),(9,7),(8,1) are all 'up' with volume>0; exit when sell Supertrend (18,3) is 'down', on the ROI ladder 10%/75%/5%/2.5% at 0/30/60/120 min, or on a -26.5% stop trailed from the high that tightens to 5% once high-water profit exceeds 10%. The six Supertrends are exact incremental ports of technical.indicators.supertrend (SMA of TRANGE), O(1) per bar.

Iteration 3 fix: the Layer-1 syntax error ('invalid decimal literal', line 1) came from iteration 2's code field holding the outbox placeholder text instead of Python. This submission carries the full source inline. The trading logic is the same as before, with one change: the ROI-ladder age now comes from calendar time (bar ts_init minus position ts_opened) instead of a held-bar counter, so it is restart-safe. Venue-managed bracket legs (STOP_MARKET stop, LIMIT ROI take-profit) are re-priced every bar to the trailing stop and the current ROI rung, which reproduces Freqtrade's intra-candle stop/ROI fills. Long-only and unlevered, as Freqtrade runs it (can_short is never set), so it trades on BINANCE_SPOT. The short signal is computed but never traded.

Verification Results

Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]: - optimization_plan fixes leverage at 1.0

Iteration History

sandbox_timeout: Verification failed (Layer 3 — sandbox backtest): smoke test exceeded the 300s wall-clock limit on a ~20000-bar window (833 days of LINKUSDT.BINANCE_SPOT-1-HOUR-LAST-EXTERNAL). This almost always means per-bar work that scales with history — e.g. rescanning the full funding/supplementary series, or rebuilding a list and calling min()/sorted() inside calculate_signal()/on_bar() on every bar. Precompute sorted timestamp arrays ONCE in __init__ and use bisect, or cache lookups keyed by timestamp, so per-bar cost is O(log n) not O(n).

Verification failed (Layer 1 — static analysis): - Syntax error: invalid decimal literal (<unknown>, line 1) (line 1)

Outcome Summary

For an unlevered spot port, make sure the optimization plan and the Layer 1.5 consistency check agree on how a fixed leverage of 1.0 is handled before coding, so a configuration mismatch does not end the run before any backtest.

It was abandoned in a verification loop after 3 iterations, failing Layer 1.5 (hypothesis/config consistency, class hypothesis_mismatch) because the optimization_plan fixes leverage at 1.0. Backtest review, optimization, analyst and risk review were never reached.

A faithful long-only, unlevered port of @juankysoriano's Freqtrade FSupertrendStrategy on LINKUSDT.BINANCE_SPOT 1h: enter long when three hyperopted Supertrends (8/4, 9/7, 8/1) all point up, exit when Supertrend(18,3) turns down, with a 10%/5%/2.5% ROI ladder and a 26.5% stop trailed from the high.

No performance data exists: the backtest report is empty and there is no optimization report, so there are no return, Sharpe or trade-count figures.

Analysis

FSupertrendStrategy

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