Robot Example 2 – Martingale Money Management
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):
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 |
# | 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.
Leave a Comment
Pings on Robot Example 2 – Martingale Money Management
Comments on Robot Example 2 – Martingale Money Management
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.