15
Сен
2011

Мартингейл в торговле на Форекс




Метод мартингейла в торговле на Форекс в различных своих вариациях всегда привлекал, привлекает и будет привлекать в будущем своей внушающей ожидаемой доходностью. Метод первоначально предназначался для игры в казино. Мартингейл основан на принципе удвоения ставки в случае проигрыша. При выигрыше ставка возвращается к первоначальному значению. Теоретически мартингейл – это беспроигрышный метод. Действительно, при увеличении числа игр вероятность хотя бы одного выигрыша растет. Шансы выиграть или проиграть в одной игре равны и составляют по 50%.

Мартингейл в торговле на Форекс

В то же время, мартингейл подразумевает наличие у игрока определенной крупной суммы денег, поскольку каждый следующий проигрыш требует средства для удвоения ставки. Например, первая ставка 1 доллар. В случае серии проигрышей размер последующих ставок составит: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, … долларов. Таким образом, серия из 10 подряд следующих проигрышей потребует наличия у игрока суммы в 1+2+4+8+16+32+64+128+256+512+1024 = 2047 долларов. В случае выигрыша на 11 ходу игрок в рулетку получит в качестве выигрыша удвоенную ставку, т.е. 2048 долларов, выиграв фактически всего 1 доллар рискуя при этом суммой в 2047 долларов. Как вы думаете, стоил ли этот результат такого риска?

Стоило ли игроку рисковать суммой в 2047 долларов ради выигрыша 1 доллара по системе мартингейла?

Просмотр результатов

Loading ... Loading ...

Казалось бы, мартингейл это беспроигрышный метод, при котором рискуя большой суммой, всегда можно “гарантированно” получить маленький выигрыш. Размер выигрыша независимо от порядкового номера игры в серии всегда определяется размером первоначальной ставки.

Ну, что-то мы все про казино… Применительно к торговле на рынке Форекс классический метод мартингейла подразумевает удвоение лота каждой последующей сделки в случае убыточной предыдущей сделки. В случае закрытия прибыльной сделки размер лота становиться равным исходному. Например, мы открыли позицию на покупку (BUY) с объемом лота 0.01. В случае закрытия этой сделки с убытком мы увеличим лот следующей сделки в два раза, т.е. следующую позицию открываем уже лотом 0.02. Если опять убыток, то следующий ордер уже открываем с лотом 0.04, следующий – 0.08, затем – 0.16 и т.д. до закрытия профитного (прибыльного) ордера. После этого первая сделка следующей серии опять открывается с размером лота 0.01.

А вот о чем говорили по поводу метода мартингейла на телеканале РБК:

И еще доводы (весьма, кстати, неконкретные) против метода мартингейла. Правда, автор говорит, что комбинированные торговые системы показывают неплохие результаты:

Действительно, метод мартингейла может быть неплохим подспорьем, но только, как говорится, в умелых руках. Но, впрочем, об этом чуть позже, а сейчас давайте посмотрим на советник, который мы написали специально для этого поста:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//+------------------------------------------------------------------+
//|                                                   Martingale.mq4 |
//|                              Copyright © 2011, MoneyInNetwork.ru |
//|                                         http://moneyinnetwork.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, MoneyInNetwork.ru"
#property link      "http://moneyinnetwork.ru"
extern string s1 = "Объем лота для первой сделки серии";
extern double Lot = 0.01;
extern string s2 = "Уровень стоп-лосса, в пунктах";
extern double stoploss = 21;
extern string s3 = "Уровень тейк-профита, в пунктах";
extern double takeprofit = 84;
extern string s4 = "Уникальная метка для ордеров, открываемых только этим советником";
extern double MagicNumber = 600;
extern string s5 = "Максимальное отклонение от запрошенной цены, в пунктах";
extern double slip = 3;
extern string s6 = "Период скользящей средней, в барах (количество свечей для расчета средней)";
extern int per = 55;
 
int init()
{
   return(0);
}
 
int deinit()
{
   return(0);
}
 
