Skip to content
All strategies

Strategies

ianzeng123 FMZ Gold Multi-Confluence System on BTC USD-M

Outcome: Abandoned

Ianzeng123GoldMultiConfluenceBtc

Outcome Summary

This hourly BTCUSDT futures strategy combined technical signals to choose long and short trades. After two iterations, its backtest recorded 3,926 closed trades, a -100% return, and liquidation. Backtest review abandoned it for negative expectancy and no edge before commissions; the optimization plan had no tunable parameters.

Hypothesis

Faithful hypothesis for ianzeng123's Gold Multi-Confluence Trading System. Despite its title, the source backtest specifies BTC_USDT Binance futures on 1-hour bars. Evaluate the supplied Pine rules on BTCUSDT.BINANCE with one long or short position at a time. The source's performance claims are unverified. Preserve its actual code behavior: volume and session each contribute one score point rather than acting as mandatory filters; the declared spread filter is never applied; and the Bollinger squeeze condition is always false because it compares the current width with a minimum that includes the current width.

The user requested the source strategy faithfully, and its own test header selects Binance BTC futures at 1 hour. This heavily researched venue and instrument warrant low priority. Changing the instrument, filters or parameters would test a different strategy.

negative_expectancy / no_edge: the strategy loses before commissions across a substantial sample. Gross price profit factor is 0.897, and the account liquidated. Optimization offers no parameter changes to test.

Implementation

Faithful port of ianzeng123's Gold Multi-Confluence (UHWR-Gold v2) Pine strategy on BTCUSDT.BINANCE 1h. It scores 10 long and 10 short factors: EMA 8/21/50 alignment, the EMA200 filter, smoothed RSI, MACD histogram momentum, position against the BB basis (with the squeeze that is never true), volume above 1.5x its SMA20, pivot-based market structure, candle direction, a break of the prior high/low, and the London/NY/Tokyo session. It enters at a score of 7 or more and risks 1% of equity per trade on a stop 1.5x smoothed ATR away, with a 3R target. A trailing stop activates at 1.5R with a 0.5 ATR offset, and a structure break triggers an early exit.

Iteration 2 fixes the QA defects. (1) Stop-loss and take-profit are now resting venue orders, placed as a market entry plus a linked STOP_MARKET/LIMIT bracket (one-updates-other) at close -/+ 1.5*ATR_smooth and close +/- 4.5*ATR_smooth. They now fill intrabar at their levels, as Pine strategy.exit does, instead of at the bar close. The trailing stop moves on the bar close, and modify_order shifts the resting stop leg, matching Pine's per-bar strategy.exit(stop=trail_stop) update. should_exit now handles only the……Show moreShow less

