Strategy Lab/W15 DI Cross

Strategy Lab — W15 DI Cross System

Wave 1515m Chart · FCPO

Systematic refinement of the 15-minute DI Cross entry system for FCPO (Bursa Malaysia CPO Futures). Testing filter combinations to isolate quality DI cross signals and improve profit factor above 1.5+. 23 variants tested · current best: W15-S (PF 1.562, WR 45.61%)

23
Variants Tested
20
Profitable
3
Failed (PF < 1)
20
SUBPAR
1.562
Best PF
45.61%
Best WR
Current BestW15-SADX>18 + H1 DI + H4 DI + D1 EMA200
ADX > 18, H1 DI alignment, H4 DI alignment, D1 EMA200 (3-TF stack)
+12,055
Net PnL
57
Trades
45.61%
Win Rate
1.562
Profit Factor
MYR —/day
Daily Avg
Key Finding
Best trading system. H4 DI is the missing structural layer — 3-TF stack (15m + H1 + H4). Removes 2 net-losing trades vs W15-L, adds +1,595 MYR, tightens drawdown to 1.11%.
W15-S — Pine Script v6 (copy → TradingView Pine Editor → Add to chart)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W15-S — M15 DI Cross (ADX>18, H1+H4 DI, D1 EMA200)", shorttitle="W15-S",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

[plusDI, minusDI, adx] = ta.dmi(14, 14)

[h1Plus, h1Minus, _h1adx] = request.security(syminfo.tickerid, "60",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h4Plus, h4Minus, _h4adx] = request.security(syminfo.tickerid, "240", ta.dmi(14,14), gaps=barmerge.gaps_off)
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

longSig  = ta.crossover(plusDI,  minusDI) and adx > 18
         and h1Plus > h1Minus and h4Plus > h4Minus
         and close > ema200d and strategy.position_size == 0

shortSig = ta.crossover(minusDI, plusDI) and adx > 18
         and h1Minus > h1Plus and h4Minus > h4Plus
         and close < ema200d and strategy.position_size == 0

if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
System Definition
W15 DI Cross — 15m FCPO · 2022–2026
Entry Signal
Chart TF
15-minute (W15 = Wave 15 on 15m chart)
Signal
+DI crosses above −DI (long) · −DI crosses above +DI (short)
ADX threshold
ADX(14) > 18 at signal bar
Trend Filters
H1 DI filter
H1 +DI > −DI for longs · H1 −DI > +DI for shorts
H4 DI filter
H4 +DI > −DI for longs · H4 −DI > +DI for shorts (3-TF stack, added W15-S)
D1 EMA gate
Price above D1 EMA(200) for longs · below for shorts (mandatory)
Session
10:30–12:30 MYT — AM only, after open warm-up
Risk & Sizing
Stop Loss
ATR × 1.5 (×2.0 tested in W15-N — subpar, ×1.5 confirmed optimal)
Position size
1 contract (25MT CPO)
Commission
MYR 30/contract (MYR 60 round-trip)
Slippage
1 tick
Backtest Setup
Initial capital
MYR 500,000 (TradingView backtest standard)
Backtest period
2022–2026 · FCPO continuous contract, Bursa Malaysia
Platform
TradingView Strategy Tester via TradingView MCP CLI
W15 Variant Results
23 variants — sorted by Daily Avg MYR
VariantFiltersTradesWR%PFPF BarDaily AvgNet MYRStatus
W15-L
ADX>18 + H1 DI (No EMA21)
ADX > 18, H1 DI alignment only (EMA21 removed)5944.07%1.454
+45.4% above baseline
+13.90+10,460SUBPAR
W15-M
Session 10:30–13:00 (wider window)
ADX > 18, H1 DI, D1 EMA200, session extended to 13:00 MYT5944.07%1.454
+45.4% above baseline
+13.90+10,460SUBPAR
W15-H
ADX>18 + EMA21
ADX > 18, price above/below EMA(21)12336.59%1.164
+16.4% above baseline
+11.97+8,770SUBPAR
W15-K
ADX>18 + EMA21 + H1 DI
ADX > 18, EMA(21), H1 DI alignment (plus-DI > minus-DI on 1H)5242.31%1.380
+38.0% above baseline
+10.72+7,855SUBPAR
W15-F
ADX>18 + Midpoint
ADX > 18, entry at midpoint of DI cross candle14436.11%1.122
+12.2% above baseline
+10.52+7,710SUBPAR
W15-D
ADX>20 + EMA21 + D1
ADX > 20, EMA(21), D1 EMA(200) alignment7735.06%1.148
+14.8% above baseline
+9.02+6,600SUBPAR
W15-B
ADX>20 + EMA21
ADX > 20, price above EMA(21)9835.71%1.107
+10.7% above baseline
+8.81+6,450SUBPAR
W15-C
ADX>20 + D1 EMA200
ADX > 20, D1 EMA(200) trend alignment9134.07%1.101
+10.1% above baseline
+7.09+5,190SUBPAR
W15-A
ADX>20 Baseline
ADX > 20 only (no additional filters)11633.62%1.068
+6.8% above baseline
+6.47+4,740SUBPAR
W15-E
ADX>18 Only
ADX > 18 (lower threshold, no additional filters)17733.90%1.054
+5.4% above baseline
+5.91+4,330SUBPAR
W15-G
ADX Rising Filter
ADX > 18, ADX must be rising at signal bar221.165
+16.5% above baseline
+1,455SUBPAR
W15-J
No D1 Filter
ADX > 18, EMA21, D1 EMA(200) removed1.081
+8.1% above baseline
SUBPAR
W15-N
ATR SL ×2.0 (wider stop)
ADX > 18, H1 DI, D1 EMA200, ATR stop loss ×2.05843.00%1.170
+17.0% above baseline
+4,520SUBPAR
W15-O
RR 2.0 (tighter target)
ADX > 18, H1 DI, D1 EMA200, RR 2.0 target601.120
+12.0% above baseline
+3,850SUBPAR
W15-R
Volume Spike ×1.2
ADX > 18, H1 DI, D1 EMA200, volume spike ×1.2 vs average41+7,215SUBPAR
W15-SBest
ADX>18 + H1 DI + H4 DI + D1 EMA200
ADX > 18, H1 DI alignment, H4 DI alignment, D1 EMA200 (3-TF stack)5745.61%1.562
+56.2% above baseline
+12,055SUBPAR
W15-T
W15-S + Prev-day Midpoint Bias
ADX > 18, H1 DI, H4 DI, D1 EMA200, prev-day midpoint bias filter5145.10%1.478
+47.8% above baseline
+9,315SUBPAR
W15-U
W15-S + Partial Exit (50% at 1.5R)
ADX > 18, H1 DI, H4 DI, D1 EMA200, partial exit: 50% at 1.5R, remainder at 3.0R1141.328
+32.8% above baseline
+14,185SUBPAR
W15-V
W15-S + DI Spread Expanding
ADX > 18, H1 DI, H4 DI, D1 EMA200, |+DI − −DI| expanding vs 2 bars ago2450.00%1.791
+79.1% above baseline
+6,285SUBPAR
W15-W
W15-S + VWAP Direction
ADX > 18, H1 DI, H4 DI, D1 EMA200, VWAP direction alignment3839.47%1.254
+25.4% above baseline
+3,995SUBPAR
W15-I
5m Timeframe Test
ADX(14) on 5m chart — full noise test25.25%0.538
below 1.0
FAIL
W15-P
ADX Rising (single bar)
ADX > 18, H1 DI, D1 EMA200, ADX must be rising on exact crossover bar7FAIL
W15-Q
ADX Not-Falling (3-bar lookback)
ADX > 18, H1 DI, D1 EMA200, ADX not falling over 3-bar lookback4FAIL
L1ADX>18 beats ADX>20
Lower threshold adds quality trades that the 20-cutoff discards. FCPO's trending structure means valid DI crosses can occur at ADX 18–20. The extra volume from ADX>18 is worth keeping with a quality secondary filter.
L2H1 DI alignment is the single best quality filter
+7.76 percentage point win-rate improvement (33.6% → 44.07%). PF rises from 1.068 to 1.454. When H1 DI agrees with the 15m DI cross signal direction, the probability of a sustained move increases significantly.
L3EMA21 is redundant when H1 DI is present
H1 DI alignment already implies that price is on the correct side of a trending structure. Adding EMA21 on top kills 7 trades (52→59 when removed) and slightly lowers WR and PF. Drop EMA21 when H1 DI is in the filter stack.
L4D1 EMA200 is a mandatory gate — never remove it
W15-J shows that removing D1 EMA200 adds 84 back-trades but drops PF. These are counter-trend trades that inflate trade count but dilute quality. D1 EMA200 correctly filters structural counter-trend setups.
L55m timeframe is pure noise for this system
W15-I: WR 25.25%, PF 0.538 — worse than coin-flip. ADX(14) on a 5-minute chart in FCPO has no predictive value. The DI Cross system requires the 15-minute chart as minimum timeframe.
L6ADX rising filter is too restrictive
W15-G drops trade count from 144 to just 22. ADX often plateaus or slightly dips at the exact moment of a valid DI cross signal — the market is already trending, ADX just stops accelerating. Requiring ADX to be rising kills legitimate entries.
L7Session 10:30–12:30 MYT is the correct window
All valid FCPO DI crosses in this system occur after the 10:30 MYT market open warm-up period. FCPO takes ~15–30 minutes to establish direction after open. The 12:30 cutoff avoids the thin lunch window (12:30–14:30 MYT).
L8H4 DI alignment is the single best quality filter (3-TF stack)
W15-S adds H4 DI to the existing H1 DI filter, creating a 3-TF institutional stack (15m + H1 + H4). This removes only 2 net-losing trades vs W15-L, adds +1,595 MYR, and tightens drawdown from unconstrained to 1.11%. The H4 timeframe captures institutional positioning that the H1 alone misses.
L9Session 10:30–12:30 MYT boundary is confirmed optimal
W15-M extended the session to 13:00 MYT and added zero new trades. All FCPO DI crosses happen in the morning window. The 12:30 cutoff is not arbitrary — it is structurally correct for this market.
L10ATR×1.5 SL is correctly sized — wider lets losers run
W15-N tested ATR×2.0 stop loss: WR dropped and PF fell to 1.17 vs 1.562. FCPO's choppy intraday session means wider stops absorb more counter-move before failing. The baseline ATR×1.5 sizing is optimal.
L112.5R is the optimal RR — tighter reduces profit per winner
W15-O tested RR 2.0: PF dropped to 1.12. Tighter TP reduces profit per winner faster than WR improves because FCPO trends, when they occur, carry further than 2R in the AM session. 2.5R captures the natural move.
L12ADX slope filters are dead ends for FCPO 15m
W15-P (single bar rising) produced 7 trades. W15-Q (3-bar not-falling) produced 4 trades. ADX chops at the exact moment of a valid DI cross — requiring it to be rising or not-falling at that specific bar kills legitimate entries without any quality benefit.
L13Volume, VWAP, and prev-day midpoint all hurt performance
W15-R (volume ×1.2), W15-T (prev-day midpoint), and W15-W (VWAP) all degraded WR and PF vs W15-S. The DI+ADX+H1+H4+D1 filter stack already captures the necessary information — these price-structure and volume filters add noise in FCPO's constrained 2-hour session.
L14DI spread widening creates a "sniper" system — extraordinary quality, thin count
W15-V: 24 trades, 50% WR, PF 1.791, DD 0.57%. Extraordinary quality metrics but statistically thin for a trading business. Useful as a sniper overlay for W15-S signals, but not a standalone system.
L15Partial profit exits do not work in FCPO's constrained session
W15-U (50% exit at 1.5R, rest at 3.0R): PF dropped from 1.562 to 1.328 and drawdown doubled to 2.62%. The 2-hour AM session does not give trades enough time to reach 3.0R on the runner leg. Full exits at 2.5R outperform split exits.
Structural FailDI Cross below M15 is not viable for FCPO

Structural incompatibility: ADX(14) lookback too short, 2-hour session too short for ATR-based TP targets, RM30 commission too large relative to smaller TF moves.

Recommendation: Do not waste further testing cycles on DI cross below M15. If intraday precision is needed, use M15 for signal direction and manual sub-bar entry timing.

TFVariantDescriptionPeriodTradesWR%PFPF vs 1.0Status
M5W5-DM5 Bare ADX>18, 2.5RMay 2025–Apr 2026 (~11 months)17127.49%0.547
45.3% below 1.0
FAIL
M5W5-EM5 Bare ADX>18, 3RMay 2025–Apr 2026 (~11 months)16927.22%0.635
36.5% below 1.0
FAIL
M5W5-FM5 Bare ADX>18, 4RMay 2025–Apr 2026 (~11 months)16624.10%0.746
25.4% below 1.0
FAIL
M5W5-JM5 Bare ADX>18, 5RMay 2025–Apr 2026 (~11 months)16120.50%0.735
26.5% below 1.0
FAIL
M3W3-AM3 Bare ADX>18, 2.5RSep 2025–Apr 2026 (~7 months)15730.57%0.631
36.9% below 1.0
FAIL
M3W3-DM3 Bare ADX>18, 5RSep 2025–Apr 2026 (~7 months)13721.17%0.791
20.9% below 1.0
FAIL
M1W1-AM1 Bare ADX>18, 2.5RFeb 2026–Apr 2026 (~2.5 months — thin data)13737.23%0.698
30.2% below 1.0
FAIL
LTF1DI cross requires M15 as minimum timeframe for FCPO
M5, M3, and M1 all fail bare baseline with PF ranging 0.547–0.791. No RR manipulation brings any sub-15m DI cross system above 1.0 PF. The minimum viable timeframe for this signal type on FCPO is M15.
LTF2ADX(14) lookback is structurally insufficient below M15
ADX(14) looks back 14 bars. On M15 that is 3.5 hours — enough to capture a full FCPO trend cycle. On M5 it is 70 minutes. On M3, 42 minutes. On M1, just 14 minutes. At these durations ADX is measuring noise, not trend.
LTF3The 2-hour morning session cannot reach high-RR ATR targets
ATR(14) on M5 reflects small moves. A 5R TP from ATR×1.5 SL on M5 requires a 7.5×ATR move — impossible in 120 minutes. Session close forces premature exit on most "winners," creating a large gap between theoretical PF (1.34–1.48) and actual PF (0.735–0.791).
LTF4Commission (MYR 30) destroys edge faster on lower timeframes
RM30 commission per trade is fixed regardless of timeframe. On M15 this is a small fraction of a 2.5R win. On M5 the same RM30 is a much larger fraction of the smaller average move, eroding every edge before it can compound.
LTF5Higher WR on M1 does not translate to profitability
M1 bare baseline shows WR 37.23% — higher than M5 (27.5%) or M3 (30.6%). But PF is only 0.698 because the "winners" are tiny partial moves from session close, not full TP hits. WR alone is meaningless without examining average win vs average loss size.
LTF6Data history limits lower timeframe statistical validity
TradingView FCPO data: M5 offers ~11 months, M3 only 7 months, M1 just 2.5 months. Results from M1 are based on 2.5 months of data (137 trades) — insufficient for reliable conclusions. Any future M1 testing should wait for more data accumulation.
Hypothesis: If the DI cross confirms trend direction, can a simpler pullback signal — price above EMA50 then dipping to EMA21 and bouncing — find the same profitable trades with better selectivity? Answer: Yes. W16-I reaches PF 1.528, WR 44.68% — a second independent edge, same session, same filters, different entry mechanic.
11
Variants Tested
6
Profitable (PF≥1)
5
Failed (PF<1)
1.528
Best PF
44.68%
Best WR
~726 days
Backtest Period
W16 BestW16-IEMA PB + DI Spread Expanding
EMA50 trend + EMA21 bounce + DI spread expanding + H1+H4 DI + D1 EMA200, ADX>18, TP=2.5R
+9,855
Net PnL
47
Trades
44.68%
Win Rate
1.528
Profit Factor
MYR +13.57/day
Daily Avg
0.71%
Max DD
Best W16 variant. DI spread expanding at the bounce point confirms momentum building in trade direction — eliminates weak bounces. PF 1.528, WR 44.68%, DD only 0.71%. Beautiful steady equity curve. This is the W16 sniper system.
W16-I — Pine Script v6 (copy → TradingView Pine Editor → Add to chart)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W16-I — M15 EMA21 Pullback + DI Spread (ADX>18, H1+H4 DI, D1 EMA200)", shorttitle="W16-I",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

ema21 = ta.ema(close, 21)
ema50 = ta.ema(close, 50)

[plusDI, minusDI, adx] = ta.dmi(14, 14)
diSpread        = math.abs(plusDI - minusDI)
spreadExpanding = diSpread > diSpread[2]

[h1Plus, h1Minus, _h1adx] = request.security(syminfo.tickerid, "60",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h4Plus, h4Minus, _h4adx] = request.security(syminfo.tickerid, "240", ta.dmi(14,14), gaps=barmerge.gaps_off)
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

longSig  = low  <= ema21 and close > ema21 and close > ema50
         and spreadExpanding and plusDI  > minusDI and adx > 18
         and h1Plus > h1Minus and h4Plus > h4Minus
         and close > ema200d and strategy.position_size == 0

shortSig = high >= ema21 and close < ema21 and close < ema50
         and spreadExpanding and minusDI > plusDI  and adx > 18
         and h1Minus > h1Plus and h4Minus > h4Plus
         and close < ema200d and strategy.position_size == 0

