Robot Example 2 – Martingale Money Management

2

This example adds Martingale-style position sizing to example 1, as NOT recommended by the Forex MegaDroid team!

Note that we have changed the default Profit Target and Stop Loss settings from the values used in example 1. If you plug these numbers into example 1 you will see that this results in that system losing money. Note also that adding position sizing to a losing system can turn it into a winning system. Imagine what a suitable position sizing method can do for a winning system. As long as you can survive the drawdowns, that is!

Here are the results from the MetaTrader strategy tester (but with the list of trades shortened):

Strategy Tester Report
GuruEx02
Symbol EURUSD (Euro vs US Dollar)
Period 1 Minute (M1) 2009.03.30 00:00 – 2009.05.01 22:59 (2009.03.30 – 2009.05.02)
Model Every tick (the most precise method based on all available least timeframes)
Parameters Magic=12345; Slippage=30; ProfitTarget=100; StopLoss=1000; Lots=0.01;
Bars in test 35815 Ticks modelled 953439 Modelling quality 25.00%
Mismatched charts errors 0
Initial deposit 500.00
Total net profit 242.52 Gross profit 848.75 Gross loss -606.23
Profit factor 1.40 Expected payoff 0.94
Absolute drawdown 364.40 Maximal drawdown 563.29 (80.60%) Relative drawdown 80.60% (563.29)
Total trades 257 Short positions (won %) 133 (89.47%) Long positions (won %) 124 (89.52%)
Profit trades (% of total) 230 (89.49%) Loss trades (% of total) 27 (10.51%)
Largest profit trade 134.00 loss trade -122.33
Average profit trade 3.69 loss trade -22.45
Maximum consecutive wins (profit in money) 43 (53.99) consecutive losses (loss in money) 2 (-132.55)
Maximal consecutive profit (count of wins) 141.99 (9) consecutive loss (count of losses) -132.55 (2)
Average consecutive wins 10 consecutive losses 1

Graph

