⚠ Structural diagnosis — three open bridges to profitability
GAP G1 · CRITICAL
TP trades are net-negative
Every "winning" exit is still a loss. TP avg = −$0.027, SL avg = −$0.184. This means the bot is entering after the move has already happened — entry timing is systematically late. Price reverses before TP fires a real profit.
Fix: entry filter — only enter on confirmed momentum, not on pattern detection alone
GAP G2 · CRITICAL
R:R ratio is inverted — 1:0.14
SL loses $0.184 on average. TP gains only $0.027. For a 0% win rate, no R:R saves you — but even at 50% WR this R:R bleeds you dry. The minimum viable ratio at 40% WR needs R:R ≥ 1.5. Current: 0.14.
Fix: widen TP to ≥7× the SL distance, or tighten SL to match TP distance
GAP G3 · STRUCTURAL
Equity slope = −$0.11/trade, R²=0.9994
The decay is perfectly linear — not random noise, not bad luck. This is a structural fee/spread problem. At 3.8 min avg between trades and $0.11 loss/trade, the system burns ~$1.73/hr. The bot is paying spread on every single trade with no edge to compensate.
Fix: reduce trade frequency 10×, add trend filter, require min spread clearance before entry
Fix 01 · Entry gate
Add a trend filter before every entry
The bot currently enters on both sides (LONG+SHORT) of every detected pattern regardless of prevailing trend. Add a 1-hour EMA check: only go LONG above EMA, only SHORT below. This alone kills ~50% of counter-trend losses.
entry_ok = (phase=='LONG' and price > ema1h) or (phase=='SHORT' and price < ema1h)
High impact · 2h to implement
Fix 02 · R:R rebalance
Widen TP to at least 3× the SL distance
Current TP = ~0.027 avg, SL = ~0.184. Even at a 35% win rate, a 1:3 R:R breaks even. At 40% WR it turns profitable. The bot clearly has some directional ability (147 TPs fired) — the edge is real but is being suffocated by the TP being too close.
tp_distance = sl_distance * 3.0 # minimum viable
High impact · 30 min to implement
Fix 03 · Frequency cap
Limit to 5–10 trades per hour maximum
Current: ~16 trades/hr on average, 21 in the worst hours. Each entry pays spread. At this frequency, spread alone accounts for the majority of losses. Add a cooldown: after any trade, lock the pair for 15 minutes. Target: <8 trades/hr total.
cooldown[pair] = now + timedelta(minutes=15)
Medium impact · eliminates ~60% of spread drag
Fix 04 · Volatility gate
Only trade when ATR clears the spread
The bot trades micro-cap pairs (DEGEN, HOME, NOM) where bid-ask spread is a large fraction of move size. Compute 14-period ATR on the entry timeframe. If ATR < 3× estimated spread, skip. This filters entries where there is no room to profit.
if atr14 < spread * 3: skip_trade()
High impact · stops trading in dead markets
Fix 05 · Pair culling
Drop AERGO, ALLO, DEXT — keep NOM, WLD
NOM-USD (avg −$0.091) and WLD-USD (avg −$0.086) are the least-bad pairs, suggesting marginally better liquidity. AERGO (−$0.133) and ALLO (−$0.148) bleed fastest. Drop them immediately. Focus volume on STG and HOME where trade count is high enough to improve with fixes 01–03.
PAIRS = ['STG-USD','HOME-USD','NOM-USD','WLD-USD']
Quick win · no logic change needed
Fix 06 · Confirmation candle
Wait for one closed candle before entry
The ping-pong pattern in the data (LONG → SHORT on same pair within 2 min) shows the bot is chasing sub-candle noise. Enforce that the signal candle must fully close before entering. This eliminates the LONG+SHORT whipsaw pattern that generated 147 back-to-back SL/TP pairs.
wait_for_close(candle) before signal_entry()
Medium impact · prevents whipsaw entries
Breakeven simulator — adjust parameters to find the threshold
Expected value per trade:
…
R:R ratio:
…
Verdict:
…