Iteration 2 fixes the QA defects. (1) Stop-loss and take-profit are now resting venue orders, placed as a market entry plus a linked STOP_MARKET/LIMIT bracket (one-updates-other) at close -/+ 1.5*ATR_smooth and close +/- 4.5*ATR_smooth. They now fill intrabar at their levels, as Pine strategy.exit does, instead of at the bar close. The trailing stop moves on the bar close, and modify_order shifts the resting stop leg, matching Pine's per-bar strategy.exit(stop=trail_stop) update. should_exit now handles only the structure-break strategy.close. (2) Sizing keeps the source's risk_qty = 1% equity / stop_distance but adds a notional cap that does not depend on ATR: min(max_notional_mult=2.5, leverage) * equity / price. Config leverage drops from 20 to 3. The source sizes without a cap, so this cap is a platform risk adaptation; it changes no fixed plan parameter. (3) min_bars_required rises to 2*ema_filter (400), so EMA200 and the other EMAs are primed from 400 buffered bars before trading. Smoothed RSI is now seeded with the first valid RSI, as Pine's custom ema() does. Pine's custom ema() also seeds with the first source value, so the close-seeded EMAs already match it. (4) A session_tz_offset_hours parameter (default 0 = UTC, Binance's exchange timezone) is exposed for the session windows. As in the source, the spread filter is still never applied and the BB squeeze is still always false. Caveat: the earlier sandbox's profit factor of 0.86 suggests the 7-of-10 confluence may have no edge on BTC 1h even with correct exits.

Verification Results

Acceptable as written. Alternatively, set use_bracket_orders and pass per-trade percentages through a supported hook, if the template adds one.

_submit_entry is overridden to route every entry through _submit_entry_bracket with stop and target percentages derived from ATR. This works because the base _process_primary calls _submit_entry when use_bracket_orders is unset. However, it also shadows the base safety path (static warning base_shadow). Any future template change that adds checks only to the base _submit_entry would be bypassed here.

Persist the per-trade fields through persistable_state(), or rebuild them from the open position and its resting stop order on start.

Trailing-stop state (entry_price, entry_stop_distance, trail_stop, trailing_activated) and the incremental EMA/RSI/ATR state are not persisted. On a live or paper restart with an open position, entry_stop_distance can refer to a different trade, or the indicators re-prime from the 500-bar buffer. The resting bracket stop still protects the position.

No change required. Consider a lower max_notional_mult if the analyst finds that commission drag dominates.

Notional is capped at min(max_notional_mult=2.5, leverage=3) x equity, so worst-case gross is 2.5x equity on a single instrument. That is within the 3x config leverage and the 20x venue cap. Per-trade risk is bounded at 1% of equity by the stop, and the 1/stop_distance divergence (lesson L156) is clamped by the notional cap. The sandbox's avg_position_pct of 565% is an artefact of the metric's denominator (equity before entry, rebuilt from realized PnL) as equity collapsed toward zero. It does not exceed the cap, and largest_loss is $1.58k, about 1.5% of starting equity.

The sandbox lost 100% (equity fell to zero on 2026-04-25) over 1441 trades in 717 days. avg_trade_return_pct was -0.138%, PF 0.847, and the win rate was 34.5% on both the long and short sides. The realized payoff was 1.6, against a nominal 3R target, so the structure-break and trailing exits are cutting most winners early. Commission was $109.6k plus $39.6k of impact on $100k equity, from turnover of 1150x. Sizing risks 1% of equity on a 1.5x ATR stop, which on BTC 1h means about 130-250% notional per trade. Each round trip therefore costs about 0.15-0.3% of equity before any gross edge. PF 0.85 is above the 0.70 polarity-suspicion line and long and short are symmetric, so this reads as no edge rather than a sign bug. Check first: gross PF before costs, and the exit-reason breakdown (structure break vs trailing stop vs SL vs TP). If gross is near 1.0, this is no_edge on the full history and not worth optimizing, especially because the plan has no tunable parameters.

Backtest Review

Sharpe
0.23
Total return
-100.00%
Max drawdown
100.00%
Trades
3926
Win rate
34.3%
Profit factor
0.89

The 3,926 closed trades provide a substantial sample.

Average return is −0.145% of notional per trade, below the 0.15% Binance futures floor.

Price P&L totals −$180,745 before the separately reported $205,321 in commissions. QA’s no-edge concern is borne out.

The account liquidated, and the optimization plan has no tunable parameters.

Iteration History

Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] Even with stops fixed, the sandbox showed PF 0.86 over 1255 trades. The average win was only 1.54x the average loss, although the design targets 3R. Commissions were about 17% of gross. At an average of about 4x notional, the 0.10% round trip costs about 0.4% of equity per trade, against a 1% risk budget. After the stop fix, check whether the payoff ratio moves toward the 2-3R the design implies. If it does not, the 7-of-10 confluence……Show moreShow less