# Time Type Order Size Price S / L T / P Profit Balance
1 2009.03.30 00:00 sell 1 0.01 1.32218 1.33236 1.32118
2 2009.03.30 07:08 t/p 1 0.01 1.32118 1.33236 1.32118 1.00 501.00
3 2009.03.30 07:08 sell 2 0.01 1.32076 1.33094 1.31976
4 2009.03.30 07:51 t/p 2 0.01 1.31976 1.33094 1.31976 1.00 502.00
5 2009.03.30 07:51 buy 3 0.01 1.31976 1.30958 1.32076
6 2009.03.30 08:05 t/p 3 0.01 1.32076 1.30958 1.32076 1.00 503.00
7 2009.03.30 08:05 sell 4 0.01 1.32103 1.33121 1.32003
8 2009.03.30 08:09 t/p 4 0.01 1.32003 1.33121 1.32003 1.00 504.00
9 2009.03.30 08:09 buy 5 0.01 1.32007 1.30989 1.32107
10 2009.03.30 08:15 t/p 5 0.01 1.32107 1.30989 1.32107 1.00 505.00
11 2009.03.30 08:15 buy 6 0.01 1.32153 1.31135 1.32253
12 2009.03.30 08:15 t/p 6 0.01 1.32253 1.31135 1.32253 1.00 506.00
13 2009.03.30 08:16 buy 7 0.01 1.32288 1.31270 1.32388
14 2009.03.30 09:01 t/p 7 0.01 1.32388 1.31270 1.32388 1.00 507.00
15 2009.03.30 09:01 sell 8 0.01 1.32385 1.33403 1.32285
16 2009.03.30 09:03 t/p 8 0.01 1.32285 1.33403 1.32285 1.00 508.00
17 2009.03.30 09:04 buy 9 0.01 1.32288 1.31270 1.32388
18 2009.03.30 15:50 s/l 9 0.01 1.31270 1.31270 1.32388 -10.18 497.82
19 2009.03.30 15:50 buy 10 0.12 1.31295 1.30277 1.31395
20 2009.03.30 16:01 t/p 10 0.12 1.31395 1.30277 1.31395 12.00 509.82
21 2009.03.30 16:01 sell 11 0.01 1.31405 1.32423 1.31305
22 2009.03.30 16:30 t/p 11 0.01 1.31305 1.32423 1.31305 1.00 510.82
23 2009.03.30 16:30 sell 12 0.01 1.31275 1.32293 1.31175
24 2009.03.30 16:32 t/p 12 0.01 1.31175 1.32293 1.31175 1.00 511.82
25 2009.03.30 16:32 sell 13 0.01 1.31130 1.32148 1.31030
26 2009.03.31 02:47 s/l 13 0.01 1.32148 1.32148 1.31030 -10.19 501.63
27 2009.03.31 02:47 buy 14 0.12 1.32178 1.31160 1.32278
28 2009.03.31 03:52 t/p 14 0.12 1.32278 1.31160 1.32278 12.00 513.63
29 2009.03.31 03:52 buy 15 0.01 1.32321 1.31303 1.32421
30 2009.03.31 03:56 t/p 15 0.01 1.32421 1.31303 1.32421 1.00 514.63
31 2009.03.31 03:56 sell 16 0.01 1.32422 1.33440 1.32322
32 2009.03.31 04:49 t/p 16 0.01 1.32322 1.33440 1.32322 1.00 515.63
33 2009.03.31 04:49 buy 17 0.01 1.32323 1.31305 1.32423
34 2009.03.31 05:17 t/p 17 0.01 1.32423 1.31305 1.32423 1.00 516.63
35 2009.03.31 05:17 buy 18 0.01 1.32461 1.31443 1.32561
36 2009.03.31 05:22 t/p 18 0.01 1.32561 1.31443 1.32561 1.00 517.63
37 2009.03.31 05:22 sell 19 0.01 1.32552 1.33570 1.32452
38 2009.03.31 06:20 t/p 19 0.01 1.32452 1.33570 1.32452 1.00 518.63
39 2009.03.31 06:20 buy 20 0.01 1.32457 1.31439 1.32557
40 2009.03.31 08:19 t/p 20 0.01 1.32557 1.31439 1.32557 1.00 519.63
41 2009.03.31 08:19 buy 21 0.01 1.32588 1.31570 1.32688
42 2009.03.31 09:50 t/p 21 0.01 1.32688 1.31570 1.32688 1.00 520.63
43 2009.03.31 09:50 buy 22 0.01 1.32722 1.31704 1.32822
44 2009.03.31 10:01 t/p 22 0.01 1.32822 1.31704 1.32822 1.00 521.63
45 2009.03.31 10:01 buy 23 0.01 1.32850 1.31832 1.32950
46 2009.03.31 11:37 t/p 23 0.01 1.32950 1.31832 1.32950 1.00 522.63
47 2009.03.31 11:37 buy 24 0.01 1.32978 1.31960 1.33078
48 2009.03.31 12:28 t/p 24 0.01 1.33078 1.31960 1.33078 1.00 523.63
49 2009.03.31 12:28 buy 25 0.01 1.33108 1.32090 1.33208
50 2009.03.31 12:42 t/p 25 0.01 1.33208 1.32090 1.33208 1.00 524.63
51 2009.03.31 12:42 buy 26 0.01 1.33247 1.32229 1.33347
52 2009.03.31 12:45 t/p 26 0.01 1.33347 1.32229 1.33347 1.00 525.63
53 2009.03.31 12:45 sell 27 0.01 1.33343 1.34361 1.33243
54 2009.03.31 13:24 t/p 27 0.01 1.33243 1.34361 1.33243 1.00 526.63
55 2009.03.31 13:24 buy 28 0.01 1.33247 1.32229 1.33347
56 2009.03.31 14:56 t/p 28 0.01 1.33347 1.32229 1.33347 1.00 527.63
57 2009.03.31 14:56 buy 29 0.01 1.33378 1.32360 1.33478
58 2009.03.31 18:30 s/l 29 0.01 1.32360 1.32360 1.33478 -10.18 517.45
59 2009.03.31 18:31 sell 30 0.12 1.32350 1.33368 1.32250
60 2009.04.01 02:14 t/p 30 0.12 1.32250 1.33368 1.32250 11.83 529.28
61 2009.04.01 02:14 buy 31 0.01 1.32239 1.31221 1.32339
62 2009.04.01 12:04 t/p 31 0.01 1.32339 1.31221 1.32339 1.00 530.28
63 2009.04.01 12:04 sell 32 0.01 1.32341 1.33359 1.32241
64 2009.04.01 16:58 t/p 32 0.01 1.32241 1.33359 1.32241 1.00 531.28
65 2009.04.01 16:58 sell 33 0.01 1.32210 1.33228 1.32110
66 2009.04.01 17:31 t/p 33 0.01 1.32110 1.33228 1.32110 1.00 532.28
67 2009.04.01 17:31 buy 34 0.01 1.32107 1.31089 1.32207
68 2009.04.01 17:41 t/p 34 0.01 1.32207 1.31089 1.32207 1.00 533.28
69 2009.04.01 17:41 sell 35 0.01 1.32205 1.33223 1.32105
70 2009.04.01 17:47 t/p 35 0.01 1.32105 1.33223 1.32105 1.00 534.28
71 2009.04.01 17:47 buy 36 0.01 1.32105 1.31087 1.32205
72 2009.04.01 17:54 t/p 36 0.01 1.32205 1.31087 1.32205 1.00 535.28
73 2009.04.01 17:55 sell 37 0.01 1.32200 1.33218 1.32100
74 2009.04.01 18:51 t/p 37 0.01 1.32100 1.33218 1.32100 1.00 536.28
75 2009.04.01 18:51 sell 38 0.01 1.32077 1.33095 1.31977
76 2009.04.01 20:12 t/p 38 0.01 1.31977 1.33095 1.31977 1.00 537.28
77 2009.04.01 20:12 sell 39 0.01 1.31942 1.32960 1.31842
78 2009.04.02 08:14 s/l 39 0.01 1.32960 1.32960 1.31842 -10.22 527.06
79 2009.04.02 08:14 sell 40 0.12 1.32944 1.33962 1.32844
80 2009.04.02 08:46 t/p 40 0.12 1.32844 1.33962 1.32844 12.00 539.06
81 2009.04.02 08:46 sell 41 0.01 1.32794 1.33812 1.32694
82 2009.04.02 09:15 t/p 41 0.01 1.32694 1.33812 1.32694 1.00 540.06
83 2009.04.02 09:15 sell 42 0.01 1.32660 1.33678 1.32560
84 2009.04.02 09:20 t/p 42 0.01 1.32560 1.33678 1.32560 1.00 541.06
85 2009.04.02 09:20 sell 43 0.01 1.32520 1.33538 1.32420
86 2009.04.02 12:21 s/l 43 0.01 1.33538 1.33538 1.32420 -10.18 530.88
87 2009.04.02 12:22 sell 44 0.12 1.33520 1.34538 1.33420
88 2009.04.02 13:32 t/p 44 0.12 1.33420 1.34538 1.33420 12.00 542.88
89 2009.04.02 13:32 buy 45 0.01 1.33414 1.32396 1.33514
90 2009.04.02 13:45 t/p 45 0.01 1.33514 1.32396 1.33514 1.00 543.88
91 2009.04.02 13:45 sell 46 0.01 1.33559 1.34577 1.33459
92 2009.04.02 13:49 t/p 46 0.01 1.33459 1.34577 1.33459 1.00 544.88
93 2009.04.02 13:49 sell 47 0.01 1.33411 1.34429 1.33311
94 2009.04.02 14:40 s/l 47 0.01 1.34429 1.34429 1.33311 -10.18 534.70
95 2009.04.02 14:40 buy 48 0.12 1.34467 1.33449 1.34567
96 2009.04.02 14:41 t/p 48 0.12 1.34567 1.33449 1.34567 12.00 546.70
97 2009.04.02 14:41 sell 49 0.01 1.34601 1.35619 1.34501
98 2009.04.02 14:41 t/p 49 0.01 1.34501 1.35619 1.34501 1.00 547.70
99 2009.04.02 14:41 buy 50 0.01 1.34506 1.33488 1.34606