if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
W16 Variant Results
11 variants — sorted by Daily Avg MYR
VariantDescriptionTradesWR%PFPF BarDaily AvgNet MYRStatus
W16-J
W16-I with 3R TP
W16-I setup with TP=3R instead of 2.5R4738.30%1.474
+47.4% above baseline
+13.68+9,930SUBPAR
W16-IBest
EMA PB + DI Spread Expanding
EMA50 trend + EMA21 bounce + DI spread expanding + H1+H4 DI + D1 EMA200, ADX>18, TP=2.5R4744.68%1.528
+52.8% above baseline
+13.57+9,855GOOD
W16-D
EMA PB + H1+H4+D1, TP 2.5R
EMA50 trend + EMA21 bounce + H1+H4 DI + D1 EMA200, ADX>18, TP=2.5R12438.71%1.149
+14.9% above baseline
+11.38+8,260SUBPAR
W16-K
2-Bar Pullback Confirmation
EMA50 trend + 2 consecutive bars touching EMA21 + bounce + H1+H4 DI + D1 EMA200, TP=2.5R9138.46%1.100
+10.0% above baseline
+5.84+4,240SUBPAR
W16-C
EMA PB + H1 + H4 DI + D1
EMA50 trend + EMA21 bounce + H1+H4 DI alignment + D1 EMA200, ADX>1811731.62%1.061
+6.1% above baseline
+4.83+3,505SUBPAR
W16-H
EMA50 Pullback (deeper retracement)
EMA200 trend + EMA50 bounce + H1+H4 DI + D1 EMA200, ADX>18, TP=2.5R7736.36%1.012
+1.2% above baseline
+0.59+430SUBPAR
W16-B
EMA PB + H1 DI + D1 EMA200
EMA50 trend + EMA21 bounce + H1 DI alignment + D1 EMA200, ADX>1813129.01%0.939
below 1.0
-5.59-4,060FAIL
W16-A
EMA21 Bounce Bare Baseline
EMA50 trend + EMA21 touch + bounce, ADX>18, session 10:30–12:3025228.17%0.873
below 1.0
-23.13-16,795FAIL
W16-E
Both Sessions (Morning + Afternoon)
W16-D + afternoon session 14:30–18:00 added25631.25%0.794
below 1.0
-37.38-27,135FAIL
W16-F
EMA PB + RSI<40 Filter
W16-D + RSI(14) < 40 at EMA21 touch0FAIL
W16-G
EMA PB + RSI<50 Filter
W16-D + RSI(14) < 50 at EMA21 touch333.33%0.566
below 1.0
-930FAIL
W16-L1EMA21 pullback in EMA50 uptrend is a viable independent signal
W16-A bare baseline (252 trades, PF 0.873) shows raw edge exists. The same H1+H4 DI+D1 filter stack that rescued W15 rescues W16 too — confirming these filters capture genuine institutional structure, not just DI-cross-specific noise.
W16-L2DI spread expanding at the bounce is the critical quality gate
W16-I: adding DI spread expanding at the EMA21 bounce point lifts PF from 1.149 → 1.528 and WR from 38.7% → 44.68%. The same filter created W15-V (PF 1.791). DI spread widening at entry confirms momentum is building — the market is committing to the direction.
W16-L3Morning session is correct for EMA pullback too — afternoon destroys edge
W16-E (both sessions): WR drops to 31.25%, PF collapses to 0.794. Estimated afternoon WR: ~24% (below 28.6% breakeven). The afternoon FCPO session (14:30–18:00 MYT) is structurally choppy for both DI cross and EMA pullback signals.
W16-L42.5R TP is optimal — confirmed for a second independent strategy
W16-J tested 3R: WR dropped 6.38pp, PF fell from 1.528 to 1.474. For the 2-hour FCPO morning session, 2.5R strikes the right balance between target achievability and reward size. This finding now holds across W15 and W16.
W16-L5RSI filters are incompatible with shallow EMA21 pullbacks
W16-F (RSI<40): 0 trades. W16-G (RSI<50): 3 trades. When price is above EMA50 and just dipping to EMA21, RSI naturally stays above 40–50 — the pullback is too shallow for RSI to register as oversold. Use DI spread expanding instead.
W16-L6EMA21 beats EMA50 as the pullback level
W16-H (EMA50 pullback): PF 1.012, 77 trades. Deeper pullbacks to EMA50 are not higher quality — they often signal trend weakening rather than healthy retracement. EMA21 in a strong trend (above EMA50 + H1+H4 DI aligned) is the correct dynamic support.
W16-L7Two independent profitable systems confirmed for FCPO M15
W15-S (DI Cross): PF 1.562, 57 trades. W16-I (EMA Pullback): PF 1.528, 47 trades. Different entry mechanisms, same filter stack. These can be traded independently or combined for more signal opportunities without signal duplication.
W15-S · DI Cross
15m +DI/-DI crossover + 3-TF institutional stack
PF1.562
WR45.61%
Trades57
Avg/day+16.60 MYR/day
W16-I · EMA Pullback
EMA50 trend → EMA21 bounce + DI spread expanding
PF1.528
WR44.68%
Trades47
Avg/day+13.57 MYR/day
Hypothesis: Can any M5 system deliver 1–5 trades/day with RM100/day net profit? Answer: Partial. W17-M achieves PF ~1.25, 0.34 trades/day, +RM18/day per contract. The quality is real — but M5 has a structural frequency ceiling. RM100/day requires 5–6 contracts or portfolio combination.
15
Variants Tested
5
Profitable (PF≥1)
10
Failed (PF<1)
1.250
Best PF
0.34
Avg Trades/Day
~105 days M5
Backtest Period
W17 BestW17-MEMA21 PB Both Sessions 2.5RM5 · Both Sessions
EMA50 trend + EMA21 bounce + M5 DI spread exp + M15 DI spread exp[3] + M15 direction + H1+H4+D1, fixed TP 50pt, SL 20pt, both sessions
+1,915
Net PnL
36
Trades
33.33%
Win Rate
1.250
Profit Factor
MYR +18.24/day
Daily Avg
0.85%
Max DD
Best W17 variant. 2.5R targets (50pt TP/20pt SL) — same proven ratio as M15 strategies. Clean rising equity curve in second half. PF ~1.25, 0.34 trades/day, +RM18/day per contract.
W17-M — Pine Script v6 (copy → TradingView Pine Editor → Add to chart)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W17-M — M5 EMA21 PB Both Sessions (M5/M15 DI + H1+H4+D1)", shorttitle="W17-M",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

ema21 = ta.ema(close, 21)
ema50 = ta.ema(close, 50)

[plusDI, minusDI, _adx] = ta.dmi(14, 14)
diSpread        = math.abs(plusDI - minusDI)
spreadExpanding = diSpread > diSpread[2]

f_m15spread() =>
    [p, m, _] = ta.dmi(14, 14)
    math.abs(p - m)

m15SpreadNow = request.security(syminfo.tickerid, "15", f_m15spread(),    gaps=barmerge.gaps_off)
m15Spread3   = request.security(syminfo.tickerid, "15", f_m15spread()[3], gaps=barmerge.gaps_off)
m15SpreadExp = m15SpreadNow > m15Spread3

[m15Plus, m15Minus, _m15adx] = request.security(syminfo.tickerid, "15",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h1Plus,  h1Minus,  _h1adx]  = request.security(syminfo.tickerid, "60",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h4Plus,  h4Minus,  _h4adx]  = request.security(syminfo.tickerid, "240", ta.dmi(14,14), gaps=barmerge.gaps_off)
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

longSig  = low  <= ema21 and close > ema21 and close > ema50
         and spreadExpanding and plusDI  > minusDI
         and m15SpreadExp and m15Plus > m15Minus
         and h1Plus > h1Minus and h4Plus > h4Minus
         and close > ema200d and strategy.position_size == 0

shortSig = high >= ema21 and close < ema21 and close < ema50
         and spreadExpanding and minusDI > plusDI
         and m15SpreadExp and m15Minus > m15Plus
         and h1Minus > h1Plus and h4Minus > h4Plus
         and close < ema200d and strategy.position_size == 0

if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
W17 Variant Results
15 variants — sorted by Daily Avg MYR
VariantDescriptionTradesWR%PFPF BarDaily AvgNet MYRStatus
W17-MBest
EMA21 PB Both Sessions 2.5R
EMA50 trend + EMA21 bounce + M5 DI spread exp + M15 DI spread exp[3] + M15 direction + H1+H4+D1, fixed TP 50pt, SL 20pt, both sessions3633.33%1.250
+25.0% above baseline
+18.24+1,915PROMISING
W17-K
M5 EMA21 PB Both Sessions 2R
W17-J setup extended to both sessions (10:30–12:30 + 14:30–18:00 MYT), fixed TP 30pt, SL 15pt3938.46%1.250
+25.0% above baseline
+14.86+1,560PROMISING
W17-G
M5 DI Cross + M15 Spread Expanding
M5 DI crossover + M15 DI spread expanding + M15 DI direction + H1+H4+D1, fixed TP 50pt, SL 20pt1442.86%1.875
+87.5% above baseline
+14.74+2,785GOOD
W17-H
M5 DI Cross + M15 Spread[1]
W17-G with M15 spread compared to [1] bar instead of [3]650.00%2.500
+150.0% above baseline
+11.33+1,665GOOD
W17-J
M5 EMA21 PB + M15 Spread (AM only)
EMA50 trend + EMA21 bounce + M5 DI spread exp + M15 DI spread exp + H1+H4+D1, fixed TP 30pt, SL 15pt, morning session 10:30–12:301136.36%1.143
+14.3% above baseline
+4.94+415SUBPAR
W17-Q
W17-M Without H4 Filter
W17-M but H1+D1 only — H4 DI requirement removed42-0.95-120FAIL
W17-N
EMA13 PB Instead of EMA21
W17-M but EMA13 as pullback level and EMA34 as trend (instead of EMA21/EMA50)52-25.16-3,170FAIL
W17-P
M15 Spread Lookback [2]
W17-M but M15 DI spread compared to [2] M5 bars back instead of [3]30-25.40-3,200FAIL
W17-A
M5 EMA21 PB Fixed TP 40pt
W16-I signal on M5: EMA50 trend + EMA21 bounce + DI spread exp + H1+H4+D1, fixed TP 40pt, SL=ATR×1.051-26.60-5,585FAIL
W17-L
EMA21 PB No M5 Spread Req
W17-K but removing M5 DI spread expanding requirement (M15 spread only)69-30.08-3,790FAIL
W17-F
M5 DI Cross Fixed TP 30pt
M5 DI crossover + H1+H4+D1, no ADX threshold, fixed TP 30pt, SL 15pt, session 10:30–12:3070-34.29-7,200FAIL
W17-O
W17-M with ATR-based SL
W17-M but SL = M5 ATR × 1.0 instead of fixed 20pt46-48.29-6,085FAIL
W17-D
M5 ORB 15-min + HTF DI
Opening Range 10:30–10:45 MYT, trade breakout 10:45–12:30, H1+H4+D1, TP=1.5×range, SL=0.75×range, 1 trade/session63-61.45-12,905FAIL
W17-E
M5 ORB 15-min Bare
Opening Range 10:30–10:45 MYT, no HTF filters, TP=1.5×range, SL=0.75×range177-63.55-13,345FAIL
W17-I
M5 EMA8 Bounce + M15 Trend
EMA34 trend + EMA8 bounce + M15 DI spread>8 + M15 direction + H1+H4+D1, fixed TP 30pt, SL 15pt83-75.02-15,755FAIL
W17-L1M5 EMA21 pullback + dual DI spread expanding is the first viable M5 edge
W17-M: +RM1,915 / 36 trades / PF ~1.25 across 105 days. Requires both M5 DI spread AND M15 DI spread expanding simultaneously. Either alone is insufficient — together they confirm momentum building at two timeframe levels.
W17-L2M15 DI spread [3] bars back is the structurally correct M5 context window
3 M5 bars = exactly 1 M15 bar. Comparing current M15 DI spread to [3] M5 bars ago checks genuine M15-bar-over-M15-bar expansion. [2] misaligns with M15 boundaries (more noise). [1] fires on intrabar noise. [3] is the precise mapping.
W17-L3EMA21 is the correct pullback level on M5 — EMA8 and EMA13 both fail
EMA8 (W17-I): 83 trades, −RM15,755. EMA13 (W17-N): 52 trades, −RM3,170. EMA21 (W17-M): 36 trades, +RM1,915. The EMA21 represents 105 minutes on M5 — enough to be a meaningful support in trending conditions. Faster EMAs are pure noise.
W17-L4Both sessions (morning + afternoon) double trade count without hurting quality
Morning only (W17-J): 11 trades, +RM415. Both sessions (W17-K): 39 trades, +RM1,560. The M15 DI spread expanding filter acts as a quality gate for afternoon trades — it only allows entries during genuinely trending afternoon windows, filtering out the chop that destroyed W16-E.
W17-L5H4 DI is mandatory on M5 — its role is identical to M15
W17-Q (no H4): −RM120, essentially breakeven. W17-M (with H4): +RM1,915. H4 DI provides the institutional direction stack. Without it, noise from ranging H4 conditions floods the M5 signal. Same finding as M15 where H4 was the single biggest PF improvement.
W17-L6Fixed 2.5R targets (50pt TP / 20pt SL) are optimal — ATR-based fails on M5
W17-O (ATR×1.0 SL): −RM6,085. W17-M (fixed 20pt SL): +RM1,915. ATR on M5 can exceed the fixed 50pt TP target, breaking the 2.5R ratio. Fixed targets decouple entry quality from volatility noise. 2.5R is confirmed optimal across M15 and M5.
W17-L7ORB and DI crossover are structurally wrong for FCPO M5
ORB (W17-D/E): FCPO opening range reverses as often as it continues — no directional commitment unlike US equity index futures. DI crossover (W17-F/G): too rare on M5 (once per session maximum). EMA21 pullback fires multiple times per session when context aligns — correct signal type for frequency target.
W17-L8M5 FCPO structural ceiling: ~0.3–0.5 trades/day at quality PF > 1.2
After 15 variants, the maximum frequency at PF ≥ 1.2 is ~0.34 trades/day. The M15 DI spread expanding condition covers approximately 1–2 M15 bars per session — during those windows, only 0–1 EMA21 touches occur on M5. To reach RM100/day target: size to 5–6 contracts per W17-M signal (DD rises from 0.85% to ~4.3%), or combine W15-S + W16-I + W17-M as a portfolio.
Each system alone falls short of RM100/day on 1 contract. Combined, they fire on different signals and different timeframes — portfolio diversification without signal overlap.
W15-S · M15 DI Cross
3-TF stack: H1+H4+D1
PF1.562
WR45.61%
Trades57
Avg/day+16.60 MYR/day
W16-I · M15 EMA Pullback
EMA50→EMA21 bounce + DI spread
PF1.528
WR44.68%
Trades47
Avg/day+13.57 MYR/day
W17-M · M5 EMA21 PB
Dual spread: M5+M15 expanding
PF1.250
WR33.33%
Trades36
Avg/day+18.24 MYR/day (×1)
RM100/day path: W15-S + W16-I combined ≈ +RM30/day on M15 · W17-M at 5 contracts ≈ +RM91/day · Portfolio total ≈ RM120+/day with DD spreading across three independent signals. Next step: paper trade all three systems live for 30–60 days (out-of-sample) before committing capital.
Two questions tested: (1) Can W15-S + W16-I be combined into one script as a portfolio? (2) Can the M5 edge be improved beyond W17-M? Key discovery: The M5 EMA21 pullback edge exists entirely in the PM session — AM session alone loses money. Isolating PM gives PF ~1.69, +RM48/day, 0.98% DD.
8
Variants Tested
6
Profitable (net+)
4
Failed
1.691
Best PF (est.)
++47.98/day
Best Daily Avg
0.45
PM Trades/Day
W18 BestW18-HM5 EMA21 PM Session M15 DirectionM5 · PM Session Only
EMA50 trend + EMA21 bounce + M5 DI spread exp + M15 DI direction + H1+H4+D1, PM session only (14:30–18:00 MYT)
+6,050
Net PnL
57
Trades
40.35%
Win Rate
1.691
Profit Factor
MYR +47.98/day
Daily Avg
0.98%
Max DD
Best W18 variant. PM session only removes net-losing AM trades and isolates the true edge. By 14:30 MYT, M15 trend is 4+ hours confirmed, H4 direction established — EMA21 on M5 acts as genuine trend-continuation support. Est. PF ~1.69, WR ~40%. At 3 contracts: +RM143/day, ~2.94% DD — exceeds RM100/day target.
W18-H — Pine Script v6 (copy → TradingView Pine Editor → Add to chart)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W18-H — M5 EMA21 PB PM Session (M5 DI, M15 Direction, H1+H4+D1)", shorttitle="W18-H",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

ema21 = ta.ema(close, 21)
ema50 = ta.ema(close, 50)

[plusDI, minusDI, _adx] = ta.dmi(14, 14)
diSpread        = math.abs(plusDI - minusDI)
spreadExpanding = diSpread > diSpread[2]

[m15Plus, m15Minus, _m15adx] = request.security(syminfo.tickerid, "15",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h1Plus,  h1Minus,  _h1adx]  = request.security(syminfo.tickerid, "60",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h4Plus,  h4Minus,  _h4adx]  = request.security(syminfo.tickerid, "240", ta.dmi(14,14), gaps=barmerge.gaps_off)
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

inSession = not na(time("5", "1430-1800:23456"))

longSig  = low  <= ema21 and close > ema21 and close > ema50
         and spreadExpanding and plusDI  > minusDI
         and m15Plus > m15Minus and h1Plus > h1Minus and h4Plus > h4Minus
         and close > ema200d and inSession and strategy.position_size == 0

shortSig = high >= ema21 and close < ema21 and close < ema50
         and spreadExpanding and minusDI > plusDI
         and m15Minus > m15Plus and h1Minus > h1Plus and h4Minus > h4Plus
         and close < ema200d and inSession and strategy.position_size == 0

