WARTADATAIndonesia Data Brief

Research, methods and code

Trading Research Zone

Every article in Trading Zone reviews a published academic paper — purely for education (learning methods from the literature), NOT a trading signal or buy/sell recommendation. The EA code shown is an illustration of the logic structure for learning purposes, not production-ready code. We encourage you to read the original paper in full and test independently on a demo account before drawing any conclusions. Futures/forex trading is a high-risk, high-return activity.

Prop FirmFTMORisk ManagementRegulationCritical Study

Prop Firms: 90% Fail the Evaluation, and One Firm Was Sued for Making Sure of It

Instrument: Forex, metals, stock indices (FTMO & The 5ers) · September 9, 2026

Prop firms are marketed hard to retail traders: pay for an evaluation, pass it, and receive hundreds of thousands of dollars in 'capital'. This report is interesting not for its strategy but because the author actually went through the process — 21 weeks across two providers at once, FTMO and The 5ers, $100,000 per account, trading Smart Money Concepts in the Inner Circle Trader style, with ChatGPT used as a prop against the psychological pressure of drawdowns.

First, its standing. This is not a journal paper but an Interactive Qualifying Project report at Worcester Polytechnic Institute. Its own cover page states that 'WPI routinely publishes these reports on the web without editorial or peer review'. The sample is one person and the results are self-reported. Read it as a well-documented account of an experience, not as evidence.

The number most worth remembering sits in the chapter 'Why Traders Fail Prop Firm Evaluations': roughly 90% of evaluation participants fail (citing Dapo, 2024). The obstacle, the report argues, is not a shortage of capital or opportunity — it is the psychological demand and the severity of the risk rules.

The typical rules run like this: on a $100,000 account, maximum drawdown is capped at 10% of account value and no more than 5% on any single trading day. That is the entire margin for error. Six causes of failure are listed: weak risk management, psychological pressure during drawdown, an untested strategy edge, over-leveraging to recover losses, misreading the evaluation rules, and inexperience.

But the most important part of the report is its regulatory chapter, and it rarely appears in prop-firm marketing. In 2023 the US Commodity Futures Trading Commission (CFTC) took action against My Forex Funds (Traders Global), one of the largest prop firms at the time.

The allegations are severe. The CFTC alleged the firm acted as the COUNTERPARTY to its own traders rather than routing orders to a liquidity provider. From that position it was accused of engineering price slippage against successful traders, imposing commission structures that systematically eroded account equity, and using specialised software so customer orders filled at worse prices than those displayed. The CFTC described it as 'handicapping the extremely small number of successful customers to decrease customer profits and increase customer losses'.

The scale was large: more than 135,000 customers signed up from November 2021, paying at least $310 million in fees. The complaint further alleged proceeds were used to buy luxury homes and cars. Which means that in a business model like this one, evaluation fees can be the primary revenue — not a share of what successful traders earn.

The reasonable conclusion is not that prop firms are a scam. FTMO and The 5ers ran their evaluations by the stated rules and a payout was requested. The reasonable conclusion is: treat the evaluation fee as money you may simply lose, check whether the provider routes orders to the market or takes the other side of them, and remember that a 5% daily drawdown rule punishes one emotional decision far harder than your own account ever would.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| NOT A STRATEGY — a prop-firm rule guard                          |
//| Derived from the limits described in the report                  |
//+------------------------------------------------------------------+
// The report provides no EA. What can be reused are the rules: the
// loss limits that wash out 90% of participants.
//
// Two limits run at once, and the DAILY one usually kills the account
// first:
//   - Total drawdown : 10% of the starting balance
//   - Daily drawdown : 5% of that day's opening balance

input double StartBalance      = 100000.0;
input double TotalLimitPct     = 10.0;
input double DailyLimitPct     = 5.0;
input double RiskPerTradePct   = 0.5;   // conservative; many use 1-2%

double dayOpenBalance = 0.0;
datetime recordedDay  = 0;

void RefreshDailyAnchor() {
   MqlDateTime t; TimeToStruct(TimeCurrent(), t);
   datetime today = StringToTime(StringFormat("%04d.%02d.%02d", t.year, t.mon, t.day));
   if (today != recordedDay) {
      recordedDay    = today;
      dayOpenBalance = AccountInfoDouble(ACCOUNT_BALANCE);
   }
}

//+------------------------------------------------------------------+
//| Returns false when opening a position would risk breaching either |
//| limit. Call it BEFORE every order.                                |
//+------------------------------------------------------------------+
bool MayOpenPosition() {
   RefreshDailyAnchor();
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);

   double totalFloor = StartBalance * (1.0 - TotalLimitPct / 100.0);
   double dailyFloor = dayOpenBalance * (1.0 - DailyLimitPct / 100.0);

   if (equity <= totalFloor) {
      Print("TOTAL drawdown limit reached. Evaluation failed.");
      return false;
   }
   if (equity <= dailyFloor) {
      Print("DAILY drawdown limit reached. Stop until tomorrow.");
      return false;
   }
   // Distance to the nearer floor sets what position size is reasonable.
   double roomLeft    = equity - MathMax(totalFloor, dailyFloor);
   double plannedRisk = StartBalance * RiskPerTradePct / 100.0;
   if (plannedRisk > roomLeft * 0.5) {
      Print("Position size too large for the remaining loss headroom.");
      return false;
   }
   return true;
}

