Перейти к содержанию

Обучение языку MQL4 под MetaTrader 4


Рекомендуемые сообщения

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@Владимир Стариков  понятно. криво написанная панель.  

При каждом запуске советник обязан искать "свои" ордера, для этого все инструменты есть. Попробуйте другую панель - их довольно много доступно, в том числе здесь на форуме.

Ссылка на сообщение
Поделиться на другие сайты

  • Ответов 6,8k
  • Создано
  • Последний ответ

Популярные авторы

Популярные авторы

Популярные посты

Смотрим видео-уроки, изучаем MQL:       Скачать видеокурс «MQL программирование. Как самому написать форекс советник/ индикатор/ скрипт»   P.S. Тема про Обучение MQ

Перейти

Циклы цикл for Иногда необходимо повторять одно и то же действие несколько раз подряд. Для этого используют циклы. К примеру, мы хотим проанализировать последние 10 баров и выяснить наименьшую цен

Перейти

Речь идет о том, что не будет значимых нововведений. А только баги периодически будут править. А вот все новое мол - в МТ5. Когда они вживую сказали то же самое на конференции в Москве, я уточнил: "То

Перейти
Обучение языку MQL4 под MetaTrader 4 Опубликовано

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

Спойлер

datetime FindLastTimeBuy()
  {
   datetime otime,time_buy=D'1980.07.19 12:30:27';
   for(int m=OrdersTotal()-1; m>=0;m--)
     {
      if(OrderSelect(m,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic_buy)
           {
            if(OrderType()==OP_BUY)
              {
               otime=OrderOpenTime();
               if(otime>time_buy)
                 {
                  time_buy=otime;
                 }
              }
           }
        }
     }
   return(time_buy);
  }

И я так понимаю последнее значение у цикла попадет в переменную time_buy ? Но мне кажется наверное надо не с конца цикл прогонять а с начала тогда.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
10 часов назад, diodio сказал:

мне интересно в каком формате записать первоначальную дату для сравнения.

можно  начальное значение значение time_buy задать = 0. Если ордер BUY есть в рынке, то его время в любом случае будет >0.
Только нужно будет обрабатывать нулевое значение, которое вернет Ваша функция в случае, если ордеров БАЙ в рынке нет.
Направление сканирования рыночных ордеров значение не имеет.

 

 

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Всем привет, скажите правильно ли я заполнил массив:

Спойлер

//+---------------------Профит уже закрытых ордеров на продажу----------------------+
void OrderProfitSellClose()
  {
   int counter=0,size=OrdersHistoryTotal();
   ArrayResize(cSellProfitClose,size);
   for(int i=OrdersHistoryTotal()-1; i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol()==Symbol()&& OrderMagicNumber()==Magic_sell)
           {
            if(OrderType()==OP_SELL)
              {
               cSellProfitClose=OrderProfit()+OrderCommission()+OrderSwap();
               counter++;
              }
           }
        }
     }
   ArrayResize(cSellProfitClose,counter);
   return;
  }

Должно получиться что в каждой ячейке массива cSellProfitClose будет лежать какая-то цифра. Массив динамический, ну это уже понятно.

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

Спойлер

for(int z=ArraySize(cSellProfitClose)-1;  z>=0; z--)
           {
               SellProfitClose+=cSellProfitClose[z];
           }

Верно иду?

Кстати usver73 спасибо.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
2 часа назад, diodio сказал:

Верно иду?

в тестере не проверял, но по теории все верно,раз нет ошибок

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
16 часов назад, diodio сказал:

Верно иду?

А я не понял смысла всех телодвижений...
 

 cSellProfitClose=OrderProfit()+OrderCommission()+OrderSwap();

будет ошибка- нет cSellProfitClose[]  c индексом массива.
Далее: массиву определяется размер в количестве ордеров в истории, а после выборки всех СЕЛЛ- ордеров идет резайз, причем скорее всего в меньшую сторону..
Какую часть массива эта команда обрежет?
тогда уж так:
 

ArrayResize(cSellProfitClose,counter+1);              
cSellProfitClose[counter]=OrderProfit()+OrderCommission()+OrderSwap();
counter++;

И вообще- в чем смысл иметь массив из определенных исторических ордеров? Если целей несколько, то, наверно, имеет смысл их копировать в массив. А если цель одна- посчитать профит, так это лучше сразу делать в цикле по истории.. ИМХО.

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
7 часов назад, usver73 сказал:

А я не понял смысла всех телодвижений...

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