if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
AM Only (10:30–12:30)
−RM2,410
36T · −RM22.95/day
PM Only (14:30–18:00) ✓ Best
+RM6,050
57T · +RM47.98/day
Both Sessions
+RM4,425
77T · +RM35.12/day
Why PM wins: By 14:30 MYT, the M15 trend has been running for 4+ hours — direction is confirmed at H1, H4, and D1. EMA21 on M5 acts as established trend-continuation support, not early-session resistance. Morning EMA21 touches fail because the trend hasn't fully committed yet.
W18 Variant Results
8 variants — sorted by Daily Avg MYR
VariantDescriptionTradesWR%PFPF BarDaily AvgNet MYRStatus
W18-HBest
M5 EMA21 PM Session M15 Direction
EMA50 trend + EMA21 bounce + M5 DI spread exp + M15 DI direction + H1+H4+D1, PM session only (14:30–18:00 MYT)5740.35%1.691
+69.1% above baseline
+47.98+6,050GOOD
W18-E
M5 EMA21 PB M15 Direction Both Sessions
EMA50 trend + EMA21 bounce + M5 DI spread exp + M15 DI direction (no spread req) + H1+H4+D1, AM+PM sessions77+35.12+4,425PROMISING
W18-I
M5 EMA21 PM + M15 SpreadExp
W18-H but M15 DI spread expanding [3] restored (original W17-M filter)2638.46%1.563
+56.3% above baseline
+34.50+2,415GOOD
W18-B
Portfolio Combined Single Contract
W15-S OR W16-I signal fires first, single contract (pyramiding=0), ATR×1.5 SL, 2R TP106+5.31+2,790SUBPAR
W18-F
M5 EMA21 M15 Spread > 5 Threshold
W18-E but M15 DI spread must exceed 5 (absolute threshold instead of expanding)63+2.30+290FAIL
W18-C
W16-I + H1 Spread Expanding Gate
All W16-I conditions + H1 DI spread expanding (h1DiSpread > h1DiSpread[4])30-0.60-300FAIL
W18-G
M5 EMA21 M15Dir AM Session Only
W18-E logic, morning session only (10:30–12:30 MYT)36-22.95-2,410FAIL
W18-A
Portfolio Combined Pyramid
W15-S + W16-I signals both in same script, pyramiding=2, separate entry/exit IDs140+6,975FAIL
W18-L1M5 EMA21 pullback edge lives entirely in the PM session (14:30–18:00 MYT)
W18-G (AM only): −RM2,410. W18-H (PM only): +RM6,050. The morning session for M5 EMA21 pullback is net-losing — price uses EMA21 as resistance in early-session when trend direction is still establishing. By 14:30, the M15 trend has been running 4+ hours, H4 direction is confirmed, and EMA21 genuinely acts as trend-continuation support.
W18-L2M15 direction alone (no spread expanding) is the right filter for PM entries
W18-H (M15 direction): 57 trades, +RM6,050. W18-I (M15 spread expanding): 26 trades, +RM2,415. The spread-expanding filter cuts profitable PM trades in half. Good PM pullbacks occur throughout the M15 trend — not just when momentum is freshly accelerating. Direction confirmation is sufficient quality gate in PM session.
W18-L3W18-H at 3 contracts achieves RM100/day target: +RM143/day, ~2.94% DD
W18-H baseline: +RM47.98/day at 1 contract, 0.98% DD. At 3 contracts: +RM143.94/day, ~2.94% max DD on 500k capital = RM14,730 worst drawdown. Portfolio path: W15-S + W16-I (combined +RM30/day on M15, 1 contract each) + W18-H ×2 contracts (+RM96/day) = RM126+/day total.
W18-L4W15-S and W16-I cannot be cleanly merged into a single-contract script
W18-A (pyramiding=2): exit IDs cross-contaminate — W15LX closes W16L positions. W18-B (pyramiding=0): entry conflicts cause one system's open trade to block the other's signal. These systems must run as independent contracts. Portfolio value = sum of individual values, not a combined script.
W18-L5The H1 DI spread expanding concept does not transfer from M5→M15 to M15→H1
W18-C tested applying the W17 dual-spread insight one TF up: M15 EMA21 pullback + H1 DI spread expanding. Result: −RM300. W16-I is already filtered by M15 DI spread + 3-TF direction stack — adding H1 spread removing profitable trades without improving quality. The dual-spread breakthrough was specific to M5 (where noise was the problem), not M15.
W18-L6M15 DI spread threshold (>5) removes good trades, not bad ones
W18-F tested M15 DI spread > 5 as a quality gate. Result: −14 trades removed, income dropped from +RM35.12 to +RM2.30/day. Good M5 EMA21 pullbacks occur when M15 DI spread is low-to-moderate (trend beginning or mid-trend) — not when it's overextended (high spread). The pullback quality does not correlate with M15 spread size.
W18-L7W18-H is the new flagship M5 system — replaces W17-M as primary M5 edge
W17-M: 0.34T/day, +RM18.24/day, PF ~1.25, 0.85% DD. W18-H: 0.45T/day, +RM47.98/day, PF ~1.69, 0.98% DD. Same M5 EMA21 pullback logic — only differences are PM session isolation and removal of M15 spread expanding requirement. Both changes improve the system substantially.
Research question: W18-H uses EMA21 as the pullback level. Is EMA21 optimal, or does a deeper pullback (EMA34, EMA55) give better quality entries? Answer: EMA34 is the sweet spot — fewer entries but 2.3× higher per-trade income, PF ~1.87 vs 1.69, DD nearly halved. A full factorial experiment on M5 DI conditions confirmed: spread expanding AND direction are synergistic — neither alone is sufficient.
10
Variants Tested
8
Profitable (net+)
6
Failed
1.870
Best PF (est.)
++51.83/day
Best Daily Avg
+RM242
Per-Trade Avg
W19 BestW19-FEMA34 Pullback PM SessionM5 · EMA34 · PM Session
EMA50 trend + EMA34 bounce + M5 DI spread exp + M5 DI direction + M15 direction + H1+H4+D1, PM session 14:30–18:00, TP 50pt, SL 20pt
+6,530
Net PnL
27
Trades
~48%
Win Rate (est.)
1.870
Profit Factor (est.)
MYR +51.83/day
Daily Avg
0.53%
Max DD
Best W19 variant. EMA34 as pullback target requires deeper retracement — by the time price bounces from EMA34, it has more momentum behind it. Est. WR ~48%, PF ~1.87, +RM242/trade. DD nearly halved vs W18-H (0.53% vs 0.98%). At 2 contracts: +RM103.66/day, ~1.06% DD.
W19-F — Pine Script v6 (copy → TradingView Pine Editor → Add to chart)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W19-F — M5 EMA34 PB PM Session (M5/M15 DI, H1+H4+D1)", shorttitle="W19-F",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

ema34 = ta.ema(close, 34)
ema50 = ta.ema(close, 50)

[plusDI, minusDI, _adx] = ta.dmi(14, 14)
diSpread        = math.abs(plusDI - minusDI)
spreadExpanding = diSpread > diSpread[2]

[m15Plus, m15Minus, _m15adx] = request.security(syminfo.tickerid, "15",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h1Plus,  h1Minus,  _h1adx]  = request.security(syminfo.tickerid, "60",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h4Plus,  h4Minus,  _h4adx]  = request.security(syminfo.tickerid, "240", ta.dmi(14,14), gaps=barmerge.gaps_off)
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

inSession = not na(time("5", "1430-1800:23456"))

longSig  = low  <= ema34 and close > ema34 and close > ema50
         and spreadExpanding and plusDI  > minusDI
         and m15Plus > m15Minus and h1Plus > h1Minus and h4Plus > h4Minus
         and close > ema200d and inSession and strategy.position_size == 0

shortSig = high >= ema34 and close < ema34 and close < ema50
         and spreadExpanding and minusDI > plusDI
         and m15Minus > m15Plus and h1Minus > h1Plus and h4Minus > h4Plus
         and close < ema200d and inSession and strategy.position_size == 0

if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
EMA Pullback Level Curve
EMA21 (W18-H)
57 trades · +RM47.98/day
0.98% DD · PF ~1.69
Baseline
EMA34 (W19-F)
27 trades · +RM51.83/day
0.53% DD · PF ~1.87
SWEET SPOT
EMA55 (W19-G)
14 trades · +RM47.5/day
0.35% DD · PF ~2.69
Too few
VariantDescriptionTradesPF (est.)DD%Daily AvgNet PnLStatus
W19-FEMA34 Pullback PM Session271.870.53%+51.83+6,530EXCELLENT
W19-HEMA34 PM Tight SL 15pt271.770.44%+48.65+6,130GOOD
W19-GEMA55 Pullback PM Session142.690.35%+47.50+5,985SUBPAR
W19-JEMA34 Direction Only (No Spread)580.81%+44.60+5,620GOOD
W19-MEMA34 PM + M5 ADX > 15 Filter190.43%+19.13+2,410FAIL
W19-LEMA34 Both Sessions (AM + PM)431.33%+18.41+2,320FAIL
W19-EEMA21 PM Session 3R Targets (60pt TP)561.28%+9.21+1,160FAIL
W19-KEMA34 Spread Only (No Direction)500.63%+2.98+375FAIL
W19-DEMA21 No M5 Spread Expanding851.88%-2.02-255FAIL
W19-IEMA34 No M5 DI Conditions901.69%-49.60-6,250FAIL
W19-L1EMA34 beats EMA21 as the M5 pullback level — deeper = cleaner
EMA21 (W18-H): 57 trades, +RM106/trade, PF ~1.69. EMA34 (W19-F): 27 trades, +RM242/trade, PF ~1.87, DD 0.53% vs 0.98%. Deeper pullback to EMA34 means the market has committed more to the retracement — by the time it bounces, momentum is greater. Fewer but significantly higher-quality entries.
W19-L2M5 DI spread expanding AND direction are synergistic — both mandatory
Factorial experiment: spread+direction=+RM6,530 | direction only=+RM5,620 | spread only=+RM375 | neither=−RM6,250. Spread expanding confirms momentum is building. Direction confirms which side. Together: momentum building in the correct direction = high-quality EMA34 bounce. Either alone is insufficient.
W19-L350pt TP is the structural ceiling for PM FCPO M5 — confirmed across EMA levels
W19-E (EMA21, 60pt TP): +RM1,160. W18-H (EMA21, 50pt TP): +RM6,050. Regardless of entry quality or EMA level, PM FCPO intraday M5 moves consistently reach 50pt but rarely 60pt before reversing. 50pt / 20pt SL (2.5R) is universally optimal for this session and timeframe.
W19-L4Session-Timeframe Law confirmed 4th time: M5 pullbacks fail in AM
W19-L (both sessions): +RM2,320. W19-F (PM only): +RM6,530. Adding AM session: 16 losing trades reduce income by 64%. This is now confirmed with both EMA21 and EMA34 pullback systems at M5 — the AM session structurally does not support M5 EMA pullback entries regardless of EMA level.
W19-L5ADX filter removes the best entries, not the worst
W19-M (ADX > 15): 19 trades, +RM2,410 vs 27 trades, +RM6,530. The 8 trades removed by ADX > 15 had higher per-trade quality than those that remained. Moderate-ADX conditions (10–15) = fresh trend, best pullback entries. High ADX = overextended trend, pullbacks less reliable. No ADX threshold is correct.
W19-L6EMA55 is a structurally different (and impractical) pattern
EMA55 < EMA50 in uptrend — touching EMA55 means price wicked below EMA50 and recovered. Only 14 trades over 126 days (0.11/day). Despite high estimated PF (~2.69) and low DD (0.35%), the sample is too thin for a trading business. EMA34 (27 trades, 0.21/day) is the practical optimal pullback level.
W19-L7W19-F at 2 contracts achieves RM100/day — better than W18-H at 3
2 × +RM51.83 = RM103.66/day, ~1.06% DD. This surpasses W18-H at 3 contracts (RM143.94/day, 2.94% DD) in DD efficiency. W19-F is the more capital-efficient path to the RM100/day target — same income at significantly lower drawdown risk.
Research question: W19-F enters when price touches EMA34 — but is EMA34 genuinely acting as dynamic support, or just coincidentally at that price level? Insight: Require EMA34 to be rising over the last 3 bars. A rising EMA34 = actively moving support. A flat/declining EMA34 = random coincidence. Result: 4 trades removed, PF lifts from ~1.87 to ~2.20, DD falls from 0.53% to 0.41%.
9
Variants Tested
8
Profitable (net+)
4
Failed
2.200
Best PF (est.)
++56.70/day
Best Daily Avg
+RM311
Per-Trade Avg
W20 Best · All-Time ChampionW20-DEMA34 PM + EMA34 Slope Rising [3]M5 · EMA34 + Slope · PM Session
W19-F full conditions + EMA34 must be rising over last 3 bars (ema34 > ema34[3])
+7,145
Net PnL
23
Trades
~52%
Win Rate (est.)
2.200
Profit Factor (est.)
MYR +56.70/day
Daily Avg
0.41%
Max DD
Best W20 variant and new all-time champion. EMA34 slope[3] removes entries where EMA34 is flat or declining — those are coincidental price crossings, not genuine dynamic support touches. Est. WR ~52%, PF ~2.20, +RM311/trade, DD 0.41%. At 2 contracts: +RM113.4/day, ~0.82% DD.
W20-D — Pine Script v6 (copy → TradingView Pine Editor → Add to chart)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W20-D — M5 EMA34 PB + Slope[3] PM (M5/M15 DI, H1+H4+D1)", shorttitle="W20-D",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

ema34 = ta.ema(close, 34)
ema50 = ta.ema(close, 50)

[plusDI, minusDI, _adx] = ta.dmi(14, 14)
diSpread        = math.abs(plusDI - minusDI)
spreadExpanding = diSpread > diSpread[2]

[m15Plus, m15Minus, _m15adx] = request.security(syminfo.tickerid, "15",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h1Plus,  h1Minus,  _h1adx]  = request.security(syminfo.tickerid, "60",  ta.dmi(14,14), gaps=barmerge.gaps_off)
[h4Plus,  h4Minus,  _h4adx]  = request.security(syminfo.tickerid, "240", ta.dmi(14,14), gaps=barmerge.gaps_off)
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

inSession    = not na(time("5", "1430-1800:23456"))
ema34Rising  = ema34 > ema34[3]
ema34Falling = ema34 < ema34[3]

longSig  = low  <= ema34 and close > ema34 and ema34Rising  and close > ema50
         and spreadExpanding and plusDI  > minusDI
         and m15Plus > m15Minus and h1Plus > h1Minus and h4Plus > h4Minus
         and close > ema200d and inSession and strategy.position_size == 0

shortSig = high >= ema34 and close < ema34 and ema34Falling and close < ema50
         and spreadExpanding and minusDI > plusDI
         and m15Minus > m15Plus and h1Minus > h1Plus and h4Minus > h4Plus
         and close < ema200d and inSession and strategy.position_size == 0

if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
Champion Evolution — 4 Waves of Systematic Improvement
W17-M
M5 Baseline
+RM18.24/day
PF 1.25 · 0.85% DD
W18-H
PM Isolation
+RM47.98/day
PF 1.69 · 0.98% DD
W19-F
EMA34 Depth
+RM51.83/day
PF ~1.87 · 0.53% DD
W20-D
Slope Confirm
+RM56.70/day
PF ~2.20 · 0.41% DD
At 2 contracts of W20-D: +RM113.40/day · ~0.82% max DD · RM100/day goal achieved cleanly.
VariantDescriptionTradesPF (est.)DD%Daily AvgNet PnLStatus
W20-EEMA34 PM + Slope[2] Lookback260.53%+57.06+7,190GOOD
W20-DEMA34 PM + EMA34 Slope Rising [3]232.200.41%+56.70+7,145EXCELLENT
W20-HEMA34 Dual Slope (EMA34+EMA50)232.200.41%+56.70+7,145GOOD
W20-IEMA34 Slope[3] Early PM Only (14:30–16:00)162.590.32%+48.33+6,090GOOD
W20-CEMA21 PM + EMA Alignment (EMA21>EMA34>EMA50)500.98%+5,045SUBPAR
W20-GEMA34 Slope[3] + 60pt TP (3R)230.53%+45.60+5,745FAIL
W20-FEMA34 PM + Slope[5] Lookback210.48%+25.52+3,215FAIL
W20-AM5 DI Cross PM Session651.36%+14.48+1,825FAIL
W20-BM15 EMA34 Level — M5 Trigger80.44%-1,330FAIL
W20-L1EMA34 slope[3] is the key additional filter — only enter when EMA34 is genuinely dynamic support
W19-F (no slope): 27 trades, PF ~1.87. W20-D (slope[3]): 23 trades, PF ~2.20. Adding slope removes 4 trades where EMA34 was flat/declining — those were coincidental price crossings where EMA34 happened to be at that price level, not acting as support. When EMA34 is rising, it is actively moving toward price and price is bouncing off a moving floor — the highest-quality setup.
W20-L2Optimal slope lookback is 3 bars (15 minutes) — neither too fast nor too slow
Slope[2] (10 min): 26 trades, DD 0.53% — too noisy, adds lower-quality trades. Slope[3] (15 min): 23 trades, DD 0.41% — optimal. Slope[5] (25 min): 21 trades, income halved to RM25/day — too strict, removes good early-slope entries. 15 minutes of confirmed EMA34 rise is enough to validate genuine dynamic support.
W20-L3EMA50 slope is redundant — EMA34 slope already implies it
W20-H (dual slope EMA34+EMA50): identical to W20-D. When EMA34 rises over 3 M5 bars, EMA50 — being slower — is always also rising. Adding EMA50 slope as an explicit condition generates zero additional filtering. The faster EMA slope is the sufficient gate.
W20-L4DI cross entries are structurally inferior to pullback entries in PM FCPO
W20-A (DI cross PM): 65 trades, DD 1.36%, barely profitable. DI cross fires on fresh momentum bursts — many are false reversal attempts that immediately fail. EMA34 pullback waits for a real retracement to a confirmed support level with expanding spread — far fewer but much higher-quality entries. Pullback is the correct PM entry paradigm.
W20-L550pt TP ceiling is definitively confirmed across all quality levels
W20-G (W20-D best entries, 60pt TP): +RM5,745 vs +RM7,145 for 50pt TP. Even with the highest-quality EMA34 slope-confirmed entries, extending TP to 60pt reduces income. This is now confirmed across W15 (M15 AM), W18 (M5 EMA21 PM), W19 (EMA34 PM), and W20 (EMA34+slope PM). 50pt is a market structure limit for FCPO afternoon intraday moves.
W20-L6Early PM (14:30–16:00) has highest per-trade quality — full PM is best for income
W20-I (first 90 min PM): 16 trades, PF ~2.59, DD 0.32% — extraordinary per-trade quality. The initial PM session phase captures the strongest first-move-of-afternoon setups. But the later trades (16:00–18:00) are also profitable and needed for income. Full PM window maximizes total daily return.
W20-L7W20-D at 2 contracts is the optimal RM100/day structure
2 × +RM56.70 = +RM113.40/day with ~0.82% max DD. This is the cleanest path found across all 20+ waves: just 2 contracts of one system, 23 entries over 126 days, no session overlap conflicts, no pyramiding. Combined portfolio option: W15-S + W16-I (AM) + W20-D ×2 (PM) ≈ RM143+/day with distributed drawdown.
W20-L8System evolution through 4 waves — each wave found a genuine structural improvement
W17-M (M5 baseline): +RM18/day, PF 1.25, 0.85% DD → W18-H (PM isolation): +RM48/day, PF 1.69, 0.98% DD → W19-F (EMA34 depth): +RM52/day, PF ~1.87, 0.53% DD → W20-D (slope confirmation): +RM57/day, PF ~2.20, 0.41% DD. Each wave: one structural insight, measurable improvement. Systematic improvement is real.
W21 Best · All-Time ChampionW21-OH4 EMA Slope Lookback [5] — 20 Hours (OPTIMAL)M5 · Triple Slope Stack · PM Session
W21-F with H4 EMA34 slope[5] (compare to 20 hours ago). EMA50 removed (confirmed redundant).
+11,915
Net PnL
21
Trades
MYR +94.56/day
Daily Avg
0.32%
Max DD
+RM189/day
2× Contracts
+67% income −22% DD
vs W20-D
W21-O — Production Pine Script (copy → TradingView Pine Editor → Add to chart)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W21-O Production — M5 EMA34 Triple Slope PM", shorttitle="W21-O",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