// Note: sizing up to recover losses is failure cause number 4 in the
// report. The function above shrinks as headroom shrinks — the opposite
// of the natural impulse.
Trading PsychologyAddictionMental HealthMust Read

When Trading Stops Being Investing: 8 Patients at a Problem Gambling Clinic

Instrument: Trader behaviour (clinical study) · September 9, 2026

Every other article in Trading Zone is about how to enter the market. This one is about what happens when someone cannot stop. It is also the only paper in the series published in a peer-reviewed medical journal rather than an engineering or business one.

Researchers at the gambling disorder unit of Nantes University Hospital in France examined a cohort of 221 outpatients seeking treatment for gambling problems. Eight of them had come not because of casinos or sports betting, but because of TRADING. They referred themselves to a pathological gambling unit, describing their problem as a trading addiction.

The central finding: the trajectory of those eight was nearly identical to that of disordered gamblers. Small early wins that built confidence, then chasing losses, then losing control over the money invested. All of them had put money into very high-risk stocks on short trading horizons — large potential gains, and losses of matching size.

The diagnostic criteria for gambling disorder turned out to apply to excessive trading; the researchers only had to replace the word 'gambling' with 'trading' in the instrument. All eight patients were male, and all scored high on sensation seeking.

The paper also lists the four elements of gambling that the literature finds present in certain trading practices: money is staked, the stake is irreversible, the outcome is binary win-or-lose, and the outcome depends entirely or partly on chance. The shorter the horizon, the more completely all four are satisfied.

Their concluding sentence is worth quoting exactly, because it refuses both extremes: 'Investing is not a form of gambling, but some people gamble with investments.' This is not a verdict that trading equals gambling — it is a recognition that for some people the activity changes into something else.

The authors state the limits themselves: only eight cases, so it cannot be generalised. Nor does a validated instrument for 'excessive trading' yet exist — they borrowed the pathological gambling criteria. Which is exactly why their closing recommendations are a call to action: do more research, build validated assessment tools, and develop prevention and treatment strategies.

We placed this article in Trading Zone deliberately. The whole section is about building systems and testing strategies — and most of its papers report results far more modest than the promises in circulation. If you find yourself adding to a position to recover yesterday's loss, or trading more frequently after a large loss, that pattern is documented in the clinical literature, and help exists.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| NOT A STRATEGY — a behavioural checklist                         |
//| Derived from the clinical markers described in the paper         |
//+------------------------------------------------------------------+
// There is no code to copy from this paper. What can be reused are its
// questions. The researchers applied gambling-disorder criteria with
// the word "gambling" replaced by "trading".
//
// Ask yourself, honestly:
//
// 1. CHASING LOSSES
//    After a loss, do I open again sooner or larger to "get it back"?
//    This was the most consistent marker across all eight patients.
//
// 2. LOSS OF CONTROL OVER THE AMOUNT
//    Has the money involved passed the limit I set for myself? How
//    many times have I moved that limit?
//
// 3. EARLY WINS SHAPING BELIEF
//    Does my confidence rest on a few early wins rather than on the
//    full record of every trade?
//
// 4. A SHORTENING HORIZON
//    Have I drifted from holding for days to holding for minutes? The
//    shorter the horizon, the more completely the gambling elements
//    cited by this paper are satisfied.
//
// 5. EFFECTS AWAY FROM THE SCREEN
//    Is sleep, work, or family life being affected?
//
// If several of these land, the answer is not a better strategy. In
// Indonesia, counselling is available through SEJIWA 119 ext. 8, and
// psychologists at public health centres and regional mental hospitals
// take referrals for behavioural addiction.
Money ManagementOscar's GrindBollinger BandsADXH1 vs H4

Oscar's Grind on XAU/USD: Raising the Lot After a Win, Not After a Loss

Instrument: XAU/USD (Gold) · September 9, 2026

Almost every other paper in this series hunts for an entry signal. This one puts the heart of its system somewhere else entirely: in how large the position is, not in when to open it. The signal itself is plain — price touching a Bollinger Band (period 21, deviation 2.0) with trend confirmation from ADX (period 14, threshold 18).

What makes it worth reading is Oscar's Grind, its money-management rule. Position size is increased after every WIN (starting at 0.10 lots, stepping up by 0.10, capped at 1.00) and held unchanged after a loss. That is the opposite of martingale, which doubles up after losses — the pattern we warned about in the free-EA reliability article. Oscar's Grind raises the stake while you are being proved right, not while you are being proved wrong.

The testing is among the most complete in this series: a three-year backtest (29 April 2022 – 29 May 2025) AND a one-month real-time test (12 June – 12 July 2025), starting from $10,000 on an XM demo account at 1:1000 leverage. Two scenarios were compared — the H1 and H4 timeframes — with identical EA parameters.

Backtest results: H1 returned a profit factor of 1.08 with a 30.45% maximum drawdown and a 42.99% win rate across 1,098 trades. H4 was better on nearly every measure — profit factor 1.26, Sharpe ratio 3.38, recovery factor 2.09, and a maximum drawdown of only 19.52% across 334 trades.

The real-time month pointed the same way, and here is the part that rarely happens in this series: BOTH scenarios finished in profit. H1 closed at $10,278.62 (a $278.62 gain, 43.33% win rate, profit factor 1.11) but with a recovery factor of just 0.28 and a 9.91% drawdown. H4 closed at $10,636.71 (a $636.71 gain) with a 61.11% win rate, profit factor 2.11, recovery factor 3.98, and a maximum drawdown of only 1.58%.