Here's the source code for the "robot":

//+------------------------------------------------------------------+
//|                                                     GuruEx02.mq4 |
//|     Copyright © 2009, Marketing Dreams Ltd. All Rights Reserved. |
//|                                         http://trading-gurus.com |
//|                                                                  |
//| GuruTrader™ example 2                                            |
//| Version 1.10                                                      |
//|                                                                  |
//| Adds Martingale style position sizing to example 1               |
//|                                                                  |
//| Wealth Warning! This expert is for educational purposes only.    |
//| It should NEVER be used on a live account. Past performance is   |
//| in no way indicative of future results!                          |
//+------------------------------------------------------------------+
//+ Revision History                                                 +
//+                                                                  +
//+ 1.10 - May 21st 2009                                             +
//+        Added display of stop level.                              +
//+        Added support for STP mode.                               +
//+        Gets around a "feature" of Boston Technologies FIFO       +
//+        implementation which rejects market orders with non-zero  +
//+        stop-loss/take-profit levels.                             +
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Marketing Dreams Ltd."
#property link      "http://trading-gurus.com"
#define SLEEP_OK     250
#define SLEEP_ERR    250
//---- input parameters
extern int     Magic = 12346;
extern int     Slippage = 30;
extern int     ProfitTarget = 100;
extern int     StopLoss = 1000;
extern double  Lots = 0.1;
extern bool    StpMode = TRUE;