Verification failed (Layer 4 — QA review) [class=code_defect]: - [edge_concern] Even with stops fixed, the sandbox showed PF 0.86 over 1255 trades. The average win was only 1.54x the average loss, although the design targets 3R. Commissions were about 17% of gross. At an average of about 4x notional, the 0.10% round trip costs about 0.4% of equity per trade, against a 1% risk budget. After the stop fix, check whether the payoff ratio moves toward the 2-3R the design implies. If it does not, the 7-of-10 confluence has no edge on BTC 1h. - [critical] Stops, take-profits and trailing stops are detected from the bar's high/low but exited with a market order at the bar CLOSE (should_exit -> _submit_exit). In the Pine source, strategy.exit stop/limit orders fill intrabar at their price (process_orders_on_close only affects market orders). Two consequences follow. (a) A take-profit touched intrabar is exited at the close, which can be far below the target or even a loss, so the 3R winners the strategy depends on are cut short. The sandbox's average win/average loss ratio is 1.54, not about 3. (b) A stop that is crossed is exited at the close, which can be several stop distances beyond the stop. The hypothesis asks to preserve the source's code behaviour; this changes the exit mechanics that set both the payoff and the risk per trade. (line 236) — fix: When the entry fills (on_order_filled / on_position_opened), submit resting reduce-only orders at the computed levels: a stop_market at stop_loss and a limit at take_profit, OCO or cancelled on the other's fill. Replace the stop order when the trailing stop ratchets. Keep the bearish/bullish structure-break exit as a signal exit in should_exit(). - [critical] Sizing is risk_quantity = equity*1%/(1.5*ATR_smoothed), capped only by equity*leverage/price with leverage 20. The ATR denominator is inverse-volatility and shrinks in calm hours (L156). With 1h BTC ATR around 0.1-0.3%, the stop is about 0.15-0.45% and notional runs to 2-7x equity, up to the 20x clamp. The sandbox's average position was 395% of equity. The 1%-of-equity risk only holds if the stop fills at its price. Because exits fill at the close (issue above), one adverse hourly bar of about 3% on 6x notional loses about 18% of equity. Realised loss is therefore unbounded relative to the stated risk_per_trade. The sandbox was liquidated (-100%, liquidation 2026-07-08, max DD 100%), against the plan's own max_drawdown_pct constraint of 20%. This is a sizing/risk defect (L148/L156), not an edge outcome. (line 260) — fix: Enforce the stop with a resting stop order so that size*stop_distance is about 1% of equity. In addition, put an explicit notional cap independent of ATR, e.g. min(risk_quantity, max_notional_mult*equity/price) with max_notional_mult around 3. Lower config.leverage to match that cap rather than 20. - [warning] EMAs (including EMA200), the MACD EMAs and the signal line are seeded from the first close in the buffer, and min_bars_required is only 35. EMA200 and ema_trend are therefore unconverged for the first ~200-600 bars, and those early scores differ from Pine, which seeds ta.ema with an SMA. This only matters early in the window and after resets: the optimization plan uses warmup_bars 500, which mostly covers it. (line 66) — fix: Return max(..., ema_filter) or a larger value such as 3*ema_filter from min_bars_required, or seed each EMA with the SMA of its first N closes. - [warning] Session windows are evaluated in UTC. The FMZ Pine runtime may evaluate time(session) in the platform's exchange/chart timezone, which may not be UTC (FMZ commonly uses UTC+8). If so, each session window is shifted 8 hours. Session is one score point, so the effect is limited. (line 133) — fix: Confirm the source timezone and add a session_tz_offset_hours parameter if it is not UTC. - [warning] should_enter mutates entry_price, stop_loss, take_profit and trailing state before position_size runs. If the order is dropped for minimum notional or zero size, the state is stale. This is harmless today, because should_exit only runs with an open position and the next should_enter overwrites the state. It becomes a bug if fills differ from close (stops are anchored to the signal close, not to the fill price). (line 205) — fix: Recompute the stop/TP from the actual avg_px_open in on_position_opened.

Outcome Summary

The entry signals need a positive gross trading edge before further optimization is useful.

Backtest review abandoned it because it lost before commissions, fell below the 0.15% per-trade return floor, and liquidated. Optimization and later reviews were not reached.

The strategy scored technical signals for long and short trades on hourly BTCUSDT Binance futures bars.

Across 3,926 closed trades, the backtest returned -100%, with a 0.229 Sharpe ratio and an average return of -0.145% of notional per trade. The account liquidated.

Analysis

黄金多重确认交易系统|Gold Multi-Confluence Trading System

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