The authors ran a t-test comparing simulation against the live market, and reported it honestly: profit per trade showed NO significant difference (p = 0.678 for H1; p = 0.938 for H4), but final balance accumulation did differ significantly (p < 0.001 for H1; p = 0.004 for H4). Individual wins and losses were similar sizes; the path the account travelled was not. A backtest still is not a copy of the live market.

Two limits worth stating plainly. First, the H4 real-time test contains only 18 trades in a month — too small a sample to conclude long-run reliability, the same caveat that applies to the Fibonacci + Ichimoku paper in this series. Second, Oscar's Grind does still scale position size up; the 1.00-lot ceiling is what contains the risk, and removing that cap would change the character of the system completely.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: Oscar's Grind + Bollinger Bands + ADX  |
//| Simplified from the paper's method — not production code         |
//+------------------------------------------------------------------+
input int    BB_Period      = 21;    // Bollinger period, as in the paper
input double BB_Deviation   = 2.0;
input int    ADX_Period     = 14;
input double ADX_Threshold  = 18.0;  // a trend counts as valid above this
input double StartStake     = 0.10;  // opening lot size
input double StakeIncrement = 0.10;  // added AFTER A WIN
input double MaxStake       = 1.00;  // the cap — the most important line here
input int    TakeProfitPts  = 1000;
input int    StopLossPts    = 800;

double currentLot = StartStake;
int bbHandle, adxHandle;

int OnInit() {
   bbHandle  = iBands(_Symbol, PERIOD_CURRENT, BB_Period, 0, BB_Deviation, PRICE_CLOSE);
   adxHandle = iADX(_Symbol, PERIOD_CURRENT, ADX_Period);
   return INIT_SUCCEEDED;
}

//+------------------------------------------------------------------+
//| The core of Oscar's Grind.                                       |
//| Note the direction: the lot goes UP after a win and STAYS after  |
//| a loss. Martingale does the reverse — doubling after a loss —    |
//| which is what makes its equity curve look smooth for years and   |
//| then empty the account in a single losing run.                   |
//+------------------------------------------------------------------+
void UpdateLot(bool tradeWon) {
   if (tradeWon) {
      currentLot = MathMin(currentLot + StakeIncrement, MaxStake);
   }
   // After a loss: the lot is NOT changed, and NOT doubled.
}

void OnTick() {
   if (PositionsTotal() > 0) return;

   double upper[], lower[], adx[], plusDI[], minusDI[];
   CopyBuffer(bbHandle, 1, 0, 2, upper);
   CopyBuffer(bbHandle, 2, 0, 2, lower);
   CopyBuffer(adxHandle, 0, 0, 2, adx);
   CopyBuffer(adxHandle, 1, 0, 2, plusDI);
   CopyBuffer(adxHandle, 2, 0, 2, minusDI);

   if (adx[0] <= ADX_Threshold) return;   // without a trend, band touches are ignored

   double ask   = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double bid   = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);

   if (ask >= upper[0] && plusDI[0] > minusDI[0]) {
      // trade.Buy(currentLot, _Symbol, ask,
      //           ask - StopLossPts * point, ask + TakeProfitPts * point);
   } else if (bid <= lower[0] && minusDI[0] > plusDI[0]) {
      // trade.Sell(currentLot, _Symbol, bid,
      //            bid + StopLossPts * point, bid - TakeProfitPts * point);
   }
}

//+------------------------------------------------------------------+
//| Fired when a position closes: its outcome sets the next lot.     |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result) {
   if (trans.type != TRADE_TRANSACTION_DEAL_ADD) return;
   // UpdateLot(dealProfit > 0);
}
Smart Money ConceptsSupply & DemandCritical StudyRisk-Reward

Smart Money Concepts: Loud on Social Media, Thin on Evidence

Instrument: Forex (market structure analysis) · September 9, 2026

Smart Money Concepts (SMC) may be the loudest trading vocabulary on social media in recent years: break of structure, order blocks, liquidity grabs, supply and demand zones. We went looking for an academic document that tests those claims — and this is the reference that keeps surfacing. What we found is itself the reason this article exists.

This is not a peer-reviewed journal paper. It is a bachelor's thesis from Centria University of Applied Sciences in Finland. More to the point, the author states plainly in the abstract that the strategy was assembled from 'various smart money concepts and strategies found on the internet along with the experience of the author trading forex'. The conclusion repeats that statement almost word for word.

The consequence has to be said out loud: there is NO backtest, no real-time test, no profit factor, no drawdown, no statistical test of any kind. The reference list is almost entirely blogs and broker websites — Investopedia, Babypips, Binomo, FBS, IG, forexlens, mytradingskills — rather than academic literature. Compare that with the Donchian or Oscar's Grind papers in this series, which test three years of data and then carry the system into the live market.

So why cover it at all? Because that IS the finding: a concept sold as 'how institutions and banks trade' has, at the best documentation we could locate, never been tested empirically. That is useful to know before anyone pays for SMC mentoring.

One part of the thesis keeps its value, because it is arithmetic rather than a claim: a table linking risk-to-reward ratio to the minimum win rate needed merely to break even. A 2:1 risk-to-reward (risking 40 pips to make 20) demands a 67% win rate. 1:1 demands 50%. 1:1.5 demands 40%. 1:2 demands roughly 33%. And at the extreme, 3:1 demands 75%. We recomputed all of them — the numbers check out.