int start()
{ 
  //инициализация параметров
  bool flag = false;
  int ticket = 0;
  double lots = Lot;
 
  //проверяем наличие торгового сигнала
  int signal1 = alert1();
  //ищем среди всех открытых ордеров открытый советником ордер 
  for ( int trade = OrdersTotal() - 1; trade >= 0; trade-- ) 
  {
      //проверяем есть ли среди всех открытых ордеров именно тот ордер, который открыт данным советником.
      //ВНИМАНИЕ! MagicNumber - должен быть свой для каждого советника!
      if ( OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) && (OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
      {
            flag = true; //значение флага наличия ордера - ордер открыт
            break; //закончим поиск
      }        
  }
  //ордер открыт и пришел новый торговый сигнал
  if ( flag && signal1!=-1 )
  {
      //проверяем тип ордера (BUY или SELL) и закрываем его по соответствующей цене
      if ( OrderType() == OP_BUY && signal1==OP_SELL )
      {
          //если ордер BUY, то закрываем его по цене Bid
          if (OrderClose(OrderTicket(), OrderLots(), Bid, slip, Green) ) 
              //если сделка закрыта, то разрешаем советнику опять открывать сделки по торговому сигналу на следующем шаге
              flag = false;
      }
      if ( OrderType() == OP_SELL && signal1==OP_BUY ) 
      {
          //если ордер SELL, то закрываем его по цене Ask
          if (OrderClose(OrderTicket(), OrderLots(), Ask, slip, Red) ) 
              //если сделка закрыта, то разрешаем советнику опять открывать сделки по торговому сигналу на следующем шаге
              flag = false;
      }    
  }
  //нет открытых ордеров
  if ( !flag )
  {
       //ищем в истории закрытых ордеров последний закрытый советником ордер 
       for ( trade = OrdersHistoryTotal() - 1; trade >= 0; trade-- ) 
       {
           if ( OrderSelect(trade, SELECT_BY_POS, MODE_HISTORY) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
           {
               if ( OrderProfit()>=0 ) lots = Lot; //последний закрытый советником ордер был прибыльным или безубыточным, значит, следующий ордер открывает с начальным лотом
                    else lots = 2*OrderLots(); //последний закрытый советником ордер был убыточным, значит следующий ордер открываем удвоенным лотом
               break; //прекращаем поиск
           }
       }
       //сигнал на продажу - продаем
       if ( signal1 == OP_SELL )
       {
            ticket = OrderSend(Symbol(), OP_SELL, NormalizeDouble(lots,2),  NormalizeDouble(Bid, Digits), slip, NormalizeDouble(Ask+stoploss*Point, Digits), NormalizeDouble(Ask-takeprofit*Point, Digits), "Martingale-Sell", MagicNumber, 0, Red);
            Sleep (1000); //задержка в одну секунду для обрабатки запроса торговым сервером брокера
            return (0);  
       }
       //сигнал на покупку - покупаем
       if ( signal1 == OP_BUY )
       {
            ticket = OrderSend(Symbol(), OP_BUY, NormalizeDouble(lots,2), NormalizeDouble(Ask, Digits), slip, NormalizeDouble(Bid-stoploss*Point, Digits), NormalizeDouble(Bid+takeprofit*Point, Digits), "Martingale-Buy", MagicNumber, 0, Green);
            Sleep (1000); //задержка в одну секунду для обрабатки запроса торговым сервером брокера
            return (0);  
        }               
  }
  return (0);  
}
 
int alert1() 
{
   int signal=-1; //нет торгового сигнала
   //получение параметра от индикатора скользящей средней
   double ma1 = iMA(Symbol(),Period(), per, 0, 0, 0, 1);
   //скользящая средняя пробита ценой снизу вверх - покупаем
   if ( iOpen(Symbol(), Period(), 1)<ma1 && iClose(Symbol(), Period(), 1)>ma1 ) signal = OP_BUY;
   //скользящая средняя пробита ценой сверху вниз - продаем
   if ( iOpen(Symbol(), Period(), 1)>ma1 && iClose(Symbol(), Period(), 1)<ma1 ) signal = OP_SELL;
   return (signal); //возвращаем торговый сигнал 
}

Этот торгующий Форекс советник, написанный на языке программирования MQL4, реализует классический метод мартингейла, о котором мы говорили выше. Для открытия позиции может использоваться один из индикаторов. В данном случае мы, например, используем индикатор скользящей средней, при пробое которой ценой снизу открываем ордер на покупку (BUY), а при пробое скользящей средней сверху – позицию на продажу (SELL). Советник можно потестить на таймфреймах M1 – D1. Результаты тестов при подборе определенных параметров весьма впечатляют. Как вы можете видеть из рисунка, советник на тесте за 8 месяцев текущего года “разогнал депозит” из 100 до 1300 долларов при объеме лот первой сделки серии равном 0.01, при этом просадка превысила 70%.

Результаты работы советника Мартингейл на таймфрейме H1 в период с 1 января 2011 г. по 1 сентября 2011 г.

Рис.1 Результаты работы советника “Мартингейл” на таймфрейме H1 в период с 1 января 2011 г. по 1 сентября 2011 г.
Исходные данные:
Брокер – InstaForex
Таймфрейм – H1
Период тестирования – с 01.01.2011 по 01.09.2011
Начальный депозит – $100
Модель – все тики
Настройки советника – Lot = 0.01; stoploss = 21; takeprofit = 84; slip = 3; per = 55.

Радоваться не стоит. Оптимизированный на истории Форекс советник абсолютно не гарантирует вам прибыли на другом временном интервале, отличном от интервала оптимизации параметров. В чем вы можете убедиться, задав другой период тестирования в тестере стратегий торгового терминала MetaTrader4.

О том как оптимизировать советники мы уже писали в посте “Прибыльные советники Форекс – это миф или реальность?“. Отметим сразу, что советники, использующие для входа в рынок пробой скользящей средней, дают особенно много ложных сигналов при флэте:

Флэт – боковое движение, ситуация на рынке, при которой цена ни повышается, ни падает или, как еще говорят, цена колеблется в узком диапазоне.

Часть таких сигналов можно попытаться отсеять используя специальные фильтры (например, оценивать текущую волотильность), но в нашем простом советнике мы не используем никаких фильтров. Кроме того, фильтр может отсеять и весьма полезный сигнал, что значительно повлияет на прибыльность советника в целом. Но, впрочем, на индикаторах и фильтрах останавливаться не будем, поскольку это обширная тема, выходящая далеко за рамки данной статьи.

Обратите внимание, что советник ограничивает убыток путем выставления уровня стоп-лосс для каждого открываемого ордера. Фиксация прибыли производится на уровне тейк-профит. В тоже время, советник также закрывает открытые ордера (с убытком или прибылью) и по новому торговому сигналу, отличному от того, по которому был открыт текущий ордер. При работе советника следует отрабатывать каждый торговый сигнал.

В “чистом виде” при торговле на Форекс, как правило, метод мартингейла в основном не используется, а если и используется, то только излишне рисковыми авантюристами, поскольку слить депозит практически любого объема можно очень быстро (в этом вы убедитесь протестировав советник). Для этого достаточно всего лишь нескольких убыточных сделок и размер лота достигнет такого значения, что остатки депозита улетучатся сразу же при движении цены на несколько пунктов против направления сделки. Именно поэтому широкое применение получили, так называемые модифицированные методы мартингейла. Все они, так или иначе, связаны с повышением лот нового открываемого ордера при наличии ордера закрытого с убытком. Например, широкое применение нашел метод основанный, на повышении лот с использованием последовательности Фибоначчи (числа Фибоначчи – ряд, где каждое следующее число равно сумме двух предыдущих чисел). Для целых чисел ряд Фибоначчи принимает вид:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, …

Применительно для Форекс, например, при объеме первой сделки 0.01 лот последовательность Фибоначчи примет следующий вид:

0.01, 0.01, 0.02, 0.03, 0.05, 0.08, 0.13, 0.21, 0.34, 0.55, 0.89, 1.44, 2.33, 3.77, 6.10…

Такая последовательность обеспечивает несколько большую “продолжительность жизни” депозиту в случае серии убыточных сделок.

Наибольшее распространение среди модифицированных методов мартингейла получил, так называемый, метод усреднения.

Усреднение – вариант торговли, при котором происходит усиление убыточной позиции в надежде на откат цены, при котором возможно будет закрыть все открытые позиции с общей прибылью, независимо от наличия ряда убыточных ордеров в серии. Опасность усреднения заключается в том, что цена может безоткатно двигаться против направления серии сделок. Применение метода усреднения возможно только при наличии запаса депозита на большую ожидаемую просадку. Однако, как показывает практика, при безоткатных движениях на сильных трендах механические торговые системы, основанные исключительно на методе усреднения, сливают весь депозит.

Чтобы вам было понятно приведем следующий пример усреднения на примере двух ордеров. Допустим, что по сигналу индикатора мы открыли ордер на покупку при цене 1.3600, объемом 1 лот, выставив тейк-профит на уровень 1.3650 (тейк-профит на 50 пунктов). Однако, цена упала на 200 пунктов до значения 1.3400. В надежде на откат цены мы открываем еще один ордер на покупку объемом 2 лот. Теперь мы должны рассчитать на какой уровень следует перенести тейк-профит для этих двух сделок, чтобы закрыться в профите. Произведем расчет уровня переноса тейкпрофита по формуле:

TPbuy = (L1*C1+L2*C2)/(L1+L2)+TPp*Point,
где L1, L2 – объемы лот первого и второго ордеров; C1, C2 – цены открытия первого и второго ордеров; TPp – размер тейк-профита в пунктах; Point – коэффициент приведения целого числа пунктов к абсолютным котировкам (для четырехзначных котировок коэффициент равен 0.0001, а для пятизначных – 0.00001).

Подставив исходные значения, получим:

TP = (1*1.3600+2*1.3400)/(1+2)+50*0.0001=1.3517

Переносим теперь уровень тейк-профит для каждой из этих сделок на отметку 1.3517. Допустим, через некоторое время сделки закрылись по тейк-профиту. В результате мы имеем убыток по первому открытому ордеру в 83 пункта и прибыль в размере 2*117=234 пункта по второму открытому ордеру. Тогда наша суммарная прибыль составит: 234-83= 151 пункт. Однако, такой исход возможен только при наличии отката цены. А теперь представьте, что отката нет… В надежде на откат цены нам придется докупаться каждый раз при прохождении ценой определенного расстояния и каждый раз переносить тейк-профит каждого открытого ордера серии в точку прибыльности. Конечно, при движении цены не в нашу сторону, мы можем переносить тейк-профит и в точку безубыточности, предварительно ее рассчитав, что повысит шансы закрыть все сделки хотя бы без потери депозита. Однако при образовании сильного тренда против направления наших позиций, депозит также будет слит. Кстати, для сделок на продажу формула прибыльного усреднения может принимать следующий вид:

TPsell = (L1*C1+L2*C2)/(L1+L2)-TPp*Point

Точку безубыточности можно рассчитать, если TPp приравнять нулю. Тогда формула расчета точки безубыточности для любого вида серий (BUY или SELL) примет вид:

TPnull = (L1*C1+L2*C2)/(L1+L2)

А теперь от теории к практике. Предлагаем вашему вниманию торгующий форекс советник, основанный на методе усреднения. Сигналом к открытию позиций будет служить все тот же пробой скользящей средней, что применялся в советнике, торгующем по классическому методу мартингейла. От метода мартингейла здесь осталась только основа – повышение лота каждой следующей сделки. При прохождении ценой определенного расстояния против направления первой и последующих позиции мы будем открывать новые сделки в направлении первой сделки серии, каждый раз повышая лот на определенный коэффициент. В советнике даны некоторые пояснения, так что в нем будет несложно разобраться:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//+------------------------------------------------------------------+
//|                                             Modif_Martingale.mq4 |
//|                              Copyright © 2011, Moneyinnetwork.ru |
//|                                         http://moneyinnetwork.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, Moneyinnetwork.ru"
#property link      "http://moneyinnetwork.ru"
 
extern string s1 = "Объем лота для первой сделки серии";
extern double Lot = 0.01;
extern string s2 = "Коэффициент повышения объема лот для каждого последующего ордера по отношению к предыдущему";
extern double Klots = 1.2;
extern string s3 = "Уровень тейк-профита, в пунктах";
extern double takeprofit = 129;
extern string s4 = "Размер колена при движении цены против направления серии, в пунктах";
extern double steppips = 18;
extern string s5 = "Период скользящей средней, в барах (количество свечей для расчета средней)";
extern int per = 16;
extern int maxtrades = 10;
extern string s6 = "Максимальное отклонение от запрошенной цены, в пунктах";
extern double slip = 3;
extern string s7 = "Уникальная метка для ордеров, открываемых только этим советником";
extern double MagicNumber = 100;
 
int init()
  {
   return(0);
  }
int deinit()
  {
   return(0);
  }
 
int start()
{
  bool flag=false;
  int numtrades = 0, ticket=0, lasttype=-1;
  double alllots = 0, sum = 0;
  double tp, lastprice, lastlot;
  //определяем направление торговли серии (покупка или продажа)
  for ( int trade = OrdersTotal() - 1; trade >= 0; trade-- ) 
  {
      if ( OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) && (OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
      {
         {
            if ( !flag )
            {
               lasttype = OrderType(); //запоминаем тип последнего открытого ордера (направление торговли всей серии)
               lastlot = OrderLots();  //запоминаем объем лотов последнего открытого ордера
               lastprice = OrderOpenPrice();//запоминаем цену открытия последнего открытого ордера
               flag = true; //запомнили параметры последнего открытого ордера, дальше вычисляем только количество ордеров серии
            }
            numtrades++; //увеличиваем число открытых ордеров серии
         }
      }
  }
 
  //получаем торговый сигнал от индикатора
  int signal1 = alert1(); 
  //не предпринимаем никаких действий, если превышен лимит числа открытых ордеров в одной серии
  if ( numtrades>=maxtrades ) return (0);
  //если нет открытых ордеров, то открываем первый ордер серии по торговому сигналу
  if ( numtrades==0 )
  {
     //продаем
     if ( signal1==OP_SELL ) 
     {
        ticket = OrderSend(Symbol(), OP_SELL, NormalizeDouble(Lot,2),  NormalizeDouble(Bid, Digits), slip, 0, NormalizeDouble(Bid-takeprofit*Point, Digits), "Sell", MagicNumber, 0, Red);
        Sleep(1000); //задержка в 1 секунду для отработки запроса торговым сервером брокера
        return (0);     
     }
     //покупаем
     if ( signal1==OP_BUY ) 
     {
       ticket = OrderSend(Symbol(), OP_BUY, NormalizeDouble(Lot,2), NormalizeDouble(Ask, Digits), slip, 0, NormalizeDouble(Ask+takeprofit*Point, Digits), "Buy", MagicNumber, 0, Green);
       Sleep(1000); //задержка в 1 секунду для отработки запроса торговым сервером брокера
       return (0);
     }
     return (0);
  }
  //открыт один или серия ордеров одного типа (BUY или SELL) и цена прошла против направления серии steppips пунктов
  if ( (lasttype==OP_SELL && Bid-lastprice>=steppips*Point) || (lasttype==OP_BUY && lastprice-Ask>=steppips*Point) ) 
  {
      //открываем еще ордер на продажу большим лотом
      if (lasttype==OP_SELL) 
      {
          ticket = OrderSend(Symbol(), OP_SELL, NormalizeDouble(Lot * MathPow(Klots, numtrades), 2), NormalizeDouble(Bid, Digits), slip, 0, 0, "Sell", MagicNumber, 0, Red);
          Sleep(1000); //задержка в 1 секунду для отработки запроса торговым сервером брокера
      }
      //открываем еще ордер на покупку большим лотом
      if (lasttype==OP_BUY)  
      {
          ticket = OrderSend(Symbol(), OP_BUY, NormalizeDouble(Lot * MathPow(Klots, numtrades), 2), NormalizeDouble(Ask, Digits), slip, 0, 0, "Buy", MagicNumber, 0, Green);
          Sleep(1000); //задержка в 1 секунду для отработки запроса торговым сервером брокера
      }
      //вычисляем среднюю цену открытия серии
      for ( trade = OrdersTotal() - 1; trade >= 0; trade-- ) 
      {
            if ( OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) )
            {
                 if  ( (OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() ) 
                 {
                      alllots+=OrderLots();
                      sum+=OrderLots()*OrderOpenPrice();
                  }
            }    
       }
       //усредняемся, путем расчета средней цены
       double averageprice =  NormalizeDouble(sum/alllots, Digits);
       //модифицируем все ордера серии путем перемещения одного и того же тейк-профита для каждого открытого ордера
       for ( trade = OrdersTotal() - 1; trade >= 0; trade-- ) 
       {
            if ( OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())
            {
                  //тейк-профит для ордера BUY
                  if ( OrderType() == OP_BUY)  tp = averageprice + takeprofit * Point;
                  //тейк-профит для ордера SELL
                  if ( OrderType() == OP_SELL) tp = averageprice - takeprofit * Point;
                  //модифицируем ордер, принадлежащий серии
                  OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), NormalizeDouble(tp, Digits), 0, Yellow);
            }    
        }
   }
   return (0);   
}
 
int alert1() 
{
   int signal=-1; //нет торгового сигнала
   //получение параметра от индикатора скользящей средней
   double ma1 = iMA(Symbol(),Period(), per, 0, 0, 0, 1);
   //скользящая средняя пробита ценой снизу вверх - покупаем
   if ( iOpen(Symbol(), Period(), 1)<ma1 && iClose(Symbol(), Period(), 1)>ma1 ) signal = OP_BUY;
   //скользящая средняя пробита ценой сверху вниз - продаем
   if ( iOpen(Symbol(), Period(), 1)>ma1 && iClose(Symbol(), Period(), 1)<ma1 ) signal = OP_SELL;
   return (signal); //возвращаем торговый сигнал 
}

Как мы можем видеть из рисунка, советник, работающий по методу усреднения на таймфрейме H1, при определенных настройках на истории с 01.01.2011 по 01.09.2011 разогнал депозит более чем в пять раз, со 100 до 565 долларов. При этом просадка доходила до 60%. При настройках: takeprofit=156, steppips=59, per=118 , Lot=0.01, Klots=1.2, maxtrades=10, slip=3 советник показал доходность 100% за 8 месяцев при просадке, не превысившей 15%, что является в целом отличным показателем, но не гарантирует доходности в будущем.

Результаты работы советника Усреднение на таймфрейме H1 в период с 1 января 2011 г. по 1 сентября 2011 г.

Рис.2 Результаты работы советника “Усреднение” на таймфрейме H1 в период с 1 января 2011 г. по 1 сентября 2011 г.
Исходные данные:
Брокер – InstaForex
Таймфрейм – H1
Период тестирования – с 01.01.2011 по 01.09.2011
Начальный депозит – $100
Модель – по ценам открытия
Настройки советника – Lot = 0.01; Klots = 1.2; takeprofit = 129; steppips = 18; per = 16; maxtrades = 10; slip = 3.

Просим обратить внимание, что оптимизация и тестирование проводились на модели по ценам открытия, а это вообще не гарантирует положительный результат. В советнике также не предусмотрено закрытие позиций при изменении направления тренда, а это при безоткатном движении рано или поздно приведет к сливу депозита. Введением модуля закрытия сделок при смене тренда при ложных сигналах также приведет к серьезной “трепке” депозита вплоть до его слития. Цель этой статьи не написать Форекс-грааль, а показать чем чревато злоупотребление мартингейлом и его различными модификациями. Не бывает идеальных Форекс-индикаторов, а это значит, что неизбежно придется иметь дело с их ложными сигналами, что будет приводить к наращиванию лотов серии сделок, что приведет к глубокой просадке, вплоть до слива депозита. Вы, возможно слышали и о таком понятии, как локирование:

Локирование – временное открытии дополнительной позиции в направлении, противоположном направлению убыточной позиции тем же числом лотов. Как правило, это делается на уровне стоп-лосс, чтобы поддержать временно убыточную позицию, открытую вдоль тренда в надежде, что прогноз все равно оправдается и можно будет избежать убытков.

С локированием не все так просто, как может показаться на первый взгляд. Если предположение о направлении движения цены будет неверным, то это не спасет депозит. При выходе из лока один из ордеров закрывается по профиту, а оставшийся, как правило, усредняется. Таким образом, применяя усреднение, а затем при тупике локирование, мы вновь обрекаем себя впоследствии на усреднение. Кстати, зачастую локирующий ордер открывается не один, а по методу усреднения с целью закрытия всех позиций с безубыточно или даже с профитом. Зачастую же трейдер попадает в ситуацию, которую можно охарактеризовать как “снежный ком”. В такой ситуации с усреднением и локированием справляются далеко не многие. Основная масса в такой трудной ситуации, как правило, сливают депозиты.

Иногда наиболее правильным решением является фиксация небольшого прогнозируемого убытка, нежели глубокая просадка с туманным исходом. Помните, друзья, что постоянно прибыльно торговать на Форекс (без просадок) просто невозможно в силу разных причин, одна из которых, например, кроется в том, что колебания цен на Форекс – это всего лишь белый шум, до конца “обуздать” который вряд ли кому-либо удастся.

Вы можете скачать Форекс советники и потестить их в торговом терминале MetaTrader4. Для скачивания кликните правой кнопкой мыши по тексту “СКАЧАТЬ”, а затем в открывшейся вкладке браузера выберите “Сохранить объект…”:

  • Форекс советник, торгующий по классическому методу мартингейла: СКАЧАТЬ
  • Форекс советник, торгующий по методу усреднения (модифицированный метод мартингейла): СКАЧАТЬ

О том как открыть счет, скачать терминал, установить советник на график и оптимизировать параметры советника мы писали в статье “Прибыльные советники Форекс – это миф или реальность?“.

Устанавливая подобные Форекс советники на реальный торговый счет, помните, что от прибыли до слива депозита порою всего один шаг, а вернее несколько шагов, но тут все зависит от размера депозита и числа лотов первой сделки серии.

Принимая решение об инвестировании средств в ПАММ счета, управляющий которых применяет в своей торговой системе элементы метода мартингейла (усреднения), всегда отдавайте себе отчет в том, что вы можете с легкостью потерять всю сумму инвестиции. При этом положительная длительная история работы управляющего вовсе не говорит о его профессионализме, как трейдера, а говорит о том, что ситуация на рынке была благоприятной для подобных торговых систем – это тренды с большими откатами либо флэтовое движение – стихия подобных систем. При наличии сильного тренда против направления серии такие системы неизбежно приведут к сливу депозита. И локирование всех открытых позиций суммирующим ордером, открытом в противоположном направлении, отнюдь еще не гарантирует благоприятного выхода из просадки. Поскольку выход из лока (замка) также связан с применением метода усреднения, что чревато более глубокой просадкой, вплоть до слива депозита. Именно поэтому правильнее было бы показывать не постоянно растущую доходность без обвалов, но с глубокими просадками, а меньшую доходность с небольшими скачками в минус и с малыми просадками. Целесообразнее зафиксировать небольшой убыток, нежели подвергать торговый счет глубокой просадке.

Если у кого-либо из читателей возникнут вопросы, то постараюсь на них ответить по мере наличия времени. Кстати, недавно для удобства общения я сделал форум, где можно обсудить многие вопросы с разбивкой по подразделам с узкой тематикой (например, тема обсуждения брокера GKFX или тема введение в программирование на MQL4 для MetaTrader), что раньше было не совсем удобно в масштабах Гостевой.

Материалы схожей тематики:
Поделитесь с другими:

Получать информацию о новых заметках:

Комментарии


  1. Было интересно почитать. Все что нужно про мартингейл я теперь понял. Спасибо

  2. Валерий 1 0

    а могу я использовать примеры ваших советников на демо или реальном счете? как это сделать.

    • Конечно, Валерий, если есть большое желание, то Вы можете использовать примеры из этой статьи на демо и реальном торговом счете, предварительно оптимизировав параметры. При этом помните о больших рисках, связанных со сливом депозита.
      Оптимизируя параметры, выбирайте режим модели “Все тики”. Это позволит подобрать более точные параметры, которые, к слову сказать, не гарантируют Вам получения прибыли на интервале, отличном от интервала оптимизации (тестирования).
      Все моменты, связанные с открытием счета, установкой терминала и советника, оптимизации параметров советника, мы описали в одной из статей (Прибыльные советники Форекс – это миф или реальность?). Если будут еще вопросы, то мы с радостью на них ответим.

  3. Павел 1 0

    Владислав а как сделать так, что бы торговля при усреднении прекращалась выставлением локирующего ордера при достижении просадки например в 20 процентов? Спасибо, если поможите.

    • Павел, здесь все не так сложно.
      Нам необходимо знать:
      1. Общую сумму лотов (alllots) серии ордеров (суммируем лоты ордеров серии с использованием функции OrderLots() )
      2. Суммарный профит/убыток (profit) этой серии (суммируем прибыль/убыток каждого ордера серии с использованием функции OrderProfit() )
      Теперь сравниваем баланс счета с профитом/убытком открытых ордеров, например:

      1
      
      if ( profit<0 && MathAbs(profit)>AccountBalance()*(drawdown/100) )

      где drawdown – заданное значение просадки в процентах.
      Если вышеуказанное условие выполняется, то открываем локирующий ордер в направлении, противоположном направлению серии усредняющих ордеров, например:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      if ( lasttype==OP_BUY ) 
      {
         ticket = OrderSend(Symbol(), OP_SELL, NormalizeDouble(alllots,2),  NormalizeDouble(Bid, Digits), slip, 0, 0, "Lock-Sell", MagicNumberLock, 0, Cyan);
         Sleep(1000); //задержка в 1 секунду для отработки запроса торговым сервером брокера    
      }
      if ( lasttype==OP_SELL ) 
      {
          ticket = OrderSend(Symbol(), OP_BUY, NormalizeDouble(alllots,2), NormalizeDouble(Ask, Digits), slip, 0, 0, "Lock-Buy", MagicNumberLock, 0, Cyan);
          Sleep(1000); //задержка в 1 секунду для отработки запроса торговым сервером брокера
      }

      где lasttype – направление серии усредняющих ордеров (BUY или SELL); MagicNumberLock – уникальная метка локирующего ордера, которую необходимо определить в параметрах советника. Именно по наличию такого помеченного ордера мы будем определять, что локирующий ордер уже открыт, а, значит, советник не предпринимает никаких действий. Да, и не забудьте модифицировать все ордера усредняющей серии, установив параметр тейк-профита каждого усредняющего ордера в 0, например:

      1
      2
      3
      4
      5
      6
      7
      8
      
      //модифицируем все ордера серии путем обнуления параметра тейк-профит
      for ( trade = OrdersTotal() - 1; trade >= 0; trade-- ) 
      {
              if ( OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())
              {
                     OrderModify(OrderTicket(), OrderOpenPrice(), 0, 0, 0, Yellow);
              }    
      }
  4. Андрей 1 0

    А все-таки не очень понял как сделать локирование позиций при достижении заданного уровня просадки. Попытался по вашим подсказкам внести изменения в советник, но появляются ошибки, которые не могу устранить.
    Возможно ли повторить код одним куском, который копипастом можно будет вставить в советник и задавать уровень просадок через редактирование значения в Метаэдиторе? :)
    Спасибо.

  5. Андрей, ответ на свой вопрос с кодом вы можете получить в посте:
    Усреднение на Форекс с режимом тейк профит или трейлинг стоп.
    Главное отличие лишь в том, что в описанном в том посте усреднителе первую позицию открывает трейдер, а в этом случае сам советник по сигналу какого-либо индикатора. Но необходимую информацию Вы там почерпнете.
    А с MQL все-таки придется Вам разобраться, поскольку без этого у Вас ничего путного не выйдет. :)
    На уровне копипаст с такими советниками не работают. :)

  6. Олег 1 0

    Мучился с иланом примерно пол года. Как только на рынке происходил большой скачок, он все сливал, хотя во время флэта торговал не плохо! В общем данный советник меня не устроил и в поисках другого грааля, наткнулся…

  7. Максим 7 0

    //+——————————————————————+
    //| Martingale.mq4 |
    //| Copyright © 2011, MoneyInNetwork.ru |
    //| http://moneyinnetwork.ru |
    //+——————————————————————+
    #property copyright “Copyright © 2011, MoneyInNetwork.ru”
    #property link “http://moneyinnetwork.ru”
    extern string s1 = “Объем лота для первой сделки серии”;
    extern double Lot = 0.01;
    extern string s2 = “Уровень стоп-лосса, в пунктах”;
    extern double stoploss = 21;
    extern string s3 = “Уровень тейк-профита, в пунктах”;
    extern double takeprofit = 84;
    extern string s4 = “Уникальная метка для ордеров, открываемых только этим советником”;
    extern double MagicNumber = 600;
    extern string s5 = “Максимальное отклонение от запрошенной цены, в пунктах”;
    extern double slip = 3;
    extern string s6 = “Период скользящей средней, в барах (количество свечей для расчета средней)”;
    extern int per = 55;

    int init()
    {
    return(0);
    }

    int deinit()
    {
    return(0);
    }

    int start()
    {
    //инициализация параметров
    bool flag = false;
    int ticket = 0;
    double lots = Lot;

    //проверяем наличие торгового сигнала
    int signal1 = alert1();
    //ищем среди всех открытых ордеров открытый советником ордер
    for ( int trade = OrdersTotal() – 1; trade >= 0; trade– )
    {
    //проверяем есть ли среди всех открытых ордеров именно тот ордер, который открыт данным советником.
    //ВНИМАНИЕ! MagicNumber – должен быть свой для каждого советника!
    if ( OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) && (OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
    {
    flag = true; //значение флага наличия ордера – ордер открыт
    break; //закончим поиск
    }
    }
    //ордер открыт и пришел новый торговый сигнал
    if ( flag && signal1!=-1 )
    {
    //проверяем тип ордера (BUY или SELL) и закрываем его по соответствующей цене
    if ( OrderType() == OP_BUY && signal1==OP_SELL )
    {
    //если ордер BUY, то закрываем его по цене Bid
    if (OrderClose(OrderTicket(), OrderLots(), Bid, slip, Green) )
    //если сделка закрыта, то разрешаем советнику опять открывать сделки по торговому сигналу на следующем шаге
    flag = false;
    }
    if ( OrderType() == OP_SELL && signal1==OP_BUY )
    {
    //если ордер SELL, то закрываем его по цене Ask
    if (OrderClose(OrderTicket(), OrderLots(), Ask, slip, Red) )
    //если сделка закрыта, то разрешаем советнику опять открывать сделки по торговому сигналу на следующем шаге
    flag = false;
    }
    }
    //нет открытых ордеров
    if ( !flag )
    {
    //ищем в истории закрытых ордеров последний закрытый советником ордер
    for ( trade = OrdersHistoryTotal() – 1; trade >= 0; trade– )
    {
    if ( OrderSelect(trade, SELECT_BY_POS, MODE_HISTORY) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
    {
    if ( OrderProfit()>=0 ) lots = Lot; //последний закрытый советником ордер был прибыльным или безубыточным, значит, следующий ордер открывает с начальным лотом
    else lots = 2*OrderLots(); //последний закрытый советником ордер был убыточным, значит следующий ордер открываем удвоенным лотом
    break; //прекращаем поиск
    }
    }
    //сигнал на продажу – продаем
    if ( signal1 == OP_SELL )
    {
    ticket = OrderSend(Symbol(), OP_SELL, NormalizeDouble(lots,2), NormalizeDouble(Bid, Digits), slip, NormalizeDouble(Ask+stoploss*Point, Digits), NormalizeDouble(Ask-takeprofit*Point, Digits), “Martingale-Sell”, MagicNumber, 0, Red);
    Sleep (1000); //задержка в одну секунду для обрабатки запроса торговым сервером брокера
    return (0);
    }
    //сигнал на покупку – покупаем
    if ( signal1 == OP_BUY )
    {
    ticket = OrderSend(Symbol(), OP_BUY, NormalizeDouble(lots,2), NormalizeDouble(Ask, Digits), slip, NormalizeDouble(Bid-stoploss*Point, Digits), NormalizeDouble(Bid+takeprofit*Point, Digits), “Martingale-Buy”, MagicNumber, 0, Green);
    Sleep (1000); //задержка в одну секунду для обрабатки запроса торговым сервером брокера
    return (0);
    }
    }
    return (0);
    }

    int alert1()
    {
    int signal=-1; //нет торгового сигнала
    //получение параметра от индикатора скользящей средней
    double ma1 = iMA(Symbol(),Period(), per, 0, 0, 0, 1);
    //скользящая средняя пробита ценой снизу вверх – покупаем
    if ( iOpen(Symbol(), Period(), 1)ma1 ) signal = OP_BUY;
    //скользящая средняя пробита ценой сверху вниз – продаем
    if ( iOpen(Symbol(), Period(), 1)>ma1 && iClose(Symbol(), Period(), 1)<ma1 ) signal = OP_SELL;
    return (signal); //возвращаем торговый сигнал
    }

    Помогите мне пожалуйста , не могли бы вы убрать индикатор , и сделать так чтоб одна сделка открывалась на покупку потом на продажу , и если сработал стоп чтоб увеличивал лот ! Ну типа открылась сделка на покупку и сработал стоп следующая чтоб открылась на продажу *2 ! за ранее спасибо.

    • Попробуйте этот совсем “горячий код” (я его только написал и не тестил):

      //+------------------------------------------------------------------+
      //|                                         Martingale - classic.mq4 |
      //|                              Copyright © 2013, MoneyInNetwork.ru |
      //|                                         http://moneyinnetwork.ru |
      //+------------------------------------------------------------------+
      #property copyright "Copyright © 2013, MoneyInNetwork.ru"
      #property link      "http://moneyinnetwork.ru"
      extern string s1 = "Объем для первой сделки серии, лот";
      extern double Lot = 0.01;
      extern string s2 = "Уровень стоп-лосса, пунктов";
      extern double stoploss = 21;
      extern string s3 = "Уровень тейк-профита, пунктов";
      extern double takeprofit = 84;
      extern string s4 = "Уникальная метка для ордеров, открываемых только этим советником";
      extern double MagicNumber = 600;
      extern string s5 = "Максимальное отклонение от запрошенной цены, пунктов";
      extern double slip = 3;
       
      int init()
      {
         return(0);
      }
       
      int deinit()
      {
         return(0);
      }
       
      int start()
      { 
        //инициализация параметров
        bool flag = false;
        int ticket = 0;
        double lots = Lot;
        int old_order_type = -1;
       
        //ищем среди всех открытых ордеров открытый советником ордер 
        RefreshRates();
        for ( int trade = OrdersTotal() - 1; trade >= 0; trade-- ) 
        {
            //проверяем есть ли среди всех открытых ордеров именно тот ордер, который открыт данным советником.
            //ВНИМАНИЕ! MagicNumber - должен быть свой для каждого советника!
            if ( OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) && (OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
            {
                  flag = true; //значение флага наличия ордера - ордер открыт
                  break; //закончим поиск
            }        
        }
        //ордер советником открыт - выходим без действий, ожидая его закрытия по тейк профиту или стоп лоссу.
        if ( flag )
        {
            return (0);
        }
        //нет открытых ордеров - ищем в истории закрытых ордеров последний закрытый именно этим советником ордер 
        flag = false;
        for ( trade = OrdersHistoryTotal() - 1; trade >= 0; trade-- ) 
        {
           if ( OrderSelect(trade, SELECT_BY_POS, MODE_HISTORY) && OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol() )
           {
               if ( OrderProfit()>=0 ) lots = Lot;   //последний закрытый советником ордер был прибыльным или безубыточным, значит, следующий ордер открываем с начальным объемом
                          else lots = 2*OrderLots(); //последний закрытый советником ордер был убыточным, значит, следующий ордер открываем удвоенным объемом
                      old_order_type = OrderType(); //запоминаем тип ордера - прокупка или продажа.
                      flag = true;
                      break; //прекращаем поиск
           }
        }
        if ( !flag ) 
            old_order_type = OP_BUY; //в истории нет ордеров открытых этим советников, значит, стартуем с покупок
        //если раньше покупали, то теперь продаем
        if ( old_order_type == OP_BUY )
        {
            ticket = OrderSend(Symbol(), OP_SELL, NormalizeDouble(lots,2),  NormalizeDouble(Bid, Digits), slip, NormalizeDouble(Ask+stoploss*Point, Digits), NormalizeDouble(Ask-takeprofit*Point, Digits), "Martingale-Sell", MagicNumber, 0, Red);
            Sleep (1000); //задержка в одну секунду для обрабатки запроса торговым сервером брокера
            return (0);  
        }
        //если раньше продавали, то теперь покупаем
        if ( old_order_type == OP_SELL )
        {
            ticket = OrderSend(Symbol(), OP_BUY, NormalizeDouble(lots,2), NormalizeDouble(Ask, Digits), slip, NormalizeDouble(Bid-stoploss*Point, Digits), NormalizeDouble(Bid+takeprofit*Point, Digits), "Martingale-Buy", MagicNumber, 0, Green);
            Sleep (1000); //задержка в одну секунду для обрабатки запроса торговым сервером брокера
            return (0);  
        }               
        return (0);  
      }
      • Если будете использовать на пятизнаке, то не забывайте задавать параметры проскальзывания, а также уровни стоп лосса и тейк профита, выраженные в пипсах, т.е. умноженные на 10.

  8. Максим 7 0

    Владислав спасибо большое все работает , хотел узнать как поменять множитель 2 на 1,3 я в скрипте менял но он постоянно ставит лот 0,01 то есть начальный !

    • В этой строке:

      else lots = 2*OrderLots(); //последний закрытый советником ордер был убыточным, значит, следующий ордер открываем удвоенным объемом

      Коэффициент 2 замените на любое, требуемое Вам значение.

      • максим 7 0

        Ну я там менял на 1.3. И получается что он умножает 1.3 на 0.01 и по этому все сделки открываются 0.01 без изменений

        • Конечно, не будет изменений, поскольку минимальный шаг у брокеров (и то не у всех) 0.01 лот, и если мы умножим 1.3 на 0.01, то получим 0.013 лот, что при округлении до сотых (размер шага) ближе к 0.01.

  9. Максим 7 0

    ладно тогда можно зделать чтоб открывались сделки вот так 0,01 0,01 0,02 0,02 0,03… вот таким образом , возможно такое ?

    • Конечно, возможно. Подумайте немного и измените :)

      • Максим 7 0

        Все перепробувал не катит моя система , у вас есть чтото достойное ?

      • Максим 7 0

        скажите хоть как сделать чтоб он открывал максимум 5 удвоенний

        • Максим, если хотите работать с советниками, то осваивайте MQL и программирование. Дам подсказку. Надо немного модифицировать блок поиска в истории закрытых ордеров. Там вести подсчет количества закрытых непрофитных ордеров. Это значение будет показателем степени для объема вновь открываемого ордера…

Ваш комментарий

Подписаться без комментирования



Инсайт Инвест Брокер