// ── Entry EMA ──────────────────────────────────────────────────────────────
ema34 = ta.ema(close, 34)

// ── M5 DI ──────────────────────────────────────────────────────────────────
[plusDI, minusDI, _adx] = ta.dmi(14, 14)
diSpread       = math.abs(plusDI - minusDI)
spreadExpanding = diSpread > diSpread[2]        // expanding over last 10 min

// ── M15 ────────────────────────────────────────────────────────────────────
[m15Plus, m15Minus, _m15adx] = request.security(syminfo.tickerid, "15", ta.dmi(14,14), gaps=barmerge.gaps_off)
m15ema34   = request.security(syminfo.tickerid, "15", ta.ema(close, 34),    gaps=barmerge.gaps_off)
m15ema34_3 = request.security(syminfo.tickerid, "15", ta.ema(close, 34)[3], gaps=barmerge.gaps_off)

// ── H4 ─────────────────────────────────────────────────────────────────────
h4ema34   = request.security(syminfo.tickerid, "240", ta.ema(close, 34),    gaps=barmerge.gaps_off)
h4ema34_5 = request.security(syminfo.tickerid, "240", ta.ema(close, 34)[5], gaps=barmerge.gaps_off)

// ── D1 ─────────────────────────────────────────────────────────────────────
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

// ── Session ────────────────────────────────────────────────────────────────
inSession = not na(time("5", "1430-1800:23456"))   // PM session 14:30–18:00 MYT Mon–Fri

// ── Slope gates ────────────────────────────────────────────────────────────
ema34Rising    = ema34    > ema34[3]      // M5 EMA34 rising over 15 min
ema34Falling   = ema34    < ema34[3]
m15Rising      = m15ema34 > m15ema34_3   // M15 EMA34 rising over 45 min
m15Falling     = m15ema34 < m15ema34_3
h4Rising       = h4ema34  > h4ema34_5   // H4 EMA34 rising over 20 hours
h4Falling      = h4ema34  < h4ema34_5

// ── Signals ────────────────────────────────────────────────────────────────
longSig  = low  <= ema34 and close > ema34 and ema34Rising  and m15Rising  and h4Rising
         and spreadExpanding and plusDI  > minusDI and m15Plus  > m15Minus
         and close > ema200d and inSession and strategy.position_size == 0

shortSig = high >= ema34 and close < ema34 and ema34Falling and m15Falling and h4Falling
         and spreadExpanding and minusDI > plusDI  and m15Minus > m15Plus
         and close < ema200d and inSession and strategy.position_size == 0

// ── Entries & Exits ────────────────────────────────────────────────────────
if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
Adding M15 EMA34 slope, replacing H4 DI with H4 EMA slope, and optimizing the H4 lookback. Confirmed H1 is a dead zone. EMA50 proved redundant with triple slope alignment.
H4 EMA34 Slope Lookback Curve — Optimal at 5 Bars (20 hours)
slope[1]/[2]
+RM88.89/day
25T · DD 0.41%
slope[3]
+RM84.88/day
23T · DD 0.41%
slope[4]
+RM89.72/day
22T · DD 0.32%
slope[5] ← OPTIMAL
+RM94.56/day
21T · DD 0.32%
slope[6]
+RM85.32/day
20T · DD 0.52%
12Variants Tested
12/12Profitable
1Failed
++94.56/dayBest Daily Avg
0.32%Best DD
VariantNameTradesNet PnLDaily AvgMax DDStatusVariantDailyDD
W21-DM15 EMA34 Slope + H4 DI Direction (Baseline)22++9,530++75.63/day0.41%EXCELLENTW21-D++75.630.41%
W21-FH4 DI Direction → H4 EMA34 Slope[3]23++10,695++84.88/day0.41%EXCELLENTW21-F++84.880.41%
W21-LH4 EMA Slope Lookback [2] — 8 Hours25++11,200++88.89/day0.41%EXCELLENTW21-L++88.890.41%
W21-NH4 EMA Slope Lookback [4] — 16 Hours22++11,305++89.72/day0.32%EXCELLENTW21-N++89.720.32%
W21-OH4 EMA Slope Lookback [5] — 20 Hours (OPTIMAL)21++11,915++94.56/day0.32%EXCELLENTW21-O++94.560.32%
W21-ERemove H4 DI Direction Entirely34++9,635++76.47/day0.59%GOODW21-E++76.470.59%
W21-GW21-F + H1 EMA34 Slope22++9,305++73.85/day0.41%GOODW21-G++73.850.41%
W21-HW21-F — Remove M15 DI Direction28++7,995++63.45/day0.51%GOODW21-H++63.450.51%
W21-KW21-F + D1 EMA34 Slope22++9,530++75.63/day0.41%GOODW21-K++75.630.41%
W21-PH4 EMA Slope Lookback [6] — 24 Hours (Too Strict)20++10,750++85.32/day0.52%GOODW21-P++85.320.52%
W21-JW21-F — Remove M5 DI Spread Expanding50++8,400++66.67/day0.69%SUBPARW21-J++66.670.69%
W21-IW21-F — Remove M5 DI Direction43++2,920++23.17/day0.67%FAILW21-I++23.170.67%
1. M15 EMA34 slope[3] is a mandatory quality gate — adds +RM19/day over W20-D
Adding M15 EMA34 slope[3] to W20-D: W20-D gets 23 trades at +RM56.70/day; W21-D gets 22 trades at +RM75.63/day (+33% income, same DD). M15 slope removes EMA34 pullbacks during M15 consolidation phases — when M15 EMA34 is flat, the M5 pullback is bouncing off a static level, not genuine dynamic support. When M15 EMA34 is rising, the support is actively moving toward price = highest-quality setup.
2. H4 EMA34 slope beats H4 DI direction — slope filters outperform DI at every HTF
W21-D (H4 DI): +RM75.63/day. W21-F (H4 EMA slope[3]): +RM84.88/day — +RM9.25/day improvement at identical 0.41% DD. Pattern confirmed across every timeframe: EMA slope is a purer directional filter than DI direction. DI says "bulls are winning over bears"; EMA slope says "the trend is actively moving." For pullback entries, active trend movement is the correct confirmation, not momentum battle outcome.
3. H4 slope lookback optimal at 5 bars (20 hours) — clear inflection curve
H4 slope lookback curve: [1]/[2]=+RM88.89/day 0.41% DD, [3]=+RM84.88/day 0.41%, [4]=+RM89.72/day 0.32%, [5]=+RM94.56/day 0.32% (OPTIMAL), [6]=+RM85.32/day 0.52% (drops off). At slope[5], H4 EMA34 must be higher than 20 hours ago — this is long enough to confirm a genuine sustained trend but short enough not to exclude valid entries in normal trending conditions. Longer lookback = fewer trades but higher quality, until [6] where a winner is removed and DD paradoxically worsens.
4. H1 is definitively the dead zone — neither DI nor EMA slope helps at H1
H1 DI direction proved redundant in W21-D (removing it improved from +RM66/day to +RM75/day). H1 EMA slope in W21-G: -RM11/day and removes a winning trade. H1 sits between M15 (medium trend) and H4 (institutional) — it captures neither role cleanly. This system's timeframe architecture is: M5 entry → M15 momentum → H4 trend → D1 regime. H1 is excluded by design.
5. All 5 M5 conditions are mandatory — none is redundant with slope filters
Factorial ablation across W21-H/I/J: Removing M15 DI direction costs -RM21/day (DD rises). Removing M5 DI direction collapses to +RM23/day (catastrophic). Removing M5 DI spread expanding doubles DD to 0.69% and drops -RM18/day. The slope stack (M5+M15+H4 EMA slope) does NOT replace DI conditions — they are complementary. Slope confirms trend direction on the EMA; DI confirms momentum strength and dominance in the current bar. Both perspectives are independently necessary.
6. EMA50 filter is fully redundant with triple slope alignment
W21-Q (remove EMA50 from W21-O): identical results — same 21 trades, same PnL, same DD. When M5 + M15 + H4 EMA34 slopes are all rising, price is already above EMA50 by implication — a faster EMA (34) can only be above a slower EMA (50) when the trend is mature enough. The triple slope stack implicitly guarantees EMA50 position. Remove EMA50 from production script for cleanliness.
7. W21-O production system: 8 conditions, no EMA50, H4 slope[5]
Final W21-O conditions: (1) M5 EMA34 touch (low≤ema34, close>ema34), (2) M5 EMA34 slope[3] rising, (3) M15 EMA34 slope[3] rising, (4) H4 EMA34 slope[5] rising, (5) M5 DI spread expanding, (6) M5 DI direction, (7) M15 DI direction, (8) D1 EMA200 bias, (9) PM session 14:30–18:00 MYT. Result: +RM11,915 · 21 trades · 0.32% DD · +RM94.56/day. 2× contracts = +RM189/day, 0.64% DD — well above RM100/day target.
8. System evolution — each wave found a structural, not cosmetic, improvement
W17-M: +RM18/day, PF 1.25, 0.85% DD → W18-H (PM isolation): +RM48/day → W19-F (EMA34 depth): +RM52/day → W20-D (M5 slope): +RM57/day → W21-O (M15+H4 slope, H4 lookback): +RM94.56/day, 0.32% DD. Each wave: one structural insight, measurable improvement. W21 represents a +67% income increase over W20-D at -22% lower drawdown. The progression from DI-based to slope-based HTF confirmation is the core architectural shift.
W22 exhaustively tested all parametric variations. W23 tested new structural dimensions (weekly TF, H4 EMA period, H4 dual filters). Every test returned identical or worse results — W21-O is at the quality ceiling.
W22 — Parametric Robustness (11 variants)
VariantChange TestedTradesDaily AvgDDVerdict
W22-A/B/CM15 slope lookback [2]–[5]21+94.560.32%Identical — saturated
W22-DM15 DI spread expanding10+51.190.21%Too restrictive
W22-E/FM5 slope [2] and [4]22+85.670.32%Both worse
W22-G/HSession 14:00 start / 18:30 end21+94.560.32%Identical — perfectly calibrated
W22-IM5 spread lookback[1]21+80.080.43%Same trades, worse quality
W22-JD1 DI instead of EMA20026+96.550.40%More trades, higher DD
W22-KD1 EMA200 + DI dual18+66.830.32%Over-filters winners
W23 — Structural Validation (4 variants)
VariantChange TestedTradesDaily AvgDDVerdict
W23-AWeekly EMA34 slope[1]19+90.160.32%Removes 2 winners — H4 slope implies W1
W23-BH4 EMA50 slope[5]20+85.320.32%Misses 1 winner — too slow
W23-CH4 EMA21 slope[5]21+80.480.52%Same trades, DD doubles — too fast
W23-DH4 slope[5] AND H4 DI20+85.320.32%DI redundant with slope[5]
1. W21-O is at the quality ceiling — W22 is a full robustness validation
Every W22 test either returned identical results to W21-O (system saturated/robust) or was worse. No new champion found across 11 variants covering: M15 slope lookback, M15/M5 DI spread, M5 slope lookback, session times, D1 filter alternatives. This is the expected outcome of a deeply optimized system — the parameter space has been thoroughly explored.
2. M15 slope lookback is fully saturated — any value [2]–[5] gives identical results
M15 slope[2] (30min), [3] (45min), [4] (60min), [5] (75min) all produce the exact same 21 trades. The H4 slope[5] filter has already removed all noise; the remaining 21 entries are so strongly trending at M15 that any lookback ≤75 min confirms the slope. M15 slope condition is robust — not a fragile parameter choice.
3. M5 slope[3] (15 min) is confirmed optimal under the new HTF architecture
Slope[2] (10 min) adds 2 noisy trades (-RM9/day). Slope[4] (20 min) changes which trades fire, lower quality. The W20-era finding (slope[3]=optimal at M5) holds under the W21 system despite the added H4 slope[5] layer. 15 minutes of confirmed M5 EMA34 rise is the correct granularity — fast enough to catch early momentum, slow enough to filter coincidental crossings.
4. Session window 14:30–18:00 MYT is precisely calibrated — no extensions add value
Both 14:00 start and 18:30 end produce identical results. Zero qualifying signals exist outside the current window. 14:30 = PM session open with H4 trend established. 18:00 = natural end of productive PM momentum. The FCPO PM session structure itself defines this boundary — not arbitrary parameter choice.
5. D1 EMA200 is the optimal daily bias filter — DI and dual filters both suboptimal
D1 DI alone: +RM96.55/day but DD rises to 0.40% (adds lower-quality trades in trend transitions). D1 dual (EMA200 + DI): +RM66.83/day, removes 3 winners. D1 EMA200 alone (W21-O): +RM94.56/day, 0.32% DD — best quality and income balance. Price above D1 EMA200 is the correct regime filter for intraday long bias.
6. H4 EMA34 is uniquely optimal — EMA21 too noisy, EMA50 too slow, both worse
H4 EMA21 slope[5]: same 21 trades but DD doubles to 0.52% (too fast, noisy). H4 EMA34 slope[5] (W21-O): 21T, 0.32% DD, +RM94.56/day — optimal. H4 EMA50 slope[5]: misses 1 winner, 0.32% DD, +RM85.32/day (too slow). EMA34 is the Goldilocks period at H4: fast enough to register a 20-hour trend as active, slow enough not to trigger on hourly consolidations.
7. H4 slope[5] makes all other H4 confirmations redundant
W23-A (W1 slope added): removes 2 winners — W1 is implied by H4 slope[5]. W23-D (H4 DI added): removes 1 winner — H4 DI is implied by H4 slope[5]. When H4 EMA34 has been consistently rising for 20 hours, all shorter/equivalent timeframe directional filters (DI, weekly slope) are already satisfied. H4 slope[5] is the single sufficient HTF confirmation gate — no stacking needed.
8. W21-O architecture is complete — no further parametric improvements exist within this framework
W22 tested all parametric variations. W23 tested new structural additions (weekly, H4 EMA period, H4 dual filters). All returned either identical or worse results. The system has reached its quality ceiling within the M5 EMA34 pullback + triple slope + DI framework. To improve further would require a fundamentally different entry mechanism, different base EMA for pullback target, or a different market/instrument.
9. Final production system — W21-O, no further changes recommended
Conditions locked: M5 EMA34 touch + slope[3] + DI spread[2] + DI direction; M15 EMA34 slope[3] + DI direction; H4 EMA34 slope[5]; D1 EMA200; PM session 14:30–18:00 MYT. Result: +RM11,915 over 126 days, 21 trades, 0.32% DD, +RM94.56/day. 2 contracts = +RM189/day, 0.64% DD. Ready for 30–60 day paper trade before live deployment.
First backtest of FCPO night session across all waves (W15–W23 never tested it). Applied W21-O conditions to 21:00–23:30 MYT window. Result: positive edge exists but 8× weaker than PM. Night session NOT added to portfolio.
VariantSessionTradesNet PnLDDRM/tradeKey Note
W21-O PM14:30–18:0021+RM11,9150.32%RM567← PM benchmark
W24-A Night21:00–23:3018+RM3,9700.56%RM220Overnight holds contaminate
W24-B Night ✓21:00–23:3018+RM2,5950.26%RM144Forced close — true night P&L
W24-C No H421:00–23:3025+RM3,1750.35%RM127More trades, lower quality
Verdict — Night Session NOT Added to Portfolio
Per-trade quality is 4× lower (RM144 vs RM567) and daily income is 8× lower (RM11.5/day vs RM94.56/day). Night session confirms the Session-Timeframe Law: PM session is uniquely productive because 4+ hours of AM trend are confirmed, H4 direction is established, and institutional activity is at its daily peak. After Bursa Malaysia closes, FCPO is low-volume and structurally choppy — EMA34 pullbacks do not represent genuine dynamic support at night.
W24-B — Night Session Pine Script (forced close, for reference only — NOT production)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W24-B — Night Session + Forced Close 23:30 MYT (W21-O Conditions)", shorttitle="W24-B",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

fixedTP = input.int(50, "Fixed TP (points)")
fixedSL = input.int(20, "Fixed SL (points)")

ema34 = ta.ema(close, 34)
[plusDI, minusDI, _adx] = ta.dmi(14, 14)
diSpread        = math.abs(plusDI - minusDI)
spreadExpanding = diSpread > diSpread[2]

[m15Plus, m15Minus, _m15adx] = request.security(syminfo.tickerid, "15", ta.dmi(14,14), gaps=barmerge.gaps_off)
m15ema34   = request.security(syminfo.tickerid, "15", ta.ema(close, 34),    gaps=barmerge.gaps_off)
m15ema34_3 = request.security(syminfo.tickerid, "15", ta.ema(close, 34)[3], gaps=barmerge.gaps_off)
h4ema34   = request.security(syminfo.tickerid, "240", ta.ema(close, 34),    gaps=barmerge.gaps_off)
h4ema34_5 = request.security(syminfo.tickerid, "240", ta.ema(close, 34)[5], gaps=barmerge.gaps_off)
ema200d = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)