The implication holds for any strategy, not just SMC: when the reward per trade exceeds the risk, a trader can stay profitable while being wrong more often than right. Conversely, a system chasing small targets behind wide stops needs a very high hit rate — and hit rates that high rarely survive outside a backtest.

The author closes with a warning worth quoting: he is not a financial adviser, takes no responsibility for anyone's losses, and recommends long practice on a demo account first. That is more honest than most of the paid SMC content in circulation.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| NOT A READY STRATEGY — a risk-reward viability calculator        |
//| Derived from the thesis's Table 1 (arithmetic, independently     |
//| verified)                                                        |
//+------------------------------------------------------------------+
// The thesis provides no testable EA, so there is no strategy to copy.
// What can be reused is the calculation: the MINIMUM win rate a system
// needs just to break even at a given risk-reward ratio.
//
// Formula: breakEvenWinRate = risk / (risk + reward)
//
// Run this BEFORE believing any system's advertised win rate — a system
// targeting 20 pips behind a 40-pip stop must be right 67% of the time
// simply to avoid losing, let alone to profit.

double BreakEvenWinRate(double riskPips, double rewardPips) {
   if (riskPips + rewardPips <= 0) return 0.0;
   return riskPips / (riskPips + rewardPips) * 100.0;
}

void OnStart() {
   //   risk  reward   result in the paper
   //     40      20   ->  67%
   //     40      40   ->  50%
   //     40      60   ->  40%
   //     40      80   ->  33%
   //     60      20   ->  75%
   PrintFormat("Stop 40 / target 20  -> needs %.1f%% wins", BreakEvenWinRate(40, 20));
   PrintFormat("Stop 40 / target 60  -> needs %.1f%% wins", BreakEvenWinRate(40, 60));
   PrintFormat("Stop 60 / target 20  -> needs %.1f%% wins", BreakEvenWinRate(60, 20));
}

// Note: these are BREAK-EVEN points, before spread, commission and
// slippage. In the real market the bar always sits higher than this
// calculation suggests.
Manipulation DetectionStop HuntPrice ActionRisk Management

Stop Hunt Detection: An EA That Watches for Stop-Loss Raids

Instrument: EUR/USD · September 9, 2026

Unlike the other papers in this series, which hunt for entry signals, this one is about detecting when price itself is being hunted — what retail traders call a stop hunt: price spikes sharply one way, sweeps the stop-loss orders clustered at a level, then reverses.

The authors build an indicator plus an Expert Advisor on MetaTrader 4 that flags suspicious candles: a sharp spike of at least a set size (250 points in their test) that quickly reverses. When the pattern appears, the EA enters against the spike, places its stop exactly at the extreme of that candle, and targets a 1:3 risk-reward ratio.

A three-year backtest (2016–2018) on EUR/USD with $10,000 starting capital and a fixed 1.0 lot produced a 124.15% profit.

An honest caveat: this paper reports BACKTEST results only — there is no real-time test, unlike several other papers in this series. Given the pattern we keep seeing (strong backtests collapsing live), that 124% is best read as "this idea is worth investigating further", not as expected performance. The paper's real value is the awareness it builds: placing stops at crowded, obvious levels carries a risk of its own.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: Stop hunt detection (spike + reversal) |
//| Simplified from the paper's method — not production code         |
//+------------------------------------------------------------------+
input int    MinSpikePoints = 250;   // minimum spike size to count as suspicious
input double RiskReward     = 3.0;   // 1:3 risk-reward, as used in the paper
input double LotSize        = 0.10;

// A candle is treated as a likely stop hunt when it has a long wick one way
// but closes back the other way — the level was touched to sweep stops rather
// than because directional pressure held.
bool IsStopHuntCandle(int shift, bool &huntedLow) {
   double high  = iHigh(_Symbol, PERIOD_CURRENT, shift);
   double low   = iLow(_Symbol, PERIOD_CURRENT, shift);
   double open  = iOpen(_Symbol, PERIOD_CURRENT, shift);
   double close = iClose(_Symbol, PERIOD_CURRENT, shift);
   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);

   double lowerWick = (MathMin(open, close) - low) / point;
   double upperWick = (high - MathMax(open, close)) / point;
   double body      = MathAbs(close - open) / point;

   if (lowerWick >= MinSpikePoints && lowerWick > body * 2) { huntedLow = true;  return true; }
   if (upperWick >= MinSpikePoints && upperWick > body * 2) { huntedLow = false; return true; }
   return false;
}

void OnTick() {
   if (PositionsTotal() > 0) return;

   bool huntedLow = false;
   if (!IsStopHuntCandle(1, huntedLow)) return;

   double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
   double high  = iHigh(_Symbol, PERIOD_CURRENT, 1);
   double low   = iLow(_Symbol, PERIOD_CURRENT, 1);

   if (huntedLow) {
      // Lows were swept and price recovered -> go long, stop at the spike low.
      double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      double sl  = low - 5 * point;
      double tp  = ask + (ask - sl) * RiskReward;
      // trade.Buy(LotSize, _Symbol, ask, sl, tp);
   } else {
      double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double sl  = high + 5 * point;
      double tp  = bid - (sl - bid) * RiskReward;
      // trade.Sell(LotSize, _Symbol, bid, sl, tp);
   }
}
Critical StudyEA ValuationTrader ProtectionMust Read