//---- static variables
static int     Dig;
static int     Stops;
static double  Points;
static double  ProfitPerPip;

static bool    Initialized = FALSE;
static bool    Running = FALSE;
static int     OrderNumber;
static double  PositionSize;
static double  LastBid;
static double  LastAsk;
static color   clBuy = DodgerBlue;
static color   clSell = Crimson;
//+------------------------------------------------------------------+
//| Utility functions                                                |
//+------------------------------------------------------------------+
#include <stdlib.mqh>
#include <stderror.mqh>
#include <WinUser32.mqh>
//+------------------------------------------------------------------+
//| Expert helper functions                                 |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Calculates a Martingale style position size                      |
//+------------------------------------------------------------------+
double MartingaleSize()
{
   int Index, Size;
   double Loss;

   Size = 1;
   Loss = 0;

   for (Index = OrdersHistoryTotal() - 1; Index >= 0; Index--) {
      OrderSelect(Index, SELECT_BY_POS, MODE_HISTORY);
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Magic)) {
         if (OrderProfit() <= 0) {
            Loss = Loss - OrderProfit();  // Add up our previous losses
            Size = 1 + MathRound(0.5 + Loss / (ProfitPerPip * Lots * ProfitTarget));
         }
         else {
            break;                        // Found a profitable trade, so we're all done
         }

      }
   }
   Print("Loss = ", Loss, ", Size = ", Size);
   return (Lots * Size);
}

//+------------------------------------------------------------------+
//| Places an order                                                  |
//+------------------------------------------------------------------+
int Order(string symbol, int Type, double Entry, double Quantity,
          double TargetPrice, double StopPrice, string comment="")
{
   string TypeStr;
   color  TypeCol;
   int    ErrorCode, Ticket;
   double Price, FillPrice;

   Price = NormalizeDouble(Entry, Dig);

   switch (Type) {
      case OP_BUY:
         TypeStr = "BUY";
         TypeCol = clBuy;
         break;
      case OP_SELL:
         TypeStr = "SELL";
         TypeCol = clSell;
         break;
      default:
         Print("Unknown order type ", Type);
         break;
   }

   if (StpMode) {
      Ticket = OrderSend(symbol, Type, Quantity, Price, Slippage,
               0, 0, comment, Magic, 0, TypeCol);
   }
   else {
      Ticket = OrderSend(symbol, Type, Quantity, Price, Slippage,
               StopPrice, TargetPrice, comment, Magic, 0, TypeCol);
   }
   if (Ticket >= 0) {
      Sleep(SLEEP_OK);
      if (OrderSelect(Ticket, SELECT_BY_TICKET) == TRUE) {
         FillPrice = OrderOpenPrice();
         if (Entry != FillPrice) {
            RefreshRates();
            Print("Slippage on order ", Ticket, " - Requested = ",
                  Entry, ", Fill = ", FillPrice, ", Current Bid = ",
                  Bid, ", Current Ask = ", Ask);
         }
         if (StpMode && ((StopPrice > 0) || (TargetPrice > 0))) {
            if (OrderModify(Ticket, FillPrice, StopPrice, TargetPrice, 0, TypeCol)) {
               Sleep(SLEEP_OK);
               return (Ticket);
            }
   	   }
      }
      else {
         ErrorCode = GetLastError();
         Print("Error selecting new order ", Ticket, ": ",
               ErrorDescription(ErrorCode), " (", ErrorCode, ")");
      }
      return (Ticket);
   } 	

   ErrorCode = GetLastError();
   RefreshRates();
   Print("Error opening ", TypeStr, " order: ", ErrorDescription(ErrorCode),
         " (", ErrorCode, ")", ", Entry = ", Price, ", Target = ",
         TargetPrice, ", Stop = ", StopPrice, ", Current Bid = ", Bid,
         ", Current Ask = ", Ask);
   Sleep(SLEEP_ERR);

   return (-1);
}