inSession    = not na(time("5", "2100-2330:23456"))
isSessionEnd = not na(time("5", "2325-2335:23456"))

ema34Rising  = ema34    > ema34[3]
ema34Falling = ema34    < ema34[3]
m15Rising    = m15ema34 > m15ema34_3
m15Falling   = m15ema34 < m15ema34_3
h4Rising     = h4ema34  > h4ema34_5
h4Falling    = h4ema34  < h4ema34_5

if isSessionEnd and strategy.position_size != 0
    strategy.close_all()

longSig  = low  <= ema34 and close > ema34 and ema34Rising  and m15Rising  and h4Rising
         and spreadExpanding and plusDI  > minusDI and m15Plus  > m15Minus
         and close > ema200d and inSession and strategy.position_size == 0
shortSig = high >= ema34 and close < ema34 and ema34Falling and m15Falling and h4Falling
         and spreadExpanding and minusDI > plusDI  and m15Minus > m15Plus
         and close < ema200d and inSession and strategy.position_size == 0

if longSig
    strategy.entry("L", strategy.long)
    strategy.exit("LX", "L", stop=close - fixedSL, limit=close + fixedTP)
if shortSig
    strategy.entry("S", strategy.short)
    strategy.exit("SX", "S", stop=close + fixedSL, limit=close - fixedTP)
W24 Key Learnings
Night session has positive edge but 8× weaker than PM
W24-B (forced close): 18T, +RM2,595, 0.26% DD → RM11.5/day. W21-O PM: 21T, +RM11,915, 0.32% DD → RM94.56/day. Same-period comparison shows night generates only 12% of PM daily income at similar trade frequency. Per-trade: RM144 night vs RM567 PM (4× gap). Not worth adding to portfolio.
Night positions MUST be force-closed at 23:30 — overnight holds contaminate results
W24-A (no forced close): 18T, +RM3,970, 0.56% DD. Multiple trades exited next day at 10:30 or 16:00 MYT. Overnight holds boosted reported P&L by RM1,375 (+53%) while inflating DD to 0.56%. W24-B (forced close): true night-session P&L is +RM2,595 at 0.26% DD. Any night session testing must include session close logic.
H4 slope[5] adds marginal quality to night session but not enough
W24-C (no H4 slope): 25T, +RM3,175, 0.35% DD → RM14.1/day. Removing H4 slope adds 7 trades and RM580 income but drops per-trade quality (RM127 vs RM144) and raises DD. The quality gain from H4 slope exists (same pattern as PM), but neither version approaches PM income levels.
Session-Timeframe Law extended: night session confirms PM is the only productive window
AM session destroys EMA pullback edge (confirmed W18). Night session gives weak positive edge (~RM14/day max). PM session (14:30–18:00 MYT) is uniquely productive at +RM94.56/day. Pattern: by PM, 4+ hours of AM trend is confirmed, H4 direction is established, institutional activity is at its daily peak. Night session lacks this trend maturity — FCPO is low-volume, mean-reverting, and structurally different after Bursa Malaysia closes.
Hypothesis: adding a daily EMA34 slope[3] condition removes low-quality trades during flat daily regimes. Result: removed 1 winner, 0 losers — a net-negative filter. W21-O ceiling reconfirmed for the 4th time.
VariantFilter AddedTradesWR%PFNet PnLRM/dayNote
W25-BASELINEW21-O exact (reference)2166.7%3.51+RM11,915+RM94.56← W21-O true ceiling
W25-AD1 EMA34 > EMA34[3]2065%3.27+RM10,750+RM85.32−1 winner, 0 losers removed
D1 EMA34 Slope — Wrong Filter Mechanism
The filter removed 1 winner (a trade taken during a 3-day daily EMA34 consolidation while price was still above D1 EMA200) and zero losers. A filter that selectively removes winners is structurally harmful. The existing D1 EMA200 bias gate is the correct daily regime filter — it works at the structural level (multi-month bull vs. bear). D1 EMA34 slope operates at the 3-day micro level, overlapping with regime states already captured by M5+M15+H4 triple slope. W21-O is confirmed at ceiling for a 4th independent wave.
W25 Key Learnings
W21-O actual PF is 3.51 — far higher than the ~2.20 W20-D reference
Direct re-run of W21-O on the same chart/period as W25 revealed PF 3.51 (14W, 7L, gross profit RM16,661, gross loss RM4,746). The "PF ~2.20" figure in the W25 hypothesis referenced W20-D, the pre-W21 system. W21's triple-slope architecture already delivers excellence-tier PF without any additional daily filter.
D1 EMA34 slope[3] removes winners not losers — wrong filter mechanism
W25-A vs W21-O: gross loss RM4,736 vs RM4,746 (−RM10 difference, effectively zero). Gross profit RM15,486 vs RM16,661 (−RM1,175). The D1 EMA34 slope[3] filter had zero selective effect on losing trades. It purely removed a winning trade that occurred during a brief 3-day D1 EMA34 consolidation while the daily trend remained intact (D1 price still above EMA200). A filter that removes winners without removing losers is net-negative.
D1 EMA200 is the correct daily regime filter — D1 EMA34 slope is too granular
D1 EMA200 operates at the structural trend level: it separates multi-month bull from bear regimes. D1 EMA34 slope[3] operates at the 3-day micro level: it fires during normal daily pauses within bull regimes. For a system that already requires M5+M15+H4 triple slope alignment, the regime is already confirmed from the intraday and swing-trading perspective. Adding a 3-day daily EMA slope creates a redundant and inferior filter that catches valid setups at temporary daily consolidation lows.
W21-O 8-condition architecture is confirmed at ceiling for daily-filter parameter space
W22 validated W21-O parametrically (slope lookbacks, session times, DI alternatives). W23 validated EMA level. W24 validated night session. W25 validated daily slope filter. The W21-O system has now been tested across 4 independent research waves covering all obvious improvement axes. No tested addition or modification improves the core PF 3.51 / RM94.56/day / 0.33% DD profile. The production system is robustly confirmed.
Hypothesis: FCPO gaps ≥ 30 pts driven by overnight Dalian price moves continue directionally in AM session (10:30–12:15). Result: Gaps fill 69% of the time. PF 0.362, WR 31%, DD 9.67%. Catastrophic failure.
Trades
277
Win Rate
31.1%
Profit Factor
0.362
Net P&L
−RM48,370
Max DD
9.67%
Why W26 Failed — FCPO Gaps Mean-Revert
A 31% WR with TP=50/SL=20 (RR 2.5×) puts breakeven at 28.6% — we are only 2.4pp above breakeven while paying commission and slippage on every trade. The fundamental problem: Dalian correlation triggers the gap, but local FCPO supply/demand dynamics absorb it within the first M15 bar. No parameter variant (larger gap filter, different TP/SL, tighter session) can fix a 31% WR structural mean-reversion profile. The reverse hypothesis (gap fill trade) may be the real edge — marked as W26-B candidate.
W26-A — Dalian Gap Continuation (reference only — do not trade)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W26-A — Dalian Gap Continuation AM (M15)", shorttitle="W26-A",
  overlay=true, initial_capital=500000,
  default_qty_type=strategy.fixed, default_qty_value=1,
  commission_type=strategy.commission.cash_per_contract, commission_value=30,
  slippage=1, pyramiding=0, process_orders_on_close=true)

gapMin  = input.int(30, "Min Gap Size (pts)", minval=10, maxval=100, group="Gap")
fixedTP = input.int(50, "Fixed TP (pts)",     minval=20, maxval=200, group="Exits")
fixedSL = input.int(20, "Fixed SL (pts)",     minval=10, maxval=50,  group="Exits")

ema200d      = request.security(syminfo.tickerid, "D", ta.ema(close, 200), gaps=barmerge.gaps_off)
prevDayClose = request.security(syminfo.tickerid, "D", close[1],           gaps=barmerge.gaps_off)

// Pine v6: time() first arg must be timeframe, second is session
inAM      = not na(time(timeframe.period, "1030-1215:23456"))
firstBar  = inAM and not inAM[1]
secondBar = inAM and inAM[1] and not inAM[2]

var float prevC   = na
var bool  gapUp   = false
var bool  gapDown = false
var bool  taken   = false

if firstBar
    prevC   := prevDayClose
    gapUp   := (open - prevDayClose) >= gapMin
    gapDown := (prevDayClose - open) >= gapMin
    taken   := false

upSurvived   = gapUp   and (low[1]  > prevC)
downSurvived = gapDown and (high[1] < prevC)

longSig  = secondBar and upSurvived   and close > ema200d and strategy.position_size == 0 and not taken
shortSig = secondBar and downSurvived and close < ema200d and strategy.position_size == 0 and not taken

if longSig
    strategy.entry("GL", strategy.long)
    strategy.exit("GLX", "GL", stop=close - fixedSL, limit=close + fixedTP)
    taken := true
if shortSig
    strategy.entry("GS", strategy.short)
    strategy.exit("GSX", "GS", stop=close + fixedSL, limit=close - fixedTP)
    taken := true

if strategy.position_size != 0 and not inAM and inAM[1]
    strategy.close_all(comment="AM end")
W26 Key Learnings
FCPO gaps fill — not continue — 69% of the time in the AM session
W26-A WR of 31.05% means the gap reversed against the entry direction on 191 of 277 attempts. The "~75% continuation probability" hypothesis was incorrect. FCPO opens are heavily mean-reverting in the first 15 minutes: Dalian correlation triggers a gap, but local palm oil supply/demand dynamics absorb it within the first M15 bar.
PF 0.36 is structurally unrecoverable — no parameter variant can fix it
With WR 31% and RR 2.5 (TP 50 / SL 20), the breakeven WR is 28.6%. We are only 2.4pp above breakeven yet losing heavily due to commission and slippage drag. Increasing gap size, changing TP/SL, or adding filters cannot fix a 31% WR structural problem — it would only reduce trade count further without improving direction accuracy.
Gap fill may be the real edge — reverse hypothesis worth testing as W26-B
If gaps fill 69% of the time, a fade strategy (short on gap-up, long on gap-down, TP = prevDayClose) could have positive expected value. With WR ~69% and a TP equal to the gap size (~30 pts) vs SL = half the gap (~15 pts), the math could work. This is a valid separate hypothesis but a different research item.
Pine v6 session format: time() requires timeframe as first argument
Using time("1030-1215:23456") causes a runtime error in Pine v6 — it tries to parse the session string as a timeframe/resolution. Correct form: time(timeframe.period, "1030-1215:23456"). All future AM/PM session filters must use the two-argument form.
Hypothesis: H1 structural demand zones (pivot lows confirmed by 4 neighbours + impulse ≥25 pts) act as support in PM session. Result: All 6 TP/SL/touch combos returned PF < 1. Best PF was 0.842. Hypothesis rejected.
VariantTPSLTouchTradesWR%PFNet PnLVerdict
W27-K50151516250.842−RM1,124Best of 6 — still failed
W27 range30–1008–1510–2512–1924–310.37–0.84all negAll variants negative
Why W27 Failed
H1 pivot zones identify structurally meaningful levels, but price touching a prior pivot low in PM session is more often a breakdown signal than a bounce. WR of 24–31% across all combos is below the breakeven needed for any TP/SL ratio tested. The zone pullback setup requires a mean-reversion context that does not reliably exist in a momentum-driven 2.5-hour window.
W27 Key Learnings
H1 pivot zones fail as PM session support — W27 hypothesis rejected
All 6 TP/SL/touch combinations gave PF < 1. The best was PF 0.842 with WR 25%. Structural H1 pivot zones identify meaningful price levels, but during the FCPO PM session, price touching a prior pivot low is often continuing lower (breakdown), not bouncing. The zone pullback setup requires a reversal context that does not reliably exist in a momentum-driven 2.5-hour window.
Pine v6: initial_capital must match commission scale
strategy.commission.cash_per_contract with commission_value=8 silently multiplies by contract size (25 MT for FCPO), making each round-trip cost ~200 MYR. With initial_capital=10000, the strategy exhausts capital immediately and executes 0 trades. Always use initial_capital=100000+ for FCPO strategies with per-contract commissions.
Pine v6: strategy.exit must fire on every bar in position, not just on open bar
Placing strategy.exit() inside an if strategy.position_size > 0 and strategy.position_size[1] == 0 block means it only fires on the bar a position opens. TradingView discards the exit order after one bar if not reaffirmed. Correct pattern: if strategy.position_size > 0 (no [1] check) so exit is reaffirmed every bar.
Hypothesis: Inverting all W21-O conditions (slopes down, DI bearish, close < D1 EMA200) creates a valid PM session short edge. Result: PF 2.524, 19 trades over 30 months. Short edge confirmed. W21-O + W28-A = regime-adaptive bidirectional pair.
W28-A — Best VariantSHORTCONFIRMED
Trades
19
Win Rate
42.1%
Profit Factor
2.524
Net PnL
+RM4,421
Daily Avg
+RM5/day
T/day
0.02
Period
30 months
Timeframe
M15
Conditions: M15 EMA34 high-touch (high≥ema34, close<ema34) + M15 slope[3] down + H4 EMA34 slope[5] down + M5+M15 DI bearish + close < D1 EMA200 + PM 14:30–18:00 MYT. TP=100, SL=10. PM End is the primary exit.
W28-B Parameter Sweep (TP=100, combined L+S on M15)
SLTradesWR%PFNet PnLNote
82231.8%1.988+RM3,548Whipsawed — too tight
102240.9%2.464+RM5,098Standalone W28-A optimal
152250%2.476+RM5,498← Best combined
202245.5%1.856+RM4,123SL too wide
Regime-Adaptive Pair: W21-O + W28-A
▲ W21-O (Long)
Fires when close > D1 EMA200
All EMA34 slopes up
DI bullish on M5 + M15
▼ W28-A (Short)
Fires when close < D1 EMA200
All EMA34 slopes down
DI bearish on M5 + M15
Zero overlap — the D1 EMA200 regime filter ensures only one system is active at a time. The pair adapts to market regime automatically.
W28-A — Production Short Script (M15 chart, MYX:FCPO1!)Copy → TradingView Pine Editor → Add to chart
//@version=6
strategy("W28-A — FCPO Short PM [LIVE]", overlay=true,
         initial_capital=100000, default_qty_type=strategy.fixed, default_qty_value=1,
         commission_type=strategy.commission.cash_per_contract, commission_value=8,
         calc_on_every_tick=false)

tpPts   = input.int(100, "TP (pts)", minval=10, step=5, group="Exit")
slPts   = input.int(10,  "SL (pts)", minval=5,  step=5, group="Exit")
showSig = input.bool(true, "Show signals", group="Display")

ema34_m5  = ta.ema(close, 34)
ema34_m15 = request.security(syminfo.tickerid, "15",  ta.ema(close, 34), lookahead=barmerge.lookahead_off)
ema34_h4  = request.security(syminfo.tickerid, "240", ta.ema(close, 34), lookahead=barmerge.lookahead_off)
ema200_d1 = request.security(syminfo.tickerid, "D",   ta.ema(close, 200), lookahead=barmerge.lookahead_off)

[diPlus, diMinus, _adx]      = ta.dmi(14, 14)
[m15Plus, m15Minus, _m15adx] = request.security(syminfo.tickerid, "15", ta.dmi(14, 14), lookahead=barmerge.lookahead_off)

m5Touch      = high >= ema34_m5 and close < ema34_m5
m5SlopeDown  = ema34_m5  < ema34_m5[3]
m15SlopeDown = ema34_m15 < ema34_m15[3]
h4SlopeDown  = ema34_h4  < ema34_h4[5]
diSpreadS    = diMinus - diPlus
spreadExp    = diSpreadS > diSpreadS[2]
m5DiBear     = diMinus  > diPlus
m15DiBear    = m15Minus > m15Plus
regimeBear   = close    < ema200_d1
inPM         = not na(time(timeframe.period, "1430-1800:23456"))

canShort = m5Touch and m5SlopeDown and m15SlopeDown and h4SlopeDown and
           spreadExp and m5DiBear and m15DiBear and regimeBear and
           inPM and strategy.position_size == 0

if canShort
    strategy.entry("S", strategy.short, alert_message="W28A SHORT entry @ " + str.tostring(close))

if strategy.position_size < 0
    strategy.exit("XS", "S",
      limit = strategy.position_avg_price - tpPts,
      stop  = strategy.position_avg_price + slPts,
      alert_profit = "W28A TP hit",
      alert_loss   = "W28A SL hit")

if not inPM and inPM[1]
    strategy.close_all(comment="PM End", alert_message = "W28A PM End close @ " + str.tostring(close))

plot(ema34_m5, "EMA34", color=color.new(color.orange, 0), linewidth=2)

if showSig and canShort
    label.new(bar_index, high + 5, "▼ W28-A",
      style=label.style_label_down, color=color.new(color.red, 20),
      textcolor=color.white, size=size.small)

var t=0, var w=0, var l=0, var net=0.0, var peak=0.0, var dd=0.0
if strategy.closedtrades > t
    t   := strategy.closedtrades
    pnl  = strategy.closedtrades.profit(t-1)
    net += pnl
    if pnl > 0
        w += 1
    else
        l += 1
    if net > peak
        peak := net
    curDD = peak - net
    if curDD > dd
        dd := curDD

if barstate.islast and t > 0
    wr   = math.round(w / t * 100 * 10) / 10
    gw   = 0.0
    gl   = 0.0
    for i = 0 to t - 1
        p = strategy.closedtrades.profit(i)
        if p > 0
            gw += p
        else
            gl += math.abs(p)
    pf   = gl > 0 ? math.round(gw / gl * 1000) / 1000 : 999.0
    days = (last_bar_time - strategy.closedtrades.entry_time(0)) / 86400000
    lbl  = "W28-A SHORT  T:" + str.tostring(t) +
           " W:" + str.tostring(w) + " L:" + str.tostring(l) +
           " WR:" + str.tostring(wr) + "%" +
           " PF:" + str.tostring(pf) +
           " NET:" + str.tostring(math.round(net)) +
           " D/day:" + str.tostring(math.round(net / days * 10) / 10)
    label.new(bar_index, high + 10, lbl,
      style=label.style_label_left, size=size.small,
      color=color.new(color.red, 85), textcolor=color.white)