Only 6.8% of Free Trading Robots Are Worth Using

Instrument: Study of free MT4 Expert Advisors · September 9, 2026

If you only read one article in Trading Zone, make it this one. This paper builds no new strategy — it tests a widely circulated claim: can the free Expert Advisors scattered across the MT4 market actually be relied on?

The authors examined three things: what percentage of free EAs are fit for traders to use, whether the number of indicators inside an EA affects profit potential, and what a free EA is actually worth under an income (discounted cash flow) approach.

The finding is blunt: only 6.8% of free EAs were judged worth using in a real market. Out of every 100 free robots downloaded, roughly 93 fail the test.

The second finding matters just as much: using one indicator or many made no significant difference to MT4 backtest results. That challenges the common assumption — often used as a selling point — that an EA packed with more indicators is inherently smarter.

Third: under DCF valuation, not one of the usable free EAs was worth as much as Rp1,000,000 (roughly US$60). So when someone sells a robot for millions of rupiah while promising certain returns, this number is worth remembering.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| NOT A STRATEGY — a checklist before trusting any EA              |
//| Derived from the suitability criteria discussed in the paper     |
//+------------------------------------------------------------------+
// This paper proposes no new EA, so there is no strategy to copy. What is
// more useful: how to vet an EA before you run it.
//
// 1. A BACKTEST IS NOT PROOF
//    Run it with "Every tick based on real ticks", never "Open prices only".
//    Modeling quality below 90% means the result cannot be trusted.
//
// 2. READ DRAWDOWN, NOT JUST PROFIT
//    A robot showing 300% gain with 80% drawdown means the account was nearly
//    wiped out on the way. Check "Maximal drawdown" in the Strategy Tester report.
//
// 3. WATCH FOR MARTINGALE PATTERNS
//    Search the code/parameters for: LotMultiplier, Martingale, Recovery,
//    Averaging. Doubling lots after losses produces an equity curve that looks
//    smooth for years, then empties the account in a single losing run.
//
// 4. INDICATOR COUNT GUARANTEES NOTHING
//    The paper found multi-indicator EAs were not demonstrably better than
//    single-indicator ones in their tests.
//
// 5. FORWARD TEST ON DEMO
//    Several weeks in live market conditions at minimum. Every paper in this
//    Trading Zone series shows the same pattern: live performance almost always
//    lands below the backtest.
//
// 6. VALUE IT YOURSELF, DON'T ACCEPT THE ASKING PRICE
//    The paper used discounted cash flow and found no usable free EA worth
//    even Rp1,000,000.
Double ConfirmationStochasticMACDTrailing Stop

Double Confirmation: A Stochastic + MACD EA on MetaTrader 4

Instrument: Forex (MetaTrader 4) · September 9, 2026

This paper designs an EA built on double confirmation: a trade only opens when MACD and Stochastic signal in the same direction at the same time. The idea mirrors the EMA+RSI+Bollinger paper in this series — filter out false signals by requiring indicators to agree.

MACD reads trend direction and momentum, while Stochastic reads overbought/oversold conditions. Combining them is meant to cover each one's weakness: MACD tends to lag, while Stochastic fires too often in sideways markets.

Exits are handled automatically through take profit, stop loss, and a trailing stop, with values the trader sets in the Input tab. The authors also provide a parameter tab for money management settings.

A limit worth stating plainly: this paper focuses on DESIGN and functional testing — whether the EA opens and closes trades according to the programmed rules. The research is declared successful when "the expert advisor runs properly and is ready to use". There is no reported profit factor, drawdown, or long-horizon backtest, unlike the Donchian or Ichimoku papers in this series. So it is a good read for learning how a double-confirmation EA is STRUCTURED, not a basis for concluding the strategy is profitable.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: MACD + Stochastic double confirmation  |
//| Entry only when BOTH indicators agree on direction               |
//+------------------------------------------------------------------+
input int    MACD_Fast   = 12;
input int    MACD_Slow   = 26;
input int    MACD_Signal = 9;
input int    Stoch_K     = 5;
input int    Stoch_D     = 3;
input int    Stoch_Slow  = 3;
input double OversoldLvl = 20.0;
input double OverboughtLvl = 80.0;
input int    TrailingStopPoints = 200;

int macdHandle, stochHandle;

int OnInit() {
   macdHandle  = iMACD(_Symbol, PERIOD_CURRENT, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE);
   stochHandle = iStochastic(_Symbol, PERIOD_CURRENT, Stoch_K, Stoch_D, Stoch_Slow, MODE_SMA, STO_LOWHIGH);
   return INIT_SUCCEEDED;
}

void OnTick() {
   double macdMain[], macdSig[], stochMain[], stochSig[];
   CopyBuffer(macdHandle, 0, 0, 2, macdMain);
   CopyBuffer(macdHandle, 1, 0, 2, macdSig);
   CopyBuffer(stochHandle, 0, 0, 2, stochMain);
   CopyBuffer(stochHandle, 1, 0, 2, stochSig);

   // MACD: main line crossing the signal line marks a momentum shift
   bool macdBull = macdMain[0] > macdSig[0] && macdMain[1] <= macdSig[1];
   bool macdBear = macdMain[0] < macdSig[0] && macdMain[1] >= macdSig[1];

   // Stochastic: the cross must come out of an extreme zone, not mid-range
   bool stochBull = stochMain[0] > stochSig[0] && stochMain[1] <= stochSig[1] && stochMain[1] < OversoldLvl;
   bool stochBear = stochMain[0] < stochSig[0] && stochMain[1] >= stochSig[1] && stochMain[1] > OverboughtLvl;

   if (PositionsTotal() == 0) {
      if (macdBull && stochBull) {
         // trade.Buy(lot, _Symbol);
      } else if (macdBear && stochBear) {
         // trade.Sell(lot, _Symbol);
      }
   } else {
      ManageTrailingStop(TrailingStopPoints);   // exits handled by the trailing stop
   }
}

