I have been working RSI methods on XAUUSD for about 18 months now, and truthfully, single-timeframe RSI gave me extra complications than income. The usual RSI(14) on M15 seemed nice in backtests—till I went reside in October and watched it get chopped to items in the course of the London open.
That is after I rebuilt every little thing round multi-timeframe affirmation. And yeah, it is a kind of “why did not I do that sooner” moments. Here is what I realized (the laborious means).
Why Single-TF RSI Fails on Quick Pairs
The issue with utilizing RSI on only one timeframe—particularly for scalping Gold or main pairs—is that you just’re principally flying blind. You would possibly see RSI < 30 on M15, assume “oversold, time to purchase,” after which watch the value drop one other 50 pips as a result of H1 and H4 are each screaming “downtrend.”
I misplaced depend of what number of occasions this occurred in November earlier than I lastly obtained it by my thick cranium: you want context from larger timeframes.
Multi-timeframe affirmation solves this by:
- Filtering out trades that contradict the larger image
- Catching high-probability setups the place a number of timeframes align
- Decreasing whipsaws throughout consolidation (wich Gold likes to do)
The Setup: RSI Convergence Technique
The fundamental concept is easy: solely take trades when RSI indicators align throughout at the very least 3 timeframes.
For instance, my present setup for XAUUSD buys requires:
- M15 RSI < 30 (strongly oversold)
- M30 RSI < 35 (approaching oversold)
- H1 RSI < 45 (beneath midline, not overbought)
When all three hit, that is my “convergence zone” (belief me on this). Win price went from 42% (single TF) to 61% (multi TF) between October and December final 12 months. Actual cash, Pepperstone account. For context: that is 127 trades, revenue issue of 1.8, max drawdown 4.2%.
MQL5 Implementation (How I Constructed It)
Let me present you the precise code I am working. It isn’t fancy, however it works.
Step 1: Create RSI Handles
In MQL5, you want indicator handles for every timeframe. This took me some time to determine as a result of I stored attempting to create them inside OnTick() (rookie mistake—large reminiscence leak).
int rsiHandleM15, rsiHandleM30, rsiHandleH1; int OnInit() { rsiHandleM15 = iRSI(_Symbol, PERIOD_M15, 14, PRICE_CLOSE); rsiHandleM30 = iRSI(_Symbol, PERIOD_M30, 14, PRICE_CLOSE); rsiHandleH1 = iRSI(_Symbol, PERIOD_H1, 14, PRICE_CLOSE); if(rsiHandleM15 == INVALID_HANDLE || rsiHandleM30 == INVALID_HANDLE || rsiHandleH1 == INVALID_HANDLE) { Print("Error creating RSI handles - test your inputs"); return(INIT_FAILED); } return(INIT_SUCCEEDED); }
Step 2: Learn RSI Values
Helper perform to seize RSI from any deal with. I exploit this always:
double GetRSI(int deal with, int shift = 0) { double rsiBuffer[1]; ArraySetAsSeries(rsiBuffer, true); if(CopyBuffer(deal with, 0, shift, 1, rsiBuffer) != 1) { Print("RSI buffer copy failed, error: ", GetLastError()); return -1.0; } return rsiBuffer[0]; }
Professional tip: For the entry timeframe (M15), I exploit shift=0 to catch the sign because it kinds. However for affirmation timeframes (M30, H1), I typically use shift=1 to learn the closed bar—this avoids false indicators from bars nonetheless in formation. Extra on this beneath.
Step 3: Convergence Logic
That is the place it will get attention-grabbing. My first model had like 8 totally different circumstances and was a multitude. Present model is means less complicated:
bool IsMultiTFBuySetup() { double rsi_m15 = GetRSI(rsiHandleM15, 0); double rsi_m30 = GetRSI(rsiHandleM30, 1); double rsi_h1 = GetRSI(rsiHandleH1, 1); if(rsi_m15 < 0 || rsi_m30 < 0 || rsi_h1 < 0) return false; if(rsi_m15 < 30 && rsi_m30 < 35 && rsi_h1 < 45) { return true; } return false; } bool IsMultiTFSellSetup() { double rsi_m15 = GetRSI(rsiHandleM15, 0); double rsi_m30 = GetRSI(rsiHandleM30, 1); double rsi_h1 = GetRSI(rsiHandleH1, 1); if(rsi_m15 < 0 || rsi_m30 < 0 || rsi_h1 < 0) return false; if(rsi_m15 > 70 && rsi_m30 > 65 && rsi_h1 > 55) { return true; } return false; }
Step 4: Truly Taking the Commerce
Combine into OnTick(). Professional tip: solely test for indicators on new bars, not each tick. In any other case you will spam your self with duplicate trades (been there).
#embrace CTrade commerce; void OnTick() { static datetime lastBar = 0; datetime currentBar = iTime(_Symbol, PERIOD_M15, 0); if(currentBar == lastBar) return; lastBar = currentBar; if(PositionSelect(_Symbol)) return; if(IsMultiTFBuySetup()) { Print("Multi-TF BUY convergence detected"); ExecuteBuy(); } else if(IsMultiTFSellSetup()) { Print("Multi-TF SELL convergence detected"); ExecuteSell(); } } void ExecuteBuy() { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = ask - 200 * _Point; double tp = ask + 400 * _Point; commerce.Purchase(0.1, _Symbol, ask, sl, tp, "RSI Multi-TF Purchase"); } void ExecuteSell() { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl = bid + 200 * _Point; double tp = bid - 400 * _Point; commerce.Promote(0.1, _Symbol, bid, sl, tp, "RSI Multi-TF Promote"); }
What I Discovered After 3 Months Stay
Okay, actual discuss: multi-TF RSI is not a magic bullet. Here is what works and what would not.
What Works:
- Gold throughout London-NY overlap (13:00-17:00 GMT) – this setup kills it. The London session itself (08:00-16:30 GMT) is sweet, however the overlap with NY is the place the actual strikes occur.
- EURUSD throughout NY-London overlap – first rate win price
- Decrease timeframes for entry, larger for development context – that is key
What Does not Work:
- Asian session on something – too uneven, convergence indicators are trash
- First 30 min of reports occasions – RSI goes haywire (misplaced $180 in 12 minutes throughout NFP in November, by no means once more)
- Pairs with excessive spreads – For XAUUSD, something above $0.30-0.40 unfold eats your edge. For foreign exchange pairs, preserve it beneath 1 pip on majors.
Stuff I am Nonetheless Testing:
- Utilizing H4 RSI as a “veto” (if H4 > 70, ignore all M15 purchase indicators)
- Dynamic thresholds based mostly on ATR (when ATR(14) on H1 spikes above $3.00, regular RSI thresholds may not apply)
- Including a easy MA filter to keep away from ranging markets
Different: Weighted RSI Rating
If strict thresholds really feel too inflexible (they do typically), do that method as an alternative. I constructed a second model that makes use of weighted scores:
double CalculateRSIScore() rsi_m30 < 0
This provides you extra nuance than binary sure/no. A rating of -25 is far more assured than -16, and you’ll dimension positions accordingly. I weight H1 at 50% as a result of the upper timeframe development is a very powerful filter—preventing it’s a dropping sport.
I am nonetheless forward-testing this model (began Jan 15), however early outcomes look promising. It avoids a few of the false indicators that the strict threshold methodology hits.
Widespread Errors (I Made All of These)
Mistake #1: Ready for ALL timeframes to be excessive
Do not require M15, M30, AND H1 to all be < 30. You may get like 2 indicators monthly. Use graduated thresholds (30/35/45) as an alternative.
Mistake #2: Ignoring time-of-day
Multi-TF RSI works throughout lively periods. Throughout Asian hours or late Friday? Overlook it. Add session filters.
Mistake #3: Forgetting to launch handles
Reminiscence leak metropolis. At all times clear up in OnDeinit():
void OnDeinit(const int purpose) { IndicatorRelease(rsiHandleM15); IndicatorRelease(rsiHandleM30); IndicatorRelease(rsiHandleH1); Print("RSI handles launched"); }
Mistake #4: No ATR filter
If Gold’s ATR(14) on H1 spikes above $3.00 (loopy volatility, like throughout FOMC), your regular RSI thresholds may not apply. I realized this the laborious means. Think about widening your thresholds or staying out fully throughout high-ATR intervals.
Mistake #5: Utilizing shift=0 for affirmation timeframes
Whenever you learn RSI from the next timeframe with shift=0 , you are studying the bar that is nonetheless forming—it will probably change earlier than it closes. For true “affirmation,” use shift=1 on M30 and H1 to learn the final closed bar. This reduces false indicators considerably.
Mistake #6: Not accounting for hedging vs netting accounts
PositionSelect(_Symbol) works nice on netting accounts (one place per image). However on hedging accounts (widespread with Pepperstone, IC Markets), you’ll be able to have a number of positions on the identical image. Use PositionsTotal() with a loop to test correctly.
The place to Go From Right here
If you wish to do that, begin with simply 3 timeframes (M15, M30, H1) and preserve it easy. Do not overthink it.
My full EA (with all of the session filters, ATR checks, and threat administration) is in my GitHub portfolio: github.com/jimmer89/mql5-portfolio. The indicator model (simply exhibits you when convergence occurs) is in MQL5 CodeBase—search “RSI MultiTF Scanner.”
For backtesting, use MT5’s Technique Tester in “Each tick based mostly on actual ticks” mode. Multi-timeframe EAs want correct tick knowledge to simulate appropriately—”Open costs solely” gives you rubbish outcomes.
I am additionally testing a model with divergence detection throughout timeframes, however that is nonetheless within the “does this truly work or am I simply curve-fitting” section.
Backside Line
Multi-timeframe RSI is not revolutionary—it is simply RSI completed correctly. Single-TF evaluation is like attempting to drive by solely trying on the dashboard. That you must look out the windshield too.
Does it work 100% of the time? Nope. However it filters out sufficient rubbish trades that my win price improved by nearly 20%, and that is what issues.
Should you’re working single-TF RSI proper now and getting chopped up, do that. Worst case, you waste a weekend coding it. Greatest case, you repair your technique.
Let me know for those who construct one thing with this. At all times curious to see what individuals provide you with.
Jaume S.(WhiteChocolate on MQL5.com) – Freelance MQL5 dev, Gold scalping addict. At the moment working this on 2 reside accounts + 1 demo for testing new filters.