Вот такое условие идет:

Спойлер

LastTimeBuy = FindLastTimeBuy();
         OrderProfitSellClose();// Профит уже закрытых ордеров на продажу
         OrderTimeSell(); // Время открытия ордеров на продажу

         for(int z=ArraySize(cTimeSellOpen)-1; z>=0;z--)
           {
            if(cTimeSellOpen[z] > LastTimeBuy)
              {
               SellProfitClose+=cSellProfitClose[z];
              }
           }
         OrderProfitBuy(); // Профит еще не закрытых ордеров на покупку
         for(int t=ArraySize(cBuyProfitOpen)-1; t>=0;t--)
           {
            BuyProfitOpen+=cBuyProfitOpen[t];
            if(MathAbs(BuyProfitOpen) <= SellProfitClose)
              {
               if(OrderType() == OP_BUY)
                  bool close_profit_buy = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage);
              }
           }

//------------------ФУНКЦИИ---------------------------------

 

//+---------------------Функция находит последнее время ордера который выставился на покупку но еще сетка не закрыта--------------------+
datetime FindLastTimeBuy()
  {
   datetime otime,time_buy=0;
   for(int m=OrdersTotal()-1; m>=0;m--)
     {
      if(OrderSelect(m,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic_buy)
           {
            if(OrderType()==OP_BUY)
              {
               otime=OrderOpenTime();
               if(otime>time_buy)
                 {
                  time_buy=otime;
                 }
              }
           }
        }
     }
   return(time_buy);
  }

//+---------------------Профит уже закрытых ордеров на продажу----------------------+
void OrderProfitSellClose()
  {
   int counter=0,size=OrdersHistoryTotal();
   ArrayResize(cSellProfitClose,size);
   for(int i=OrdersHistoryTotal()-1; i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol()==Symbol()&& OrderMagicNumber()==Magic_sell)
           {
            if(OrderType()==OP_SELL)
              {
               cSellProfitClose=OrderProfit();
               counter++;
              }
           }
        }
     }
   ArrayResize(cSellProfitClose,counter);
   return;
  }

 

//+---------------------Время открытия ордеров на продажу----------------------+
void OrderTimeSell()
  {
   int counter=0,size=OrdersTotal();
   ArrayResize(cTimeSellOpen,size);
   for(int i=OrdersTotal()-1; i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol()==Symbol()&& OrderMagicNumber()==Magic_sell)
           {
            if(OrderType()==OP_SELL)
              {
               cTimeSellOpen=OrderOpenTime();
               counter++;
              }
           }
        }
     }
   ArrayResize(cTimeSellOpen,counter);
   return;
  }

 

//+---------------------Профит еще не закрытых ордеров на покупку----------------------+
void OrderProfitBuy()
  {
   int counter=0,size=OrdersHistoryTotal();
   ArrayResize(cBuyProfitOpen,size);
   for(int i=OrdersTotal()-1; i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol()&& OrderMagicNumber()==Magic_buy)
           {
            if(OrderType()==OP_BUY)
              {
               cBuyProfitOpen=OrderProfit()+OrderCommission()+OrderSwap();
               counter++;
              }
           }
        }
     }
   ArrayResize(cBuyProfitOpen,counter);
   return;
  }

Сделал условие по времени открытия. Здесь на этом моменте решил проверить работоспособность и не сработало. Далее поставлю условие на участие определенных ордеров в закрытии, но это будет после. Хотя бы это должно работать, смысл пока идти дальше нет. Ну и где ошибка?)

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Только что, diodio сказал:

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

Давайте разделим задачу на чисто код и логику.
Во-первых- Вы не объявляете массивы (хотя, возможно, они на глобальном уровне объявлены).
Во-вторых, когда Вы пишете в них информацию, то пишете с ошибкой синтаксиса- должно быть указание на ИНДЕКС массива в [] после имени.
В третьих- если Вам нужно одно значение- сумма профита исторических ордеров, время последнего ордера и т.д., то массивы вообще не нужны- объявляете переменную нужного типа и в цикле либо к ней прибавляете (расчет профита), либо проверяете ее значение (время крайнего ордера)..

По логике:
Если Вы все таки хотите решить несколько задач, связанных, например, с историческими ордерами, то логично в массивы писать ВСЮ нужную информацию (профит, время открытия/закрытия, цены открытия/закрытия и т.п). Тогда нужно объявлять структуру (F1) и объявлять, соответственно, массив структур.

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
9 минут назад, diodio сказал:

OrderProfitSellClose();// Профит уже закрытых ордеров на продажу

Функция не возвращает значение. Предполагаем, что внутри нее происходят вычисления и результат присваивается некоей переменной, объявленной на глобальном уровне..
Но по факту Вы получите значение первого(?) по времени закрытого СЕЛЛ ордера. 
Про массив я писал.
Про СУММУ СЕЛЛ ордеров вроде тоже.
Еще момент- у Вас нет ограничения по глубине истории, т.е. в данной реализации Вы будете считать ВСЮ историю закрытых СЕЛЛ ордеров.

16 минут назад, diodio сказал:

 OrderTimeSell(); // Время открытия ордеров на продажу

Та же фигня- Вы получите время первого закрытого ордера СЕЛЛ.

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

@diodio Вам @usver73 намекает, что решать такую задачу (непростую) и одновременно заниматься обслуживанием массива не очень разумно, тем более значения профита/убытка меняется на каждом тике и всё-равно нужно гонять цикл пересчёта ордеров, точного совпадения убытка и профита ордеров не будет, надо учитывать нереализованный профит при их совместном закрытии и т.д. - куча проблем, но есть и положительный момент - опыт Вы получите бесценный...

От Вас нужно чёткое понимание зачем (это делать, ведь просадка это бензин сетки) и как (алгоритм).

Много лет назад мне тоже это показалось ценной идеей и алгоритм был такой (насколько помню):

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

Делал это однократно, т.к. больше профита не хватало... 

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Всем привет.

22 часа назад, usver73 сказал:

Во-первых- Вы не объявляете массивы (хотя, возможно, они на глобальном уровне объявлены).

По поводу массивов, они объявлены на глобальном уровне:

Спойлер

datetime cTimeBuyOpen[100], cTimeSellOpen[100], cTimeSellClose[100],cTimeBuyClose[100];
double   cBuyProfitOpen[100], cSellProfitOpen[100],cBuyProfitClose[100], cSellProfitClose[100];

Я даже им размер поставил.

 

22 часа назад, usver73 сказал:

Во-вторых, когда Вы пишете в них информацию, то пишете с ошибкой синтаксиса- должно быть указание на ИНДЕКС массива в [] после имени.

Далее я заполняю, их через цикл в функции: cSellProfitClose(i)=OrderProfit(); я тут поставил круглые скобки

где i и является тем индексом которая присутствует в цикле и в номере ячейки массива.

 

22 часа назад, usver73 сказал:

Но по факту Вы получите значение первого(?) по времени закрытого СЕЛЛ ордера. 

Я по факту хочу просто заполнить массив в самой функции путем цикла. Мне не нужно значение первого там или последнего ордера. 

Заполнен массив, который объявлен на глобальном уровне, далее я его кручу как хочу. Или я чего-то уже не понимаю. Разве не так заполняются массивы как я показал?

Ну и собственно к чему все эти движения?! Массивы были нужны для того чтоб я в них мог менять значения, а именно те значения, которые участвовали в переборе и закрывались допустим всей суммой просадку. Если говорить по-простому, то я хочу обнулить эти значения, не все, а только те, которые помогли закрыть просадку. Хотел это сделать вот таким путём:

Спойлер

for(int z=0; z < ArraySize(cTicketSellClose); z++)
                    {
                     if(cTicketSellClose[z] > LastTicketBuy)
                               
                        for(int b=0; b < ArraySize(cSellProfitClose); b++)
                          {
                           cSellProfitClose=+SellProfitClose;

                           OrderProfitBuy(cBuyProfitOpen); // Профит еще не закрытых ордеров на покупку
                           for(int t=0; t < ArraySize(cBuyProfitOpen); t++)
                             {
                              cBuyProfitOpen[t]=+BuyProfitOpen;
                              if(MathAbs(BuyProfitOpen) <= SellProfitClose)
                                {
                                 if(OrderType() == OP_BUY)
                                    bool close_profit_buy = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage);
                                 for(int n=0; n < b; n++)
                                   {
                                    cSellProfitClose[n] = 0;
                                   }
                                    ArrayCopy(cSellProfitClose,cSellProfitClose,0,WHOLE_ARRAY);
                                    ArrayResize(cSellProfitClose, ArraySize(cSellProfitClose));
                                }
                             }
                          }
                       }

 

Изменено пользователем diodio
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 24.06.2020 в 21:23, diodio сказал:

Далее я заполняю, их через цикл в функции: cSellProfitClose(i)=OrderProfit(); я тут поставил круглые скобки

где i и является тем индексом которая присутствует в цикле и в номере ячейки массива.

Блин, или я чего-то не знаю, либо Вы не читаете, то, что пишут... Почему КРУГЛЫЕ скобки в массиве cSellProfitClose(i)?
Далее по функции OrderProfitSellClose();// Профит уже закрытых ордеров на продажу:
 

Спойлер

//+---------------------Профит уже закрытых ордеров на продажу----------------------+
void OrderProfitSellClose()
  {
   int counter=0,size=OrdersHistoryTotal();
   ArrayResize(cSellProfitClose,size); // устанавливаем размер массива по количеству ордеров в истории, допустим 1000
   for(int i=OrdersHistoryTotal()-1; i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol()==Symbol()&& OrderMagicNumber()==Magic_sell)
           {
            if(OrderType()==OP_SELL)
              {
               cSellProfitClose=OrderProfit(); // если здесь будет исправлена ошибка и будет записано cSellProfitClose[i], то массив будет заполняться с "дырками"
               counter++;
              }
           }
        }
     }
   ArrayResize(cSellProfitClose,counter); // здесь мы обрежем примерно половину массива
   return;
  }

 

Про синтаксическую ошибку написал в комментарии.
По логике: Вы сканируете всю историю и выбираете только СЕЛЛ ордера. Но значения профита в массив пишутся не подряд, а так, как ордера СЕЛЛ в истории записаны. Будет примерно так:
1.0$
0.5$
0.0$
0.0$
-0.3$  и т.д.
т.е. там, где 0.0$ скорее всего были БАЙ-ордера.
Далее Вы уменьшаете размер массива до количества найденных СЕЛЛ ордеров. В примере- 3 шт.
В остатке массив будет содержать:
1.0$
0.5$
0.0$
Дальше вся Ваша логика летит в топку. Как сделать правильно- я писал ранее..
По вопросу, который осветил 0ll :
Сканировать на каждом тике (или с каким-то периодом- не важно) историю, да еще раздельно для БАЙ и СЕЛЛ как-то... неразумно. Терем просто умрет на каком-то этапе
Если количество ордеров в рынке конечно (даже если это сетка), то в истории их будет со временем ооочень много.. 
И нафига Вам ВСЕ исторические ордера? Скорее всего нужны последние сетки или еще-что-то.

if(cTicketSellClose[z] > LastTicketBuy)

 

Изменено пользователем usver73
  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Здравствуйте!

 

Осваиваю программирование на MQL4, пока дилетант. Написал несложный советник, прогнал в тестере.

Проблема такая - каждый новый бар (на Д1) советник должен открывать новые отложенные ордера. И в тестере все хорошо на истории, открывает.

А в реале приходится перезапускать терминал. После перезапуска сразу открывает, а просто при появлении новой свечки - нет.

Не могу понять, в чем может быть проблема. Счет - Альпари PRO.ecn

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
В 01.07.2020 в 20:42, Ill333 сказал:

И в тестере все хорошо на истории, открывает.

А в реале приходится перезапускать терминал.

Нужно вести лог при помощи Print(...), так можно будет понять что происходит.

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Ребят, пишу советник на базе индикатора ТМА, уже тестирую простенький. Но есть еще задумка заложить в советник элементы теории вероятности.

Не получается создать цикл, уже всю голову сломал.

 

Суть такова:

 

Параметры:

 

extern int    Lot             = 10;  // Объем лота в % от депозита
extern double Factor          = 2.0; // Множитель при успешной сделке
extern int    Attempt         = 3;   // Количество попыток

 

1. Первая сделка (попытка) выполняется с базовым лотом (Lot)

2. Если попытка 1 закрывается по ТР, то попытка 2 открывается с лотом рассчитанным по формуле (лот первой сделки * на множитель). Если сделка один закрывается по SL,, то цикл останавливается и начинается заново и сделка открывается с базовым лотом (Lot)

3. Аналогично,

 

После отработки цикла, все начинается заново исходя из полученного баланса.

 

Таким образом у нас есть 10 попыток, чтобы поймать 3 последовательно успешные сделки. В таком случае если депозит 100, то расчет в трех попытках такой 10+20+40. Если цикл отработал на пример на 4 попытке, то баланс составляет 100-30+70 = 140.

 