void ManageTrailingStop(int points) {
   // Walks the stop loss behind price once the position is in profit,
   // matching the trailing-stop mechanism described in the paper.
}
BreakoutDonchian ChannelSafe-F Money Management

Donchian Channel + Safe-F Money Management on XAG/USD

Instrument: XAG/USD (Silver) · September 8, 2026

This study builds and tests an Expert Advisor (EA) on MetaTrader 5 that combines breakout signals from the Donchian Channel indicator with position sizing via the Safe-F Money Management method — a conservative approach that adjusts trade size based on account balance and drawdown tolerance, rather than a fixed lot size.

The EA was tested two ways: backtesting on 4 years of historical data across two timeframes (M30 and H1) with a $10,000 starting balance and 2% risk per trade, then real-time testing for 1 month on a Weltrade demo account with the same balance.

The results are honestly interesting to study: the H1 scenario looked great in backtesting (Sharpe Ratio 1.26, low drawdown, stable performance). But once tested in real time, BOTH scenarios recorded a profit factor below 1 and a net loss — proof that a solid backtest doesn't guarantee immediate profitability under real market conditions, where volatility and execution factors (slippage, actual spread) matter a great deal.

The paper itself concludes that further optimization and broader testing are needed before a system like this can be relied upon in dynamic market conditions.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: Donchian Breakout + Safe-F Money Mgmt  |
//| Simplified from the paper's methodology — not for live trading  |
//+------------------------------------------------------------------+
input int    DonchianPeriod   = 20;     // channel length (number of bars)
input double RiskPercent      = 2.0;    // % of balance risked per trade
input double SafeF_MaxDD      = 0.20;   // max tolerated historical drawdown (Safe-F)

double GetDonchianUpper(int period) {
   return iHigh(_Symbol, PERIOD_CURRENT, iHighest(_Symbol, PERIOD_CURRENT, MODE_HIGH, period, 1));
}
double GetDonchianLower(int period) {
   return iLow(_Symbol, PERIOD_CURRENT, iLowest(_Symbol, PERIOD_CURRENT, MODE_LOW, period, 1));
}

// Safe-F: lot size is derived from account balance and tolerated drawdown,
// not a fixed lot — a more conservative variant of classic "optimal f".
double CalcSafeFLotSize(double accountBalance, double stopLossDistance) {
   double riskAmount = accountBalance * (RiskPercent / 100.0);
   double safeFCap   = accountBalance * SafeF_MaxDD;
   riskAmount = MathMin(riskAmount, safeFCap);
   double tickValue  = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double lots       = riskAmount / (stopLossDistance * tickValue);
   return NormalizeDouble(lots, 2);
}

void OnTick() {
   double upper = GetDonchianUpper(DonchianPeriod);
   double lower = GetDonchianLower(DonchianPeriod);
   double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);

   if (PositionsTotal() == 0) {
      double sl_distance = (upper - lower); // illustration: channel width as SL basis
      double lots = CalcSafeFLotSize(AccountInfoDouble(ACCOUNT_BALANCE), sl_distance);

      if (price >= upper) {
         // Breakout above the channel -> Buy signal
         // trade.Buy(lots, _Symbol, price, price - sl_distance, price + sl_distance * 2);
      } else if (price <= lower) {
         // Breakout below the channel -> Sell signal
         // trade.Sell(lots, _Symbol, price, price + sl_distance, price - sl_distance * 2);
      }
   }
}
Multifilter BreakoutEMARSIBollinger Bands

Multifilter Breakout: EMA + RSI + Bollinger Bands on XAU/EUR

Instrument: XAU/EUR (Gold vs Euro) · September 8, 2026

This paper designs a "Multifilter Breakout" EA that combines three indicators at once as a signal filter: Bollinger Bands (volatility and breakout levels), EMA (trend direction), and RSI (momentum strength). The idea: a single indicator alone triggers false signals easily; requiring all three to "agree" is meant to filter out that noise.

The EA was tested across two timeframes (H1 and H4) using 3 years of historical data (2022–2025), then validated with one month of real-time testing plus a T-Test for statistical significance.

The most important finding is the H1-vs-H4 dichotomy: the H1 scenario won decisively in backtesting but FAILED COMPLETELY in real-time. Conversely, the H4 scenario was weaker in simulation but proved robust and profitable in real-time.

The authors' conclusion: H4 is more viable to implement due to its superior stability, underscoring the indispensable role of real-time testing — backtesting alone can be misleading. This is a textbook case of overfitting: a strategy can "memorize" specific patterns in H1 historical data that don't repeat under new conditions.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: Multifilter Breakout EMA+RSI+Bollinger |
//| Signal only valid if ALL THREE indicators agree on direction     |
//+------------------------------------------------------------------+
input int    EMA_Period      = 50;
input int    RSI_Period      = 14;
input int    BB_Period       = 20;
input double BB_Deviation    = 2.0;
input double RSI_BullLevel   = 55.0;   // RSI threshold considered "bullish"
input double RSI_BearLevel   = 45.0;   // RSI threshold considered "bearish"

