Expert Advisors • Indicators • Scripts • Libraries

MQL.RobotFX.org is the biggest collection of MetaTrader expert advisors (MT5 & MT4), indicators, scripts and libraries that can be used to improve trading results, minimize risks or simply automate trading tasks

Metatrader 5 Libraries | CSetupLedger: a per-setup win rate ledger for Expert Advisors | MQL5 Code

Discover expert developed MetaTrader tools that can complement professional solutions.

Why I wrote it

My scalper trades two setups. A bullish order block and the bearish mirror of it. The Strategy Tester gave me one profit factor for both of them. I spent two weeks tuning inputs that applied to each setup equally.

Then I split the trades by setup type. On USDCAD M1 the bullish side had caused 88 percent of the loss. The bearish side was close to flat. The number I needed had been sitting in my own trade history the whole time. I just had no way to read it.

This class reads it.

Recover from drawdowns intelligently with the Auto Recovery Expert Advisor for MT4/MT5. Perfect for hedging strategies. Learn more.

What it gives you

You register your setup types once at startup. Each one gets an id back. That id is added to your magic number base so every order carries its own setup tag from the moment it is sent.

After that the ledger answers three questions for each setup. How many wins and losses. What the net result was after swap and commission. And whether the win rate has earned any trust yet.

That last question is the one I built this for. Three wins from three trades is a 100 percent win rate. It is also what a coin that lands heads 44 percent of the time manages about once in twelve attempts. So the class prints a Wilson score lower bound beside the raw rate and checks it against the breakeven win rate your reward ratio demands. At 1:2 that bar sits at 33.3 percent. A setup only reads as trusted when even its pessimistic rate clears the bar. Early on everything reads "not yet trusted". That is the honest answer when you have twenty trades.

Using it

#include <CSetupLedger.mqh>

CSetupLedger ledger;
int SETUP_BULL, SETUP_BEAR;

int OnInit()
  {
   ledger.Init(552001);                          // your magic base
   SETUP_BULL = ledger.Register("Bullish OB");   // id 0 -> magic 552001
   SETUP_BEAR = ledger.Register("Bearish OB");   // id 1 -> magic 552002

   ledger.RebuildFromHistory();                  // read the record off the account
   Print(ledger.Report(2.0));                    // 2.0 = reward-to-risk ratio
   return INIT_SUCCEEDED;
  }

Stamp the setup onto the trade before the order goes out.

trade.SetExpertMagicNumber((ulong)ledger.MagicFor(SETUP_BULL));

Fold the position in once it closes.

double net = 0.0;
if(ledger.ProcessClosedPosition(posId, setupId, net))
   Print(ledger.Report(2.0));

Report()

Per-setup ledger  (breakeven win rate at 1:2.0 = 33.3%)
---------------------------------------------------------------------
Bullish OB         235/529  raw  30.8%  wilson  27.6%  net  -5819.94  not yet trusted
Bearish OB         191/393  raw  32.7%  wilson  29.0%  net   -811.42  not yet trusted

Image for CSetupLedger: a per-setup win rate ledger for Expert Advisors

The same report passed to

The counts are wins over losses. So that is 764 trades on the bullish setup and 584 on the bearish one. Both nets add back to the tester's own net loss to the cent. Run that reconciliation on your own output before you trust any ledger including this one. If the per-setup trades do not sum to the tester's trade count then positions are being miscounted and every percentage above that line is worthless.

Three traps it handles for you

Hand written versions of this usually get these wrong. I got two of them wrong myself before this class existed.

Deals are not trades. MT5 history is a list of deals. A position closed in three parts produces three OUT deals. Loop over deals and count each profitable one as a win and a single winning trade becomes three wins. The ledger aggregates by

DEAL_PROFIT

POSITION_TICKET

The one rule you must not break

Registration order is a data format. The setup id lives nowhere except inside the magic numbers of trades that have already closed. Insert a new setup in the middle of the list next month and every historical trade of the setup that used to hold that id silently becomes a trade of the new one. Nothing throws an error. The numbers are simply wrong from then on.

New setups go at the end of the list. If you retire a setup then leave its

What it will not do

It keeps one record per position. An EA that stacks a second entry into the same netting position will credit the whole thing to the first setup. If yours does that it needs a per-deal model instead.

Sixteen setups is the ceiling. Raise

A net result of exactly zero counts as a loss. Scratch trades are rare and treating them as wins is the more flattering error.

ProcessClosedPosition()

And it measures your exits rather than your idea. A setup that reads direction correctly but places its stop badly scores as a bad setup. For deciding what to trade tomorrow that is arguably the right answer. It is not the same as judging whether the idea was sound.

Requirements

MetaTrader 5. No dependencies beyond the standard library. Drop the file in

One last thing. A ledger built on a single in sample backtest measures that backtest. It does not validate a strategy. Out of sample testing on a period you never tuned on is a separate job and this class does not replace it.

— Ali Rajput


Build better strategies with RobotFX professional tools – check them out.

77531

Best MetaTrader Indicators + Profitable Expert Advisors