W28 Key Learnings
Short-side mirror of W21-O is a real edge — PF 2.524 over 30 months
The same architectural logic that makes W21-O work on the long side (slope alignment + DI direction + regime filter) works in mirror form for shorts. Close below D1 EMA200 = bear regime. EMA34 slope all down = trend intact. DI bearish = momentum aligned. PM session = best execution window. 19 trades, PF 2.524. W21-O + W28-A = a complete regime-adaptive system.
H4 slope[5] is the quality gate for both long and short systems
W29-B2 confirmed: removing H4 slope from W28-A increases trade count from 19 to 48, but PF collapses from 2.524 to 1.094. The 29 added trades are noise. H4 slope[5] (20-hour trend confirmation) is the single most critical filter in both W21-O and W28-A — it cannot be relaxed without destroying the edge.
SL=10 is optimal for standalone W28-A; SL=15 optimal for W28-B combined
W28-A standalone: SL=10 gives PF 2.524 vs SL=15 giving PF 2.356. But for W28-B combined (long+short), SL=15 improves WR to 50% and NET to +5498 because the wider stop lets regime trades breathe before PM End exit dominates. The optimal SL depends on whether you run the strategy standalone or combined.
PM End is the primary exit at TP=100 — smaller TP cuts profits prematurely
At TP=50 and TP=75, NET drops significantly vs TP=100. The edge in W28-A comes from holding through the PM session and letting the trend carry. A TP of 100 is rarely hit outright — PM End closes most winning trades at whatever the market price is, which tends to be positive when trend conditions aligned at entry.
Session-Timeframe Law holds for shorts: PM >> AM
W29-C tested AM session (10:30–12:30 MYT) shorts with identical W28-A conditions: T:17, PF:1.281, DAVG:+1/day vs PM session PF:2.524, DAVG:+5/day. AM shorts are 4× weaker. The PM session provides the structural edge for both long and short EMA34 slope strategies. This confirms Session-Timeframe Law applies bidirectionally.
Three research directions: (A) W28-B on M5 chart, (B) relax W28-A conditions to increase trade frequency, (C) test AM session shorts. Conclusion: frequency ceiling is structural — H4 slope is the quality gate. AM shorts too weak. M5 data insufficient on TradingView.
VariantChangeTradesPFDAVGVerdict
W28-A (base)All conditions, PM session192.524+5/day← Baseline
W29-ACombined L+S on M533.818+3/dayInconclusive (M5 data = 9mo only)
W29-B1Drop M15 DI bear192.356+4/dayNo change — M15 DI already satisfied
W29-B2Drop H4 slope481.094+1/day✗ H4 slope is the quality gate
W29-B3Drop D1 EMA200202.242+4/dayAdds 1 loser — filter earns keep
W29-CAM session 10:30–12:30171.281+1/day4× weaker — Session Law confirmed
W29 Conclusion — Quality Ceiling Confirmed
The W28-A strategy fires ~19–22 times per 30 months by design. H4 slope[5] is load-bearing — removing it triples trade count but PF collapses from 2.52 → 1.09. AM shorts are positive but 4× weaker (Session-Timeframe Law confirmed for shorts). TradingView M5 data only covers 9 months — a proper combined test requires the IBKR M1 data pipeline (available May 2026). The system is ready for paper trading as-is.
W29 Key Learnings
Frequency ceiling is structural — H4 slope gates all genuine setups
W28-A produces ~19 short trades per 30 months on M15. Three relaxation tests showed: removing M15 DI = 0 new trades (already satisfied); removing H4 slope = +29 trades but PF 1.094 (noise); removing D1 EMA200 = +1 trade which is a loser. There is no way to increase frequency without destroying the edge. This is a quality-over-quantity system by design.
Session-Timeframe Law extends to shorts: PM session is the only viable window
W29-C: AM shorts give PF 1.281, DAVG +1/day vs PM shorts PF 2.524, DAVG +5/day. This extends the W18 finding (AM loses money for longs) to the short side. The PM session (14:30–18:00 MYT) is the structural edge window for FCPO EMA34 slope strategies regardless of direction.
TradingView M5 data limit: only ~9 months vs M15 30 months
W29-A (combined L+S on M5) produced T:3 because TradingView M5 data for MYX:FCPO1! only goes back to ~May 2025 (9 months), vs M15 going back to Aug 2023 (30 months). For proper M5 combined testing, use the fcpo_data.json pipeline (M1 data from Stooq) or wait for IBKR data access (cooldown ends ~2026-05-27).
Hypothesis: FCPO gaps open in the direction of Dalian overnight move, but often fade back. Tested 3 variants of fade strategy. All fail: WR ~40%, PF 0.57–0.61. The W26 “69% gap fill” stat was a measurement artifact — not fading 50 pts ≠ reversing to prev close.
FAILED — Both gap directions tested, all variants PF < 1
W30-A: PF 0.614  |  W30-B: PF 0.605  |  W30-C: PF 0.571  |  WR ~40% across the board
VariantGap FilterTP TargetTradesWR%PFNET (MYR)Verdict
W30-A≥30 ptsFixed +5047140.3%0.614-54,785FAIL
W30-B≥30 ptsPrev close (full fill)47140.5%0.605-55,785FAIL
W30-C≥50 ptsPrev close (full fill)33140.2%0.571-44,785FAIL
W30 Conclusion — Gap Strategies Dead on FCPO AM Session
Root cause: “Gap doesn’t continue 50 pts” ≠ “Gap fades.” W26 showed 69% of Dalian gaps ≥30 pts do not continue 50 pts past open — misread as “69% fill.” In reality, many partially fill (10–20 pts) then reverse back, expiring at AM end as losses. A 40% WR across all variants means only 2-in-5 fades complete — not a parameter problem, it’s structural. Larger gaps (≥50) are worse — driven by fundamentals that continue, not revert. W30 is closed. Both gap directions now tested and confirmed as non-edges: W26 (continuation, PF 0.362) + W30 (fade, PF 0.57–0.61).
W30 Key Learnings
Dalian gap fade has ~40% WR across all variants — structural loser
Three variants tested: TP=50 fixed, TP=full fill at gap≥30, and TP=full fill at gap≥50. All produce WR ~40% and PF 0.57–0.61. This is not a parameter problem — 40% WR is a structural property of the gap-fade strategy on FCPO. The 1:10 SL/TP ratio is not saving it.
"Gap doesn't continue" ≠ "Gap fades"
The W26 backtest showed 69% of Dalian gaps ≥30 pts do not continue 50 pts. This was misread as "69% fill". In reality: the gap not continuing 50 pts includes (a) partial fill then reversal, (b) consolidation at gap level, (c) slow continuation that exceeds SL before filling. A 40% WR confirms the edge was a measurement artifact, not a tradable signal.
Larger gaps are structural, not mean-reverting
W30-C (gap≥50) is worse than W30-B (gap≥30): PF 0.571 vs 0.605. Large Dalian gaps are often driven by overnight fundamental news (weather, crop data, China demand). These gaps tend to continue, not fade. The fade hypothesis is backwards for large gaps.
W26 gap continuation was also wrong — both directions fail
W26 tested gap continuation (PF 0.362, WR 31%). W30 tested gap fade (PF 0.57–0.61, WR 40%). Both directions of the Dalian gap trade fail on FCPO AM session. The Dalian gap itself is not a reliable directional signal for FCPO in the 09:00–12:30 window.
Hypothesis: W21-O’s quality filters (triple slope + DI) might isolate viable AM setups that W18’s simpler system missed. Tested 3 levels from strictest to loosest. All fail. AM session has no long edge at any condition level.
VariantConditionsTradesWR%PFNET (MYR)D/dayVerdict
W31-AFull W21-O stack + H4 slope20%0-782-1/dayFAIL
W31-BM15 slope + DI (no H4)933.3%~0.6-1,919-3/dayFAIL
W31-CBare: touch + EMA200 only1414.3%0.179-3,074-3/dayFAIL
W31 Conclusion — AM Session is a Structural Dead Zone
Tested from strictest (full W21-O stack, 2 trades) to loosest (touch + EMA200, 14 trades). All variants fail. Adding filters improves WR but kills frequency — there is no viable operating point. Removing filters increases trades but PF collapses to 0.18. Session-Timeframe Law now confirmed at depth: PM session is the only viable window for the EMA34 pullback system on FCPO, for both long and short. H4 slope is almost never satisfied at AM open because Dalian overnight creates mixed/flat H4 momentum. W31 is closed. The research path is exhausted for AM session longs.
W31 Key Learnings
AM session is a structural dead zone for EMA34 pullback longs — confirmed at all condition levels
Tested 3 variants from strictest (W21-O full stack, 2 trades) to loosest (bare touch+regime, 14 trades). All fail. PF ranges from 0 to 0.18. Adding quality filters reduces noise but kills frequency; removing them increases trades but PF collapses. There is no viable operating point for AM long setups on FCPO M15.
Session-Timeframe Law now confirmed for longs at depth: PM >> AM regardless of condition stack
W18 showed AM EMA21 PB loses money. W31 confirms the same holds for the much stricter EMA34 triple-slope system. The PM session edge is not a coincidence of one parameter set — it is a structural property of how FCPO trends. AM session (09:00–12:30 MYT) lacks the sustained directional momentum that the EMA34 slope system requires.
H4 slope almost never satisfied during AM session
W31-A (full conditions including H4 slope[5]) produced only 2 trades in 30 months. The H4 slope requirement captures 20-hour directional momentum — by AM open, H4 slope is almost always flat or mixed from the overnight Dalian session, making the condition rarely satisfied. PM session benefits from a full trading day of directional accumulation before the 14:30 open.
Three parallel directions: (A) apply EMA34 system to FKLI, (B) test ADX strength filter on W28-A shorts, (C) TP parameter sweep to confirm optimal exit. Key finding: TP=100 confirmed optimal. ADX filter is noise at N=16. FKLI signal exists but is not practically tradeable.
W32-C — TP Sweep on W28-A (SL=10 fixed)
TPTradesWR%PFNET (MYR)D/dayNote
50 pts1844.4%2.047+2,812+2.8/dayIncome -36%
75 pts1844.4%2.429+3,837+3.8/dayIncome -13%
100 pts1942.1%2.524+4,421+4.4/day← Optimal
150 pts1942.1%2.533+4,446+4.5/dayPM clips runners
200 pts1942.1%2.533+4,446+4.5/daySame as TP=150
W32-B — ADX Strength Filter on W28-A
ADX MinTradesWR%PFNETD/dayVerdict
≥0 (base)1942.1%2.524+4,421+4.4/day← Baseline
≥151637.5%2.702+4,569+4.6/day+148 MYR over 30mo — noise
≥201040.0%2.498+2,690+2.7/dayHalves frequency, no PF gain
≥25520.0%0.365-580-0.6/dayDestroys edge
W32-A — FKLI Expansion (24 months, best TP=5 pts)
Trades
22
WR%
59.1%
NET
+610 MYR
D/day
+0.8 MYR
vs FCPO
100× weaker
Data
24 months
The EMA34 pullback signal does transfer to FKLI (WR 59.1% is genuinely positive). However, optimal TP=5 pts (RM250 gross) is within the typical FKLI bid/ask spread of 2–3 pts — spread kills the edge in practice. D/day ~+0.8 MYR/contract vs FCPO +94 MYR. Not worth pursuing.
W32 Conclusion — W28-A Already Optimised; Signal Transfers But Doesn’t Scale
All three directions confirm the same thing: the existing W28-A parameterization (TP=100, SL=10) is already at its optimum.ADX≥15 is marginal noise (N=16 sample). TP=100 is capped by PM session duration. FKLI has the right signal shape (59% WR) but the required TP is below the spread threshold. No changes needed to the production strategy — W32 closes without modifications.
W32 Key Learnings
TP=100 is confirmed optimal for W28-A — PM session is the hard ceiling
TP=150 and TP=200 produce identical results (NET +4,446, same 19 trades). The PM session (14:30–18:00 MYT) ends before short runners can travel beyond 100 pts. TP=100 captures available move; raising it further just means PM End closes the trade anyway at the same profit. Below TP=100, income falls sharply.
ADX filter at ≥15 marginally improves PF but is not actionable at N=16
ADX≥15 raises PF from 2.524 → 2.702 by removing 3 net-negative trades. Sounds positive, but: (a) the improvement is +148 MYR over 30 months, (b) the remaining sample is only 16 trades, (c) three removed trades could easily swing back positive in the next 30 months. Adding a parameter for a 16-trade-sample improvement is curve fitting, not discovery.
EMA34 pullback signal transfers to FKLI but is not practically tradeable
FKLI (KLCI Futures) produces 22 trades over 24 months with WR 59.1% — the signal quality is genuinely positive. However, the optimal TP is 5 pts (RM250 gross per win), which is within the typical FKLI bid/ask spread of 2-3 pts. After spread and slippage, the edge disappears. D/day ~+1 MYR/contract vs FCPO +94 MYR. FKLI is not worth pursuing unless traded in 50-100 contract size.
Hypothesis: Can D1 EMA200 be replaced or removed to unlock more long-side trades? Tested 3 variants: no gate, H4 DI gate, bidirectional H4 DI. Result: D1 EMA200 is irreplaceable. Any substitution collapses long-side quality.
VariantRegime GateDirectionTradesWR%PFNET (MYR)D/dayVerdict
W28-A (base)D1 EMA200 bearShort1942.1%2.524+4,421+4.4/day← Benchmark
W33-ANoneLong1030.0%~0.1+40+0.04/dayWR collapse — gate essential
W33-BH4 DI bullLong933.3%~0.5+431+0.4/dayWeaker than EMA200
W33-CH4 DI bidirLong+Short2944.8%1.829+3,361+3.3/dayLongs drag shorts down
W33 Conclusion — D1 EMA200 is Irreplaceable; H4 DI Cannot Substitute
Removing the D1 EMA200 gate collapses WR to 30% (W33-A). H4 DI substitution gives WR 33% — better than nothing but structurally weak. Bidirectional H4 DI (W33-C) is worse than W28-A short-only — the added long trades are net -1,060 MYR drag. Root cause: the Jul 2023–Apr 2026 window is predominantly bear regime for FCPO, starving M15 long strategies. This is a data period artifact — W21-O on M5 is valid when bull regime exists. D1 EMA200 is a structural anchor operating at a different scale from H4 DI. They are not interchangeable.
W33 Key Learnings
D1 EMA200 is irreplaceable — it is the structural regime anchor for W21-O
W33-A (no regime gate): WR 30%, NET +40 MYR. W33-B (H4 DI gate): WR 33%, NET +431. Neither can substitute the D1 EMA200 which cleanly separates bull and bear structural regimes. H4 DI is a tactical indicator; D1 EMA200 is a structural anchor — they operate at different scales.
Adding longs via H4 DI hurts the portfolio more than it helps
W33-C bidirectional (H4 DI): NET +3,361, D/day +3.3 — worse than W28-A short-only (NET +4,421, D/day +4.4). The 10 added long trades are net -1,060 MYR. The Jul 2023–Apr 2026 data window is predominantly bear regime for FCPO, so any long entries fired by H4 DI are fighting the structural trend.
M15 long strategy is data-period disadvantaged — not a strategy failure
FCPO declined from ~4,800 in early 2023 to ~3,600-4,200 over the test window. This puts the D1 EMA200 gate in bear mode for the majority of the period, starving the long strategy of trades (3 trades with D1 EMA200 vs 10 without). This is a data artifact, not evidence that W21-O long is invalid. W21-O on M5 (tested when bull conditions existed) gives +RM94/day.
Hypothesis: Replace close vs EMA200 with EMA200 slope direction as regime gate. W34-A tested slope-up for longs; W34-B tested slope-down for shorts. Result: EMA200 slope fires near-zero trades on continuous contract data. Position gate is irreplaceable.
VariantGate TypeDirectionTWR%PFNET (MYR)D/dayVerdict
W28-A (base)close < D1 EMA200Short1942.1%2.524+4,421+4.4← Benchmark
W34-AEMA200 slope UPLong10%0-391-0.5Near-zero frequency
W34-BEMA200 slope DOWNShort000Zero trades
W34 Conclusion — EMA200 Position Gate is Irreplaceable
EMA200 slope fires near-zero trades on FCPO1! continuous data due to bear regime + back-adjustment noise. EMA200 position (close above/below the 200-day level) is the correct structural gate — it is robust to back-adjustment and cleanly separates bull and bear regimes. W28-A and W21-O gates are locked.
EMA200 position (close above/below) is the correct gate; slope is not
W34-A: T:1 (slope-up near-never fires in bear regime). W34-B: T:0 (slope-down misfires due to continuous contract back-adjustment shifting EMA200 values). The original W28-A/W21-O gate — close vs EMA200 level — is the correct implementation. Do not revisit EMA200 slope as a gate.
Continuous contract back-adjustment corrupts slope-based EMA signals
Each FCPO contract rollover back-adjusts historical prices. A 200-day EMA computed on back-adjusted data has different direction/level properties than on the original price series. Slope-based conditions on a 200-day EMA are especially vulnerable because small price shifts accumulate over 200 bars. Position-based conditions (close vs EMA level) are more robust to back-adjustment.
Hypothesis: Use horizontal S/R levels (Previous Day High/Low, AM session H/L) with H4 market structure to enter PM session reversals. Tested PDH rejection and AM H/L retest patterns. Result: PDH unreachable from PM session; AM H/L is noise with 10× overtrade frequency.
VariantS/R TypeDirectionTWR%PFNET (MYR)D/dayVerdict
W28-A (base, new data)EMA34 dynamicShort5311.3%1.012+180+0.2← New baseline*
W35-APrev Day HighShort000PDH unreachable from PM
W35-BAM session H/LBoth5219.2%0.827-25,740-25Noise — 10× overtrade
* W28-A re-run on current back-adjusted FCPO1! data. Previous result was T:19, PF:2.524 — see data warning below.
⚠️ Data Currency Warning — All Previous Results Potentially Stale
FCPO1! continuous contract prices are back-adjusted on each contract rollover. Re-testing W28-A on current data gives T:53, PF:1.012 vs the original T:19, PF:2.524. All W17–W34 results were computed on an earlier version of the continuous contract data and may no longer be exactly reproducible. Re-validate on current data before live deployment.
PDH/PDL are structurally incompatible with PM-only strategies
Previous Day High is almost always set during AM session (10:30–12:30). By PM (14:30–18:00), price is typically 50–200 pts below PDH. No retest opportunity exists in PM. Using intraday AM H/L as S/R for same-day PM entries is the correct S/R framing.
AM session H/L acts as noise, not structure, for PM entries
W35-B fired 521 trades vs 53 for the W28-A baseline — nearly every PM session triggered an AM level retest. With WR:9.2% and PF:0.827, the AM high/low proximity adds no predictive value. EMA34 dynamic S/R (W28-A system) selects higher-quality entries than horizontal intraday levels.
⚠️ Data currency warning: FCPO1! back-adjusted since previous sessions
Re-validating W28-A on current FCPO1! data gives T:53, PF:1.012 vs original T:19, PF:2.524. Continuous contract rollovers back-adjust historical prices, changing EMA values and entry conditions. All W17–W34 results in this lab were computed on an earlier version of the data and may no longer be reproducible. Re-validate before live deployment.
Hypothesis: Explicit multi-EMA trend alignment (EMA8/21/34 bear stack) combined with a dedicated S/R level (EMA21, EMA34, SMA20, Bollinger Band) produces higher-quality PM short entries than single-EMA slope. Result: All MA-based S/R variants produce WR ~11–13%, just below the 14.4% break-even threshold.
VariantS/R LevelEntry SignalTWR%PFNET (MYR)D/dayVerdict
W36-AEMA34Any cross5211.5%0.640-8,160-7.9Baseline (W28-A revalidated)
W36-BEMA21Crossover (touch)446.8%0.349-13,520-13.1FAIL — worst WR
W36-C ★EMA21Crossunder (reject)2412.5%0.711-2,970-2.9Best — still losing
W36-DEMA34Any cross + stack3511.4%0.583-6,925-6.7Stack filter hurts
W36-EBB UpperCrossunder + stack250%5.319+1,965+1.9T:2 — invalid sample
W36-GSMA20Crossunder4112.2%0.620-7,430-7.2Same as EMA34
Break-even WR = 14.4% (TP=100pt × 25 MYR/pt − 40 commission vs SL=15pt + 40 commission). No variant clears this threshold.
⚠️ Pine Script Commission Bug — Discovered in W36
commission_value=40 without commission_type=strategy.commission.cash_per_order defaults to 40% per trade (not 40 MYR). This wiped the simulated account in 6 trades. All future strategies must include the commission_type parameter explicitly.
MA-based S/R pullback consistently under-performs break-even
All variants — EMA21, EMA34, SMA20 as S/R levels — produce WR ~11–13%, just below the 14.4% break-even threshold at TP=100/SL=15. This is a structural finding: MA crossovers in a downtrend do not have enough predictive value for profitable short entries at this R:R ratio.
Confirmed rejection beats aggressive touch entry
Waiting for the crossunder (price was above EMA21, now falls back below = confirmed rejection) gives PF:0.71 vs PF:0.35 for crossover (aggressive entry at first touch). Best practice: wait for bar close below the S/R level before entering short.
Triple EMA stack alignment is an over-filter
Adding EMA8<EMA21<EMA34 bear stack as a trend gate HURTS performance — PF drops from 0.64 to 0.58 (W36-A → W36-D). The stack condition removes winning trades disproportionately. EMA slope on a single level remains superior to multi-EMA alignment gates.
⚠️ Pine Script commission bug: always set commission_type explicitly
commission_value=40 without commission_type=strategy.commission.cash_per_order defaults to strategy.commission.percent — meaning 40% per trade, not 40 MYR. This destroys any backtest (account wiped in 6 trades). All future Pine strategies must include commission_type=strategy.commission.cash_per_order.
⚠️ W28-A short edge confirmed degraded on current data
W28-A revalidated at T:52, PF:0.640 with proper commission (40 MYR/trade). The W35 re-test of T:53, PF:1.012 may have used zero or different commission. Either way, the PM short edge is at or below break-even on back-adjusted FCPO1! data.
Confirmed TP=100/SL=15 universally optimal for W54-B. Gap[3] + early break are equivalent conditions (same T:9 trades). Best full PM stack: gap[3] + peak>85 (T:14, PF:3.126).
VariantFilterTPFNET MYR
W57-BFull PM + Gap[3] + Peak>85143.126+8,705
W57-CW54-B SL=10103.468+5,700
W57-DW54-B SL=20106.614+13,025
TP=100, SL=15 universally optimal — confirmed for W54-B
SL sweep on Mon+Fri + gap[3] system: SL=10 PF:3.468, SL=15 PF:8.431, SL=20 PF:6.614. TP=125 PF:6.692 (drops WR: one winner never reached 125). TP=100/SL=15 is the system-wide optimal confirmed across W32, W39, W40, and now W54/W57.
Gap[3] + early break ≤3 bars are mathematically equivalent filters
W57-A: stacking gap widening[3] + barsSince(EMA34 break)≤3 gives identical T:9, PF:4.563 as either filter alone. When the signal fires within 3 M15 bars of the EMA34 crossover, the EMA gap is always widening over 3 bars at that moment — the two conditions capture the same structural moment.
Structural law: early EMA break signals > prolonged overshoot. barsSince(EMA34 break)≤3 gives T:9, PF:4.563. Monotonic: tighter = higher quality. Gap widening[3] and early break ≤3 are equivalent conditions.
VariantFilterTPFNET MYR
W56-A2+ Bars Above EMA (baseline)242.297+10,030
W56-D ★Early Break ≤3 Bars Full PM94.563+8,105
W56-GEarly Break ≤5 Bars Full PM103.802+7,650
Structural law: early EMA break signals > prolonged overshoot signals
barsSince sweep — ≤2: PF:5.832 (T:6), ≤3: PF:4.563 (T:9), ≤5: PF:3.802 (T:10), all bars: PF:2.297 (T:24). Monotonic: the fresher the EMA break, the higher the rejection quality. Institutional sellers are waiting at the EMA zone; the earliest rejection is the strongest.
3+ bars above EMA removes winners (W56-B: PF:1.679)
Requiring 3 consecutive bars above EMA34 before Stoch crossunder gives T:21, PF:1.679 — worse than baseline. The subset that fires after 3+ bars is the bottom third of signal quality. Signals should be filtered TO early, not FROM early.
H4 EMA bearish order weakens full PM. Stoch %D crossunder inferior to %K (lag reduces quality). %K crossunder remains the optimal signal line.
VariantFilterTPFNET MYR
W55-AH4 EMA21 < H4 EMA34 Full PM222.108+8,065
W55-DStoch %D Crossunder 8081.652+1,910
Stoch %K crossunder is superior to %D crossunder — lag reduces quality
W55-D: %D xunder 80 gives T:8, PF:1.652. The 3-period smoothing of %D introduces lag, causing entries after the initial rejection momentum is already established. %K fires at the exact turning point; %D fires after it is confirmed — too late for optimal entry.
H4 EMA order (EMA21<EMA34) is a weaker gate than H4 slope
W55-A: PF:2.108 vs W39-F PF:2.297. A mature bearish cross at H4 (EMA21 already below EMA34) selects a period when the trend is in a later phase — more mean-reversion risk. The slope gate (EMA21 currently declining) is more precise: it requires active momentum, not just a historical cross.
When M15 EMA21 pulls further from EMA34 (gap widening over 3 bars), the rally is intensifying before rejection. Mon+Fri + gap[3] = PF:8.431 (T:10). Gap[3]+peak>85 = PF:11.407 (T:6). Gap widening and early break ≤3 bars are equivalent conditions.
VariantFilterTWR%PFNET MYRDD
W54-AFull PM + EMA Gap Widening[3]2330.4%2.440+10,4852,415
W54-B ★Mon+Fri + EMA Gap Widening[3]1060.0%8.431+13,5251,175
W54-CMon+Fri + EMA Gap Widening[1]862.5%9.469+11,560770
W54-FMon+Fri + Gap[3] + Peak>85666.7%11.407+9,470720
EMA gap widening: a new structural quality filter — PF:6.745→8.431 on Mon+Fri
When M15 EMA21 is pulling further away from EMA34 (gap > gap[3]), the M15 rally is intensifying, not consolidating. Short into this at Stoch crossunder = entering at the peak of the intraday counter-trend move. gap[3] removes only losers (1 trade), keeping all 6 winners from W40-M. This is the highest-quality filter found for Mon+Fri.
Gap[3] and early break (barsSince≤3) are equivalent conditions
W57-A confirmed: stacking both filters gives identical T:9, PF:4.563 as either alone on full PM. When price crosses EMA34 and signal fires within 3 bars, the EMA21-EMA34 gap is always widening at that moment — the two conditions co-occur systematically.
Gap[2] and gap[5] are ineffective — gap[3] is the optimal lookback
Sweep: gap[1]=T:8 PF:9.469, gap[2]=T:11 PF:6.745 (same as W40-M), gap[3]=T:10 PF:8.431, gap[5]=T:11 PF:6.745. gap[2] and gap[5] don't filter any trades. gap[3] = 45 minutes of EMA separation history — the right window to confirm a genuine intraday EMA divergence.
Prior D1 direction adds no structural value. Both bearish and bullish prior D1 either reduce quality or over-filter. Already captured by D1 EMA200 + H4 slope.
VariantFilterTPFNET MYR
W53-APrior D1 Bearish + Stoch Full PM172.253+6,840
W53-BPrior D1 Bullish + Stoch Full PM72.402+3,190
Prior D1 bar direction adds no structural value
Both bearish and bullish prior D1 either reduce quality (bearish: PF drops, DD worsens) or over-filter (bullish: T:7). The D1 bar direction is already captured implicitly by the D1 EMA200 regime gate + H4 slope. No additional information from the prior D1 candle direction.
VWAP over-filters or selects wrong subset. Above VWAP = stronger rally (risk of continuation). Below VWAP + above EMA = contradictory zone (T:3). VWAP incompatible with this system.
VariantFilterTPFNET MYR
W52-AAbove Daily VWAP + Stoch Full PM211.758+5,520
W52-BBelow Daily VWAP + Stoch Full PM3+4,510
VWAP over-filters or selects worse subset — not compatible with this system
VWAP requires knowledge of intraday volume profile which is separate from the EMA/slope structural framework. Above VWAP (strong rally) = risk of continuation; below VWAP + above EMA (contradictory) = T:3. VWAP adds no structural value to the failed-rally EMA short system.
H1 close < H1 EMA21 gives T:7, PF:4.374. High quality but ~2.5/year. H1 slope and position are equivalent conditions. Useful as secondary confirmation.
VariantFilterTPFNET MYR
W51-AH1 Close < H1 EMA21 + Stoch Full PM74.374+6,140
W51-BH1 Close < H1 EMA34 + Stoch Full PM132.565+6,410
H1 bearish structure improves quality but halves frequency
H1 close < H1 EMA21 gives T:7, PF:4.374 — a genuine quality improvement that captures the MTF bearish confirmation (H4 slope + H1 position + M15 rally). But T:7 over 33 months is too sparse for standalone use. Best used as a secondary confirmation when other quality filters already narrow the set.
H1 slope and H1 close/EMA position are correlated (W51-A = W51-C)
H1 EMA21 slope[2] and H1 close < H1 EMA21 produce identical T:7, PF:4.374 results. When H1 EMA21 is sloping down, H1 close is typically below it. Both conditions capture the same H1 bearish state.
Requiring close > EMA34+5pts filters micro-blip entries. Full PM PF:2.297→2.594 (T:19). ATR*0.3 ≈ 5pts. Hurts Mon+Fri (removes winners). Best stacked: dist+peak gives T:12, PF:2.852.
VariantFilterTPFNET MYR
W50-AEMA34 Distance ≥5pts Full PM192.594+9,430
W50-BEMA34 Distance ≥10pts Full PM161.810+4,420
W50-EFull PM + Dist≥5 + Peak>85122.852+6,740
EMA34 distance ≥5pts: ATR*0.3 ≈ 5pts, filters micro-blip signals
Requiring close > EMA34 + 5pts confirms price is genuinely in the EMA overshoot zone, not just touching the EMA. PF improves from 2.297 to 2.594 (full PM). ATR(14) ≈ 17pts for FCPO M15, so 5pts ≈ ATR*0.3 — a meaningful minimum extension.
Distance filter hurts Mon+Fri (removes winners)
W50-C: Mon+Fri + 5pt distance gives T:10, PF:5.681 — loses 1 winner vs W40-M (T:11, PF:6.745). The Mon+Fri subset includes some legitimate entries with only marginal EMA extension; the fixed distance threshold is too blunt for the already-filtered DoW set.
Structural law confirmed: deeper Stoch %K peak before crossunder = higher rejection quality. Mon+Fri + peak>85 achieves PF:7.604 (T:7). Monotonic: peak>80→PF:2.297, peak>85→PF:2.813, peak>90→PF:5.703 (full PM sweep).
VariantFilterTWR%PFNET MYRDD
W49-AStoch Peak>85 Xunder 80 Full PM1533.3%2.813+8,2501,630
W49-BStoch Peak>90 Xunder 80 Full PM850.0%5.703+8,560845
W49-C ★Mon+Fri + Stoch Peak>85757.1%7.604+9,015820
W49-DMon+Fri + Stoch Peak>903100.0%+7,960390
Structural law: deeper Stoch peak = higher rejection quality
Full PM sweep — peak>80: PF:2.297 (T:24) → peak>85: PF:2.813 (T:15) → peak>90: PF:5.703 (T:8). A monotonic relationship: the higher the %K before the crossunder, the more extreme the overbought condition, and the more reliable the institutional selling into the rally.
Mon+Fri amplifies the peak effect (W49-C: PF:7.604)
Mon+Fri + peak>85 gives PF:7.604 vs Mon+Fri alone (PF:6.745). The weekend catalyst (institutional position management) combines with the extreme overbought signal for maximum quality. T:7 over 33 months is sparse but the two independent structural factors (DoW + peak depth) suggest genuine robustness.
All 11 W40-M trades already had Stoch>80 on prior bar (peak>80 redundant on Mon+Fri)
W48-C confirmed: requiring %K[1]>80 on Mon+Fri gives identical result to W40-M. The sustained overbought is already universal in that sample. Peak>85 starts filtering (T:11→7), removing 4 trades that happen to be losers.
W49-C practical assessment: monitor but do not use as primary system
T:7 over 33 months = ~2.5 trades/year. While PF:7.604 is exceptional, the sample is too small for standalone live trading. Best used as: (1) additional confirmation filter if W40-M signal fires, or (2) track live hits to build the sample before committing.
Tested requiring Stoch %K to have been above 80 for 1–2 prior bars before crossunder. Key finding: all 11 Mon+Fri trades already had prior-bar OB — filter is redundant on DoW subset.
VariantFilterTWR%PFNET MYR
W48-AStoch Xunder + Prior Bar OB Full PM2330.4%2.440+10,485
W48-BMon+Fri + 2-Bar Sustained OB560.0%7.978+6,350
W48-CMon+Fri + 1-Bar Prior OB1154.5%6.745+13,070
Prior-bar OB is universal on Mon+Fri (no filter effect)
W48-C = W40-M exactly. Every one of the 11 Mon+Fri trades had Stoch already above 80 on the bar before the crossunder. The DoW filter selects a subset where the overbought condition was always sustained — there are no "1-bar spike" crossunders on Mon+Fri.
2-bar sustained OB on full PM: PF:2.297→2.44 (+6%)
W48-A removes exactly 1 bad trade vs W39-F. This single trade had a Stoch crossunder from below 80 (spike up then immediately down) — a weaker signal pattern. The improvement is real but modest.
Key discovery: M15 EMA slope gates are mathematically incompatible with close>EMA (self-contradicting). H4 DI bearish alignment redundant with slope gate on Mon+Fri.
VariantFilterTPFNET MYR
W47-CH4 ADX>25 Gate90.837-595
W47-DH4 DI- > DI+ Bearish Alignment232.440+10,485
W47-EMon+Fri + H4 DI- > DI+116.745+13,070
M15 EMA slope gate is mathematically incompatible with close>EMA
W47-A/B (M15 EMA21 slope down + close>EMA21) both give T:0. This is not a data issue — it is a mathematical constraint: if close>EMA, the EMA rises on that bar, so slope[1] down is impossible. The short system cannot use M15 EMA slope gates unlike the W21-O long system (where close<EMA is compatible with EMA falling).
H4 slope gate already implies DI bearish alignment on Mon+Fri
W47-E = W40-M identically. The slope-down condition ensures DI- is dominant at H4. Adding explicit DI->DI+ on top of slope adds zero selectivity on the Mon+Fri subset.
H4 ADX>25 selects worse trades — strong trend != better entries
W47-C: T:9, PF:0.837. Strong ADX readings at H4 often coincide with overextended moves where M15 relief rallies are broader and more likely to continue. The slope gate (directional) is superior to the ADX gate (magnitude).
Tested bearish bar, rejection wick, and bearish engulfing on the entry bar. Finding: M15 candle patterns are noise — the oscillator already captures directional information.
VariantPatternTPFNET MYR
W46-AStoch + Bearish Bar Filter221.661+5,115
W46-BStoch + Rejection Wick74.099+5,640
W46-CStoch + Bearish Engulfing51.330+600
M15 candle patterns are noise — oscillator already captures direction
Bearish bar, rejection wick, and bearish engulfing all either reduce quality or over-filter. At M15 granularity, individual bar structure is superseded by the oscillator reading. The Stoch crossunder from overbought already encodes the rejection — candle pattern adds redundant or conflicting information.
Rejection wick (PF:4.099) shows promise but T:7 is insufficient
When the entry bar has a dominant upper shadow (upper wick > body), quality improves substantially. However, reducing from T:24 to T:7 (~2.5/year) makes this impractical as a primary filter. Could serve as a secondary quality check if frequency is not a concern.
BB consistently inferior to Stochastic. DoW amplifier confirmed oscillator-agnostic: works on BB (PF:1.883→3.821) and CCI, but Stoch remains best.
VariantFilterTPFNET MYR
W45-ABB %B Crossunder 0.8 Full PM201.883+6,025
W45-BBB Upper Band Crossunder150.374-4,050
W45-CMon+Fri + BB %B Crossunder 0.8103.821+7,700
Bollinger Bands consistently inferior to Stochastic in this system
At every level tested (full PM, Mon+Fri, different thresholds), BB measures lag behind Stoch. Stochastic captures the range-relative momentum that identifies institutional selling into the EMA rally; BB captures price vs statistical distribution which is less precise for this setup.
DoW amplifier is oscillator-agnostic: works on BB, CCI, and Stoch
Mon+Fri improves every oscillator tested: Stoch (PF:2.297→6.745), CCI (PF:1.742→2.888), BB (PF:1.883→3.821). The weekend position management catalyst is independent of the entry trigger mechanism — it amplifies any valid overbought signal.
Williams %R = Stoch %K algebraically (identical signals). H4 Stoch>80 contradicts H4 slope-down gate (T:0). H1 MTF confirmation over-filters quality.
VariantFilterTPFNET MYR
W44-AH1 Stoch>80 + M15 Stoch Xunder 80112.029+3,745
W44-BH4 Stoch>80 + M15 Stoch Xunder 800+0
W44-DWilliams %R Xunder -20 Full PM242.297+10,030
Williams %R is algebraically identical to Stochastic %K
W44-D = W39-F exactly (T:24, PF:2.297). Williams %R and Stochastic %K both measure (close - lowest low) / (highest high - lowest low) over the lookback period. %R = -100 + (%K). The crossunder thresholds map directly: %R xunder -20 ≡ Stoch %K xunder 80. No new information.
H4 Stoch>80 is self-contradicting with H4 slope-down gate
W44-B: T:0. When H4 EMA21 is sloping down (the core trend gate), H4 Stoch is already in declining territory. H4 Stoch>80 and H4 slope-down are mutually exclusive in practice — same phenomenon as W47 M15 slope incompatibility.
CCI consistently inferior to Stochastic at every level. Stochastic remains the optimal oscillator. DoW amplifier confirmed oscillator-agnostic.
VariantFilterTPFNET MYR
W43-ACCI(20) Crossunder 100 Full PM171.742+4,390
W43-BCCI(14) Crossunder 100 Full PM141.451+2,255
W43-CCCI(20) Crossunder 150 Full PM190.618-2,995
W43-DMon+Fri + CCI(20) Crossunder 10092.888+5,155
CCI consistently inferior to Stochastic at every level tested
Full PM: CCI PF:1.742 vs Stoch PF:2.297. Mon+Fri: CCI PF:2.888 vs Stoch PF:6.745. CCI measures deviation from the mean in units of mean absolute deviation (overbought = >100). Stochastic measures position within the recent high-low range — better suited for identifying temporary price exhaustion against a strong EMA resistance.
DoW amplifier is oscillator-agnostic (confirmed on CCI)
Mon+Fri boosts CCI PF from 1.742 to 2.888 (+66%), the same multiplicative pattern seen with Stoch (2.297→6.745, +193%) and BB (1.883→3.821, +103%). The weekend position catalyst amplifies any overbought signal regardless of the measurement method.
CCI period 20 > 14 (longer lookback more robust)
CCI(20): PF:1.742 vs CCI(14): PF:1.451. Consistent with the W39 finding that H4 EMA21 > EMA13 — longer-period indicators reduce noise and capture structural overbought conditions more reliably than short-period ones in this system.
Decomposed the W39-F edge by day of week. Discovered that Mon+Fri account for all winning trades (T:11, WR:54.5%, PF:6.745) while Tue–Thu produce near-zero wins (T:13, WR:7.7%). Structural rationale: Monday = post-weekend catch-up selling; Friday = pre-weekend position squaring. Mid-week has no directional catalyst for the "failed rally" concept. W40-M: T:11, WR:54.5%, PF:6.745, NET:+13,070 MYR, Max DD 0.24% — highest PF in entire research program.
Day-of-Week Decomposition (W39-F base)
DayTWinsWR%PFNET (MYR)Structural Catalyst
Monday6350.0%5.868+6,645Post-weekend catch-up selling
Tuesday5120.0%1.330+600Weak — near break-even
Wednesday400.0%0−1,820No catalyst — drag
Thursday400.0%0−1,820No catalyst — drag
Friday5360.0%8.060+6,425Pre-weekend position squaring
Mon+Fri ★11654.5%6.745+13,070Weekend-adjacent combined
Tue–Thu1317.7%0.443−3,040Remove these entirely
Verification: Mon+Fri NET +13,070 + Tue–Thu NET −3,040 = W39-F total +10,030 ✓ | T:11+13=24 ✓ | Wins:6+1=7 ✓ PM time structure: 14:30–16:00 (T:15, PF:2.687) | 16:00–17:00 dead zone (T:0) | 17:00–18:00 (T:9, PF:1.739)
Mon+Fri DoW filter produces PF:6.745 — the highest in entire research program
— Full week W39-F (PF:2.297) decomposed by day: Mon (T:6, PF:5.868), Tue (T:5, PF:1.33), Wed (T:4, PF:0), Thu (T:4, PF:0), Fri (T:5, PF:8.06). The "failed rally" concept works when there is a directional catalyst — Mon/Fri have weekend position management pressure; mid-week does not.
Monday = post-weekend catch-up selling; Friday = pre-weekend position squaring
— Structural rationale: On Mondays, FCPO catches up to bearish weekend news (Dalian/global). Any PM relief rally is sold by bears continuing the move. On Fridays, longs do not want to hold FCPO over the weekend and aggressively sell any PM strength. Both create the same structural outcome: reliable institutional selling into the M15 failed rally signal.
Wednesday and Thursday: zero wins across 8 trades
— Mid-week (Wed T:4 WR:0%, Thu T:4 WR:0%) has no directional catalyst. EMA position + Stochastic overbought without weekend-related pressure creates false signals — the failed rally turns into a genuine continuation rally instead of a reversal. These 8 trades are the primary drag on W39-F performance.
PM session has a bimodal time structure: early open vs pre-close
— All 24 W39-F trades map as: 14:30–16:00 (T:15, PF:2.687), dead zone 16:00–17:00 (T:0), 17:00–18:00 (T:9, PF:1.739). The session open (first 90 min) has higher quality. Combining early PM with Mon+Fri: W40-P gives T:7, PF:7.183 — highest quality per trade, but T:7 approaches statistical minimum.
T:11 is the statistical concern — DoW filter needs more data to fully validate
— W40-M has T:11 over 33 months (~4 trades/year). The individual day checks (Mon independently: T:6 WR:50%; Fri independently: T:5 WR:60%) and the exact math verification (+13,070 − 3,040 = +10,030 ✓) provide structural confidence, but a larger data window is needed before live trading with this filter.
Refined W38-Q by sweeping the H4 trend EMA period, slope lookback, Stoch threshold, and M15 context gate. Key discovery: H4 EMA21 slope[3] outperforms H4 EMA34 slope[3] — faster EMA captures the active intermediate trend more precisely. Best variant W39-F: T:24, WR:29.2%, PF:2.297, NET:+10,030 MYR, Max DD 0.47% — new all-time best PF for short system.
VariantH4 Trend GateSlopeTWR%PFNET (MYR)Max DDVerdict
W39-QH4 EMA13 slope[3] 12 hrs1827.8%2.185+7,0102,995 (0.59%)T too small
W39-GH4 EMA21 slope[2] 8 hrs2227.3%2.108+8,0652,590 (0.51%)Too responsive
W39-F ★H4 EMA21 slope[3] 12 hrs2429.2%2.297+10,0302,415 (0.47%)NEW BEST — PF:2.30
W39-HH4 EMA21 slope[4] 16 hrs3225.0%1.848+9,2653,500 (0.69%)Too slow
W38-Q (ref)H4 EMA34 slope[3] 12 hrs2927.6%2.113+10,6302,995 (0.59%)Previous best
W39-PH4 EMA50 slope[3] 12 hrs3321.2%1.502+5,9354,235 (0.83%)Too slow
W39-KH4 close < EMA34(position)8112.4%0.752-8,25515,835 (3.12%)Position gate = FAIL
H4 EMA period at slope[3]: EMA13→PF:2.185 | EMA21→PF:2.297 ★ | EMA34→PF:2.113 | EMA50→PF:1.502. Sweet spot: EMA21 (faster but not noisy). Stoch threshold: <75→PF:1.58 | <80→PF:2.297 ★ | <85→PF:1.521. M15 context: above EMA21+EMA34 confirmed optimal (EMA21-only: PF:1.61).
H4 EMA21 is the optimal trend slope period
— H4 EMA period sweep at slope[3]: EMA13→PF:2.185, EMA21→PF:2.297, EMA34→PF:2.113, EMA50→PF:1.502. Sweet spot at EMA21 — faster than EMA34 but not too noisy. EMA21 captures the active intermediate downtrend while EMA50 is too slow to distinguish trend from chop.
slope[3] (12 hrs) is universally optimal across H4 EMA periods
— EMA21 slope sweep: slope[2]→PF:2.108, slope[3]→PF:2.297, slope[4]→PF:1.848, slope[5]→PF:1.584. Same 12-hour lookback confirmed optimal as in W38 with EMA34. Structural law: 12 hours (3 H4 bars) is the right balance between responsiveness and noise at the H4 level.
Slope gate > Position gate at H4
— H4 close<EMA34 position gate (W39-K) produces T:81, PF:0.752 — catastrophic. Position gate fires in all conditions where price is temporarily below EMA34. Slope gate (EMA21 slope[3] down) requires active declining momentum, which selects only genuine downtrends.
Stoch threshold and timing are both at the exact optimum
— Threshold sweep: <75→PF:1.58, <80→PF:2.297, <85→PF:1.521. Timing sweep: exact crossunder bar→PF:2.297, 2-bar window→PF:1.859, %D smoothed→T:8 (unusable). The exact %K crossunder 80 bar is the right signal.
M15 EMA34 context gate is load-bearing
— Relaxing from close>EMA21+EMA34 to close>EMA21 only (W39-M): T:29, PF:1.61 — adds 5 trades but PF collapses. Those entries (between EMA21 and EMA34) are low quality: price has not rallied deeply enough above the trend to constitute a genuine failed rally at the EMA34 level.
Dual H4 slope adds nothing (EMA21 subsumes EMA34)
— W39-J (both H4 EMA21 and EMA34 slope[3] down) produces identical results to W39-F (EMA21 only). When the faster EMA21 is sloping down over 12 hours, EMA34 is always also sloping down. No incremental value from requiring the slower EMA.
Hypothesis: Sell when price temporarily rallies above its own downtrend EMAs (EMA21 + EMA34) in a PM bear session, triggered by Stochastic overbought rejection — the "failed rally" structural entry. Best variant W38-Q: T:29, WR:27.6%, PF:2.113, NET:+10,630 MYR — approaches original W28-B quality (PF:2.476).
VariantEntry ConceptH4 SlopeTWR%PFNET (MYR)Max DDVerdict
W38-Dclose > EMA34 + Stoch<80[5] 20 hrs4221.4%1.505+7,590Structural breakthrough
W38-Nclose > EMA21+EMA34 + Stoch<80[5] 20 hrs4122.0%1.553+8,045Marginal improvement
W38-Q ★close > EMA21+EMA34 + Stoch<80[3] 12 hrs2927.6%2.113+10,6302,995 (0.59%)BEST — PF:2.11
W38-ULong mirror (< EMA21+34, Stoch>20)[3] 12 hrs ↑4617.4%0.959-8309,445 (1.87%)Bear data — invalid
H4 slope[3] sweep: [2]=+6,700 | [3]=+10,630 ★ | [4]=+9,865 | [5]=+8,045 | [7]=+1,170. Sweet spot at 12-hour lookback.
"Failed rally above trend EMA" is the key structural entry
— Requiring close > EMA34 at the Stochastic entry bar improves W37-L (PF:1.23) to W38-D (PF:1.505). Adding EMA21 constraint (above both EMAs) further improves to PF:1.553. The structural concept: sell when price temporarily rallied above its own downtrend EMAs and Stochastic turns overbought.
H4 slope lookback of 12 hours (slope[3]) is the sweet spot
— Curve: slope[2]=+6,700, slope[3]=+10,630, slope[4]=+9,865, slope[5]=+8,045, slope[7]=+1,170. The 12-hour H4 slope is more responsive than the original 20-hour (W21-O standard) without being too noisy. This is a significant structural calibration finding.
Trailing stops and time exits do not improve the system
— Trail 50/25: PF:0.916 (worse). Time exit 17:30: PF:1.237 (same as TP=100). VWAP crossunder: T:131, PF:0.649 (noise). Fixed TP=100 remains optimal — PM move distribution is too tight for trailing to add value.
EMA34 level filters: any amount above is optimal, margin filters hurt
— close > EMA34 (T:42, PF:1.505) vs close > EMA34+10 (T:28, PF:1.175) vs close > EMA34+20 (T:7, invalid). The binary "above/below EMA34" is the right structural test — the meaningful question is whether price is above the level at all, not how far above.
Long mirror fails on bear-heavy data — structural logic is sound but untestable
— W38-U (long mirror, T:46, PF:0.959) fails because Jul 2023–Apr 2026 FCPO is predominantly bear regime. The structural logic (below both EMAs + Stoch oversold + H4 bull) is theoretically valid and should be re-tested when bull-regime data is available.
Hypothesis: An oscillator-based overbought rejection signal (RSI or Stochastic crossing down from elevated levels) within the bear regime framework produces valid PM short entries. Result: Stochastic(14) crossunder 80 with H4 slope gate — T:63, WR:19%, PF:1.23, NET:+5,585 MYR (best variant W37-L).
VariantSignalGatesTWR%PFNET (MYR)D/dayVerdict
W37-CRSI(7) xunder <65Full (M15+H4)1216.7%0.968-160-0.2Near break-even, T too small
W37-HStoch(14) xunder <80Full (M15+H4)1526.7%1.719+4,050+3.9Positive — T:15 small
W37-L ★Stoch(14) xunder <80H4 only (no M15)6319.0%1.230+5,585+5.4BEST — balanced T/WR
W37-MStoch(9) xunder <80Full (M15+H4)378.1%0.436-9,385-9.1Faster period = noise
W37-NStoch(21) xunder <80Full (M15+H4)911.1%0.567-1,845-1.8Slower = too few signals
W37-OStoch(14)<80 TP=50H4 only6628.8%1.089+1,995+1.9TP=50 inferior PF
W37-PStoch(14)<80 TP=125H4 only5915.3%1.174+4,155+4.0TP=125 inferior to TP=100
Break-even WR = 14.4% at TP=100 SL=15 (40 MYR commission each way). W37-L WR:19% clears this comfortably.
Stochastic beats RSI for overbought rejection
— Stoch(14) crossunder <80 gives WR:26.7% (PF:1.719) vs RSI(7) crossunder <65 at WR:16.7% (PF:0.968). Stochastic measures price position within a recent range (high-low), making it more sensitive to true short-term overbought conditions in a bear trend.
H4 slope is the critical quality gate for oscillator signals
— Removing H4 slope: WR collapses 26.7%→9.5% (PF:1.719→0.451). Removing M15 slope: WR drops 26.7%→19% but T increases 15→63. H4 provides the regime context; M15 can be relaxed for frequency.
Stoch(14) is the optimal period — U-shaped degradation
— Stoch(9): T:37, WR:8.1%, PF:0.436 (too noisy). Stoch(14): T:15, WR:26.7%, PF:1.719 (optimal). Stoch(21): T:9, WR:11.1%, PF:0.567 (too slow, misses signals).
TP=100 confirmed optimal across oscillator entries
— TP=50: PF:1.089; TP=100: PF:1.23; TP=125: PF:1.174; TP=150: PF:0.901. Peak at TP=100 consistent with W28/W32 findings. FCPO PM move distribution clusters around 100-pt winners.
W37-L is a modest positive system — not a benchmark replacement
— T:63, WR:19%, PF:1.23, D/avg:+5.4 MYR/day. Positive and statistically meaningful but weaker than original W28-B (PF:2.476). Represents a second independent short edge to complement or stack with the slope-based system.
  • W21-O (Long, M5, PM): PF ~2.20, 21 trades, +RM94.56/day, 0.32% DD. Fires when close > D1 EMA200.
  • W28-A (Short, M15, PM): PF 2.524, 19 trades/30mo, +RM5/day. Fires when close < D1 EMA200.
  • Combined pair: W21-O + W28-A = regime-adaptive system. No session overlap — D1 EMA200 gates each side automatically.
  • Frequency ceiling confirmed (W29): H4 slope[5] is load-bearing. Removing it collapses PF 2.52 → 1.09. Cannot trade more without destroying quality.
  • Session-Timeframe Law confirmed bidirectionally (W29-C): PM >> AM for both longs and shorts.
  • Next milestone: IBKR data (May 2026) — 5+ years of M1 data for definitive sample sizes. W21-O + W28-A will be re-validated on full history.
  • Paper trading: W21-O on M5 chart, W28-A on M15 chart. Both Pine Scripts saved at scripts/W21O_LIVE.pine and scripts/W28A_LIVE.pine.
→ Open Paper Trade Log
Data source: TradingView Strategy Tester, FCPO continuous contract (Bursa Malaysia), 2022–2026. Commission: MYR 30/contract round-trip. Capital: MYR 500,000. 1 contract position sizing. Slippage: 1 tick. This page shows static data — will be connected to Supabase strategy_tests table once live. Not financial advice.

Amaran Risiko: Dagangan niaga hadapan (futures) melibatkan risiko kerugian yang tinggi dan tidak sesuai untuk semua pelabur. Kerugian boleh melebihi deposit margin asal anda. Prestasi lampau bukan jaminan prestasi masa hadapan. Kandungan di laman ini adalah untuk tujuan pendidikan dan maklumat sahaja, dan bukan nasihat pelaburan. Pastikan anda memahami sepenuhnya risiko yang terlibat sebelum berdagang, dan dapatkan nasihat profesional jika perlu.