int emaHandle, rsiHandle, bbHandle;

int OnInit() {
   emaHandle = iMA(_Symbol, PERIOD_CURRENT, EMA_Period, 0, MODE_EMA, PRICE_CLOSE);
   rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
   bbHandle  = iBands(_Symbol, PERIOD_CURRENT, BB_Period, 0, BB_Deviation, PRICE_CLOSE);
   return INIT_SUCCEEDED;
}

void OnTick() {
   double ema[], rsi[], bbUpper[], bbLower[];
   CopyBuffer(emaHandle, 0, 0, 1, ema);
   CopyBuffer(rsiHandle, 0, 0, 1, rsi);
   CopyBuffer(bbHandle, 1, 0, 1, bbUpper);  // buffer 1 = upper band
   CopyBuffer(bbHandle, 2, 0, 1, bbLower);  // buffer 2 = lower band

   double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   bool trendUp   = price > ema[0];
   bool momentumUp = rsi[0] > RSI_BullLevel;
   bool breakoutUp = price > bbUpper[0];

   bool trendDown   = price < ema[0];
   bool momentumDown = rsi[0] < RSI_BearLevel;
   bool breakoutDown = price < bbLower[0];

   if (PositionsTotal() == 0) {
      if (trendUp && momentumUp && breakoutUp) {
         // trade.Buy(lotSize, _Symbol);
      } else if (trendDown && momentumDown && breakoutDown) {
         // trade.Sell(lotSize, _Symbol);
      }
   }
}
Trend-FollowingIchimoku CloudFibonacci Money Management

Fibonacci Money Management + Ichimoku Cloud on Crude Oil

Instrument: XTI/USD (Crude Oil) · September 8, 2026

This paper builds an EA that uses Ichimoku Cloud (a Japanese-origin indicator that shows trend, support/resistance, and momentum all at once) as the signal source, combined with a Fibonacci Money Management strategy for position sizing.

The EA was tested across two timeframe scenarios (H1 and H4): backtesting on 4 years of historical data (Jan 2021–Dec 2024), validated with one month of real-time testing (Aug 22–Sep 22, 2025).

The result is one of the clearest examples of overfitting you'll find: the H1 scenario was very profitable in backtesting (Profit Factor 1.46) but collapsed to a Profit Factor of 0.04 in real-time. The H4 scenario was more stable (PF 1.72) and stayed profitable in real-time too — but the sample size was just 1 trade over the whole month, clearly not enough to call it reliable.

A weakness the authors honestly admit: both scenarios only ever executed buy (long) positions — this system has never been tested against bearish or sideways market conditions.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: Ichimoku Cloud + Fibonacci Money Mgmt  |
//+------------------------------------------------------------------+
input int TenkanPeriod = 9;
input int KijunPeriod  = 26;
input int SenkouPeriod = 52;

// Fibonacci Money Management: lot size follows a Fibonacci ratio sequence
// (e.g. 0.618, 1, 1.618) off a base lot, scaled up/down by the last trade's result.
double fibSequence[] = {1.0, 1.0, 1.618, 2.618, 4.236};
int fibIndex = 0;

double CalcFibonacciLot(double baseLot, bool lastTradeWon) {
   if (lastTradeWon) fibIndex = 0;
   else fibIndex = MathMin(fibIndex + 1, ArraySize(fibSequence) - 1);
   return NormalizeDouble(baseLot * fibSequence[fibIndex], 2);
}

int ichimokuHandle;
int OnInit() {
   ichimokuHandle = iIchimoku(_Symbol, PERIOD_CURRENT, TenkanPeriod, KijunPeriod, SenkouPeriod);
   return INIT_SUCCEEDED;
}

void OnTick() {
   double tenkan[], kijun[], spanA[], spanB[];
   CopyBuffer(ichimokuHandle, 0, 0, 1, tenkan);
   CopyBuffer(ichimokuHandle, 1, 0, 1, kijun);
   CopyBuffer(ichimokuHandle, 2, 1, 1, spanA);
   CopyBuffer(ichimokuHandle, 3, 1, 1, spanB);

   double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   double cloudTop = MathMax(spanA[0], spanB[0]);

   bool aboveCloud   = price > cloudTop;
   bool tenkanCrossUp = tenkan[0] > kijun[0];

   if (PositionsTotal() == 0 && aboveCloud && tenkanCrossUp) {
      double lots = CalcFibonacciLot(0.01, true);
      // trade.Buy(lots, _Symbol);  // note: this paper only tested the Buy side
   }
}
Statistical/AdaptiveGARCH VolatilityReaction Trend SystemOpen-Source Code

RTS: Reaction Trend System with GARCH Volatility

Instrument: Stocks (example: BOVA11.SA) · September 8, 2026

Unlike the other four articles in this series, this paper is a scholarly publication in an Elsevier journal (Software Impacts) specifically dedicated to reproducible research code — the code is genuinely public on GitHub and Code Ocean under an MIT license.

The underlying strategy, Reaction Trend System (RTS), was originally proposed by J. Welles Wilder in 1978 (also the creator of RSI and ATR). RTS operates on 4 calculated Action Points that split market conditions into REACTION MODE (ranging/sideways) and TREND MODE (a clear uptrend or downtrend).