//+------------------------------------------------------------------+
//| Performs system initialisation                                   |
//+------------------------------------------------------------------+
void InitSystem()
{
   Running = FALSE;

   PositionSize = MartingaleSize();

   RefreshRates();
   LastBid = Bid;
   LastAsk = Ask;

   Initialized = TRUE;
}

//+------------------------------------------------------------------+
//| Checks for entry to a trade                                      |
//+------------------------------------------------------------------+
int CheckEntry(double Size)
{
   if (Ask > LastAsk) {  // Short term uptrend so GO LONG!
      OrderNumber = Order(Symbol(), OP_BUY, Ask, Size, Ask + (Points * ProfitTarget), Bid - (Points * StopLoss));
      if (OrderNumber > 0)
         return(1);
   }
   else if (Bid < LastBid) {  // Short term downtrend so GO SHORT!
      OrderNumber = Order(Symbol(), OP_SELL, Bid, Size, Bid - (Points * ProfitTarget), Ask + (Points * StopLoss));
      if (OrderNumber > 0)
         return(1);
   }
   return(0);
}

//+------------------------------------------------------------------+
//| Checks for exit from a trade                                     |
//+------------------------------------------------------------------+
int CheckExit()
{
   int ErrorCode;

   if (OrderSelect(OrderNumber, SELECT_BY_TICKET) != TRUE) {
      ErrorCode = GetLastError();
      Print("Error selecting order ", OrderNumber, ": ", ErrorDescription(ErrorCode), " (", ErrorCode, ")");
      return(-1);
   }
   else if (OrderCloseTime() > 0) {
      Print("Order ", OrderNumber, " closed: ", OrderClosePrice(), ", at ", TimeToStr(OrderCloseTime()));
      return(1);
   }
   else {
      return(0);
   }
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
   Dig = MarketInfo(Symbol(), MODE_DIGITS);
   Points = MarketInfo(Symbol(), MODE_POINT);
   Stops = MarketInfo(Symbol(), MODE_STOPLEVEL);
   ProfitPerPip = 100000 / MathPow(10, Dig);

   Print("Profit per pip per lot = ", ProfitPerPip, ", Stops = ", Stops, ", Digits = ", Dig, ", Points = ", DoubleToStr(Points, 5));

   if (!IsDemo() && !IsTesting()) {
      MessageBox("Wealth Warning! This expert is for educational purposes only." +
            " It should NEVER be used on a live account." +
            " Past performance is in no way indicative of future results!");
      Print("Initialization Failure");
      return(-1);
   }

   InitSystem();

   Print("Initialized OK");

   return(0);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{
    Print("DeInitialized OK");

    return(0);
}

//+------------------------------------------------------------------+
//| Expert start function                                            |
//| Executed on every tick                                           |
//+------------------------------------------------------------------+
int start()
{
   if (!Initialized) {
      return(-1);
   }
   else if (Running) {                    // Are we in a trade at the moment?
      if (CheckExit() > 0) {              // Yes - Last trade complete?
         Initialized = FALSE;             // Yes - Indicate we need to reinitialise
         InitSystem();                    //  and start all over again!
      }
   }
   else {
      if (CheckEntry(PositionSize) > 0) {         // Entered a trade?
         Running = TRUE;                  // Yes - Indicate that we're in a trade
      }
   }
   return(0);
}

You can also download the source code here.

Pings on Robot Example 2 – Martingale Money Management

June 2, 2009

Comments on Robot Example 2 – Martingale Money Management Leave a Comment

May 22, 2009

Jim @ 7:41 am #

On May 21st 2009 we released version 1.10. (We're following the Forex Megadroid in our version numbers!)

This version now displays the broker's stop level on startup. More importantly it also introduces the new StpMode input parameter. This should normally be set to "false". At the moment though, you need to set it to 'true' for FXCM, MB Trading, and quite possibly other brokers who use Boston Technologies "Straight Through Processing" version of MetaTrader 4.

Leave a Comment

Fields marked by an asterisk (*) are required.