Вот мой пример, но что то он считает не так(

 

if (Attempt > 1)
       { 
        for (int i = Attempt; i >= 1; i--)
         {
           if (i == Attempt)
             { 
               OpenOrder(Lots);
             }
           if (i < Attempt && LastOrderProfit() > 0)
             { 
               double OLot = LastOrderLot() * Factor;

               OLot = NormalizeDouble(OLot , 2);
               OpenOrder(OLot);
             }
            if (i < Attempt && LastOrderProfit() < 0)
             {
               break;
             }

               
         }

Изменено пользователем Pretor85
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
50 минут назад, Pretor85 сказал:

Ребят, пишу советник на базе индикатора ТМА, уже тестирую простенький. Но есть еще задумка заложить в советник элементы теории вероятности.

Не получается создать цикл, уже всю голову сломал.

 

проблема в том, что это должен быть не цикл, а независимые функции.

А вот тот Attempt - должен быть глобальным параметром

  • Лайк 2
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Ребят, начинаю осваивать MQL и напоролся на такую проблему. 

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

bool OrderHitoryClose()
  {
   for(int i=0; i<OrdersHistoryTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))                                         // Выбор ордера для дальнейшей работы..
         if(OrderType() == OP_BUY)                                                            // ..тип ордера..
            if(TimeToStr(OrderCloseTime(), TIME_DATE) == TimeToStr(TimeCurrent(), TIME_DATE)) // ..дата закрытия ордера равна текущей дате..
               return(true);                                                                  // ..(на текущий день был закрыт ордер на покупку)
         if(OrderType() == OP_SELL)
           if(TimeToStr(OrderCloseTime(), TIME_DATE) == TimeToStr(TimeCurrent(), TIME_DATE))
              return(true);
     }
   return(false);
  }

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

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Стоило мне задать вопрос, как спустя час нашлось решение.

Переделал код и избавился от работы с OrdersHistoryTotal()

Работал с временем открытия бара

bool NewBar()
  {
   static datetime BarTime        = 0;             
   datetime        CurrentBarTime = Time[0];       
   
   if(BarTime == CurrentBarTime) return(false);
   else
     {
      BarTime = CurrentBarTime;
      return(true);
     }
  }

 

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

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

Вот код:

Глобальные переменные:
double BuyProfitOpen;
double SellProfitClose;   
---------------------------------------------------------------
for(int s=OrdersHistoryTotal()-1; s>=0; s--)
           {
            if(OrderSelect(s,SELECT_BY_POS,MODE_HISTORY))
              {
               if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_SELL)
                 {
                     SellProfitClose += OrderProfit();
                     SellProfitClose = NormalizeDouble(SellProfitClose,2);
                     Print("Сумма по истории селл ордеров SellProfitClose= ",SellProfitClose);
                 }
              }
           }

         for(int h = 0; h < OrdersTotal(); h++) 
           {
            if(OrderSelect(h,SELECT_BY_POS,MODE_TRADES))
              {
               if(OrderMagicNumber()==Magic && OrderSymbol()==Symbol())
                 {
                  if(OrderType()==OP_BUY)
                    {
                     BuyProfitOpen += OrderProfit()+OrderSwap()+OrderCommission();
                     BuyProfitOpen = NormalizeDouble(BuyProfitOpen,2);
                     Print("Сумма в рынке по бай ордерам BuyProfitOpen= ",BuyProfitOpen);
                    }
                 }
              }
           }

А теперь про мусор, прикрепил изображение. Что не так? Торги сеткой лотностью 0,01, в сетке по 10 ордеров где-то. И это начало тестирование в тестере MT4. Проверка на ошибки - ошибок нет.

журнал.jpg

Изменено пользователем diodio
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
Только что, diodio сказал:

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

Вот код:


Глобальные переменные:
double BuyProfitOpen;
double SellProfitClose;   
---------------------------------------------------------------
for(int s=OrdersHistoryTotal()-1; s>=0; s--)
           {
            if(OrderSelect(s,SELECT_BY_POS,MODE_HISTORY))
              {
               if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic && OrderType()==OP_SELL)
                 {
                     SellProfitClose += OrderProfit();
                     SellProfitClose = NormalizeDouble(SellProfitClose,2);
                     Print("Сумма по истории селл ордеров SellProfitClose= ",SellProfitClose);
                 }
              }
           }

         for(int h = 0; h < OrdersTotal(); h++) 
           {
            if(OrderSelect(h,SELECT_BY_POS,MODE_TRADES))
              {
               if(OrderMagicNumber()==Magic && OrderSymbol()==Symbol())
                 {
                  if(OrderType()==OP_BUY)
                    {
                     BuyProfitOpen += OrderProfit()+OrderSwap()+OrderCommission();
                     BuyProfitOpen = NormalizeDouble(BuyProfitOpen,2);
                     Print("Сумма в рынке по бай ордерам BuyProfitOpen= ",BuyProfitOpen);
                    }
                 }
              }
           }