The paper's contribution: instead of fixed values for calculating those action points, the authors substitute quantiles from a GARCH volatility model (a Bayesian bivariate DCC-GARCH via the R library bayesDccGarch) — making the action points adaptive to current market volatility rather than rigid numbers.

The workflow spans two languages: R code estimates parameters (example in the paper: C_Trend=0.95 and C_Reaction=0.50) from historical data, then those parameters feed into an MQL5 Expert Advisor on MetaTrader 5 for actual execution. Because it's open-source, this is the only paper in this series whose results can genuinely be reproduced directly by anyone else.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: RTS framework with GARCH-adaptive      |
//| thresholds — C_Trend & C_Reaction are estimated separately in R  |
//+------------------------------------------------------------------+
input double C_Trend    = 0.95;  // GARCH quantile for TREND mode (from R output)
input double C_Reaction = 0.50;  // GARCH quantile for REACTION mode (from R output)
input int    MagicNumber = 20220054;

enum MarketMode { MODE_REACTION, MODE_TREND };
MarketMode currentMode = MODE_REACTION;

// Placeholder: in the original implementation, mode detection comes from
// historical Action Points (Wilder, 1978) compared against GARCH quantiles.
MarketMode DetectMarketMode() {
   // if (priceCrossedTrendActionPoint(C_Trend)) return MODE_TREND;
   return MODE_REACTION;
}

void OnTick() {
   currentMode = DetectMarketMode();

   if (currentMode == MODE_REACTION) {
      // REACTION mode: more frequent entries/exits following short-term
      // support/resistance bounces — threshold from the C_Reaction quantile.
   } else {
      // TREND mode: the EA lets positions ride the confirmed trend direction,
      // with a looser exit threshold (C_Trend).
   }

   // Wilder's "Phasing" technique (B/O/S) governs which days new trades may
   // open; this paper tested with that technique disabled (see the paper's
   // footnote: competitive results without it, and no proven statistical basis for it).
}
Arbitrage/HedgingCurrency CorrelationHigh-Risk Case Study

Triangle Hedging: A Currency-Pair-Correlation Trading Robot

Instrument: EURUSD/USDCHF, AUDUSD/USDCAD, GBPUSD/USDJPY · September 8, 2026

Unlike the other four articles, which are all about breakout/trend-following on a single instrument, this paper covers an entirely different family of strategy: Triangle Hedging — exploiting the stable correlation between THREE currency pairs at once to chase profit while offsetting risk through opposing positions.

Correlation analysis selected three stable, strongly-correlated combinations: EURUSD & USDCHF, AUDUSD & USDCAD, and GBPUSD & USDJPY. The robot was forward-tested (live on demo accounts, not just historical backtesting) across 4 separate demo accounts.

Results: Demo 1 gained 205.07% (43.52% drawdown), Demo 2 gained 91.57% (61.42% drawdown), Demo 3 gained 263.54% (60.12% drawdown), Demo 4 gained 170% (91.81% drawdown).

The gain figures look tempting, but the authors honestly admit: on drawdown, this method shows NO risk-control optimization whatsoever — all four demo accounts drew down above 50%, two of them above 90%. A drawdown that severe means the account nearly wiped out entirely before eventually turning a profit — on a real account, most traders would hit a margin call long before ever "recovering" to the flashy final gain number. Gain figures alone are never enough to judge a strategy without looking at risk metrics too.

Open the paper/source →
Inspect the MQL5 illustration
//+------------------------------------------------------------------+
//| EDUCATIONAL ILLUSTRATION: Correlation Divergence Detection for   |
//| Triangle Hedging — not a full replication of the risk logic      |
//+------------------------------------------------------------------+
input string PairA = "EURUSD";
input string PairB = "USDCHF";
input int    CorrelLookback = 50;      // bars used for rolling correlation
input double DivergenceThreshold = 2.0; // std-dev threshold considered "diverged"

// EURUSD-USDCHF historically tends to be strongly negatively correlated
// (both pairs involve USD moving in opposite directions).
double CalcRollingCorrelation(string symA, string symB, int bars) {
   double retA[], retB[];
   ArrayResize(retA, bars); ArrayResize(retB, bars);
   for (int i = 0; i < bars; i++) {
      retA[i] = iClose(symA, PERIOD_H1, i) - iClose(symA, PERIOD_H1, i + 1);
      retB[i] = iClose(symB, PERIOD_H1, i) - iClose(symB, PERIOD_H1, i + 1);
   }
   return PearsonCorrelation(retA, retB); // helper function, not shown
}

void OnTick() {
   double correlNow = CalcRollingCorrelation(PairA, PairB, CorrelLookback);
   double correlBaseline = -0.85; // illustration: this pair's "normal" historical correlation
   double deviation = MathAbs(correlNow - correlBaseline);

   if (deviation > DivergenceThreshold && PositionsTotal() == 0) {
      // Correlation has diverged from its norm -> a triangle hedging
      // opportunity: open opposing positions on both pairs, "betting" the
      // correlation reverts to normal (mean-reversion), not guessing direction.
      // trade.Buy(lotSize, PairA);
      // trade.Buy(lotSize, PairB); // direction adjusted to the pair's correlation sign
   }

   // NOTE: the logic above still includes no drawdown limiter/circuit-breaker
   // whatsoever — exactly the weakness the paper's own authors admit to.
}