А теперь про мусор, прикрепил изображение. Что не так? Торги сеткой лотностью 0,01, в сетке по 10 ордеров где-то.

журнал.jpg

В цикле сверху, вы считаете профит/убыток от всех ордеров закрывших по SELL направлению на истории.

В цикле снизу, вы считаете профит/убыток от всех ордеров по BUY направлению в рынке.

 

Написал небольшой советник для подсчета профита.

extern int Magic = 0;

void OnTick() {
	double BuyProfitOpen,  BuyProfitClose;
	double SellProfitOpen, SellProfitClose;  
	int    s;
	for (s = 0; s < OrdersTotal(); s++) {
		if ((OrderSelect(s, SELECT_BY_POS, MODE_TRADES)) && (OrderMagicNumber() == Magic) && (OrderSymbol() == Symbol())) {
			if (OrderType() == OP_BUY)  {
				BuyProfitOpen  += NormalizeDouble((OrderProfit() + OrderSwap() + OrderCommission()), 2);
			}
			if (OrderType() == OP_SELL)  {
				SellProfitOpen += NormalizeDouble((OrderProfit() + OrderSwap() + OrderCommission()), 2);
			}
		}
	}	
	for (s = OrdersHistoryTotal() - 1; s >= 0; s--) {
		if (OrderSelect(s, SELECT_BY_POS,MODE_HISTORY) && (OrderMagicNumber() == Magic) && (OrderSymbol() == Symbol())) {
			if (OrderType() == OP_BUY)  {
				BuyProfitClose  += NormalizeDouble((OrderProfit() + OrderSwap() + OrderCommission()), 2);
			}
			if (OrderType() == OP_SELL)  {
				SellProfitClose += NormalizeDouble((OrderProfit() + OrderSwap() + OrderCommission()), 2);
			}			
		}
	}	
	Comment("Сумма профита открытых BUY ордеров: ",               DoubleToStr(BuyProfitOpen, 2),   "\n",
	        "Сумма профита открытых SELL ордеров: ",              DoubleToStr(SellProfitOpen, 2),  "\n",
			"\n",                                                 
			"Сумма профита закрытых BUY ордеров: ",               DoubleToStr(BuyProfitClose,  2),  "\n",
			"Сумма профита закрытых SELL ордеров: ",              DoubleToStr(SellProfitClose, 2),  "\n",
			"\n",
			"Сумма профита открытых + закрытых BUY ордеров: ",    DoubleToStr((BuyProfitOpen  + BuyProfitClose),  2),  "\n",
			"Сумма профита открытых + закрытых SELL ордеров: ",   DoubleToStr((SellProfitOpen + SellProfitClose), 2),  "\n"			
			);

	return;
}

Единственное для увеличения производительности не рекомендую считать профит/убыток на истории на каждом тике, например, это можно делать только с последним ордером, добавляя профит или убыток к общей переменной.

  • Лайк 2
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
2 часа назад, Ent сказал:

Единственное для увеличения производительности не рекомендую считать профит/убыток на истории на каждом тике, например, это можно делать только с последним ордером, добавляя профит или убыток к общей переменной.

Ну у меня почти тоже самое написано, только немного по-другому, вопрос в том почему в журнале такие числа? На каждом тике считает?

Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано
21 минуту назад, diodio сказал:

Ну у меня почти тоже самое написано, только немного по-другому, вопрос в том почему в журнале такие числа? На каждом тике считает?

Сложно сказать, т.к. вы не показываете код целиком.

Если у вас переменные вынесены за функцию OnTick(), то они не обнуляются на каждом тике, как моём примере, выше.

  • Лайк 1
Ссылка на сообщение
Поделиться на другие сайты

Обучение языку MQL4 под MetaTrader 4 Опубликовано

Пишу свой первый советник. Уроки очень помогают. 

Но не могу разобаться с 

double NormaliseDouble(double Lots, int 2);
Компилятор ругается

'2' - comma expected    Test!.mq4    33    41


 

Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Специальное предложение


  • Рекомендуемые брокеры

  • ×
    ×
    • Создать...