Скачать MetaTrader 5

Подсчитать кол-во вызовов функции:

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Mike Kharkov
849
Mike Kharkov  
Здравствуйте.
Есть такой код:

//+------------------------------------------------------------------+
//|                                                  My_Practics.mq5 |
//+------------------------------------------------------------------+
#property copyright "Mike_Kharkov"
#property link      "https://www.fl.ru/users/Yamaradg/"
#property version   "1.00"

double COEF  = 1.0;  //коэффициент кратности увеличения лота
int    DELTA = 200;  //количество пунктов прохода цены для уведичения позиции
int    counter = 0; // счетчит вызовов функции
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  counter=0;

//---
   
//---
   return(INIT_SUCCEEDED);
}//---------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}//---------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{ 
   // вызываем функцию вычисления последнего ордера и преобразовываем результат в 5-ти значное число.
      double last_order = FindLastPrice(ORDER_TYPE_BUY);
      
   int positions_total = PositionsTotal();
  
//---блок первоначального окрытия позиции по текущей цене
   if(PositionsTotal() < 1)
   {
      double prc = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
      double lot = 0.01;
      
      // вызов функции формирования торгового запроса
      bool isOpen = SendOrder(prc, lot);
       
      if (isOpen)
      {
         Print("         Первоначальное открытие               ");
   
         if (PositionSelect(Symbol()))
         {
            double priceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
            double posTP     = PositionGetDouble(POSITION_TP);
            Print(" Количество открытых позиций: ", PositionsTotal());
            Print(" Цена в сделке, подтверждённая брокером : ", DoubleToString(priceOpen, 5));
            Print(" Тэйк-Профит позиции : ", DoubleToString(posTP, 5));
            Print("                        ");
         }
      }
      return;
   }
      
//---блок наращивания существующей позиции
   //double posPriceOpen  = 0;
   double ask           = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   double posVolume     = 0.01;
   
   // узнаем цену открытия и совокупный объем позиции
   if (PositionSelect(Symbol()))
   {
      posVolume    = PositionGetDouble(POSITION_VOLUME);
      
   }
   
   // условие для наращивания позиции
   if(ask <= last_order - DELTA * _Point && PositionsTotal() == 1)
   {
      double prc = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
      //увеличим размер позиции на коэффициент
      double lot = posVolume * COEF;
      
      // вызов функции формирования торгового запроса
      bool isOpen = SendOrder(prc, lot);
       
      if (isOpen)
      {
         Print("          Увеличение объема позиции              ");
         Print(" Цена по которой открываем ордер : ", DoubleToString(ask, 5));
         Print(" Объем открываемого ордера : ", DoubleToString(lot, 2));
         
         if (PositionSelect(Symbol()))
         {
            posVolume    = PositionGetDouble(POSITION_VOLUME);
            double posTP = PositionGetDouble(POSITION_TP);
            Print("          Данные после открытия ордера              ");
            Print(" Количество открытых позиций_2: ", PositionsTotal());
            Print(" Оъем открытой позиции после открытия ордера : ", DoubleToString(posVolume, 2));
            Print(" Тэйк-Профит позиции : ", DoubleToString(posTP, 5));
            Print("Цена последней сделки: ", DoubleToString(last_order, 5));
            Print("Порядковый номер вызова ф-ции: ", counter,"-я функция.");
         }
      }
      return;
   }
//---
   
}//---------------------------------------------------------------------------+

//функция формирующая торговый запрос на открытие позиции
//и проверки результата открытия
bool SendOrder(double price, double volume)
{
   MqlTradeRequest request = {0};
   MqlTradeResult  result  = {0};
  
//---заполняем поля торгового запроса
   request.action       = TRADE_ACTION_DEAL;    // Тип выполняемого действия
   request.symbol       = _Symbol;              // Имя торгового инструмента
   request.volume       = volume;               // Запрашиваемый объем сделки в лотах
   request.price        = price;                // Цена  
   request.type         = ORDER_TYPE_BUY;       // Тип ордера
   request.tp           = price + 250*_Point;   // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
   request.sl           = 0;                    // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
   request.type_filling = ORDER_FILLING_FOK;    // Тип ордера по исполнению
   request.type_time    = ORDER_TIME_GTC;
   
//---проверим хватает ли средств для открытия позиции
   double margin = 0.0;
   
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
      return(false);
   
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
      return(false);

   
//---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
      {
      counter++;
      return(true);
      }
   else
      Print(__FUNCTION__,"   При выставлении ордера произошла ошибка. Error = ",GetLastError());
                                    
   return(false);
}//---------------------------------------------------------------------------+

// возвращает цену открытия последнего ордера, где nMode - ORDER_TYPE_BUY/ORDER_TYPE_SELL
// для позиции с идентификатором PositionID
double FindLastPrice(int nMode)
  {
    int  CntPos;               // количество ордеров в истории
    ulong nTicket;             // тикет выбранного ордера из истории
    ulong OldTicket = 0;       // тикет ордера найденного ранее
    long PosID, PosiID;        // идентификатор позиции, к которой относится выбранный ордер
    //long Magic;              // магический номер
    long Type;                 // тип найденного ордера (Buy или Sell)
    double OrderPrice = 0;     // найденная цена
    // идентификатор позиции
    if((PosiID = PositionGetInteger(POSITION_IDENTIFIER))==0) return(0.0);
    
    // создадим список ордеров и сделок, находящихся в истории
    HistorySelect(0, TimeCurrent());
    
    CntPos = HistoryOrdersTotal(); // количество ордеров в истории
    
    // переберем все ордеры истории и отберем те, что относятся к нашей открытой позиции
    for (int i = 0; i < CntPos; i++)
      {
        nTicket = HistoryOrderGetTicket(i);  // получим тикет очередного ордера
        PosID  = HistoryOrderGetInteger(nTicket, ORDER_POSITION_ID);  // позиция ордера
        Type   = HistoryOrderGetInteger(nTicket, ORDER_TYPE);         // тип ордера
        
        if ((PosID == PosiID) && (Type == nMode)) 
          {
            if (nTicket > OldTicket)  // этот ордер был открыт позже найденного ранее
              {
                OrderPrice = HistoryOrderGetDouble(nTicket, ORDER_PRICE_OPEN); // цена открытия ордера
                OldTicket = nTicket; // запомним тикет
              };
          };
      };
      
    return(OrderPrice);
  };//---------------------------------------------------------------------------+

Не подскажите каким образом можно подсчитать кол-во вызовов ф-ции:
bool SendOrder(double price, double volume)

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



  if (OrderSend(request,result))

      {

      counter++;

      return(true);

      }

Но подсчет начинает вестись начиная от 118 , 119 или 120.

(каждый раз по разному)

Почему это может происходить?

Igor Konyashin
3130
Igor Konyashin  
В OnInit пропишите обнуление этого вашего counter.
Mike Kharkov
849
Mike Kharkov  
i_logic:
В OnInit пропишите обнуление этого вашего counter.
   Прописал - но тоже самое.
   В журнале начинается теперь отсчёт с 54-х. )
   P.S. Как именно у меня на данный момент код выглядит - я указал сообщением выше.
  (перезалил его сейчас.)
Anatoli Kazharski
59227
Anatoli Kazharski  
Mike_Kharkov:
   Прописал - но тоже самое.
   В журнале начинается теперь отсчёт с 54-х. )
   P.S. Как именно у меня на данный момент код выглядит - я указал сообщением выше.
  (перезалил его сейчас.)

1. Отследите этот момент выводом сообщения в журнал.

2. Или воспользуйтесь отладкой кода.

3. Или воспользуйтесь профилировщиком.

Что такое Отладка и Профилирование можно прочитать в справке MetaEditor

Mike Kharkov
849
Mike Kharkov  
tol64:

1. Отследите этот момент выводом сообщения в журнал.

2. Или воспользуйтесь отладкой кода.

3. Или воспользуйтесь профилировщиком.

Что такое Отладка и Профилирование можно прочитать в справке MetaEditor

    А есть какие то другие статьи(очень развернутые по отладке и профилировщику.) ?
    (Ещё лучше видео.)
    Пробовал как то разобраться во всем этом деле по этой(и ещё одной статье) - вообще ничего не понял. )
    Отслеживание момента с выводом тоже не совсем понял, что может дать это дело.
    (и главное как это все отслеживать?)
    Увидел я допустим, что сообщение первое равняется 54-м. И что это мне дает?

    Дальше, с каждым новым вызовом, значение прибавляется по 1-му.
    (И какой вывод я должен из этого сделать в данном случае?)  

    P.S. Уверен, что новичку(в программировании) подобные статьи о профилировании и отладке,
    вообще ни чего не дадут в плане получения навыков. )

  
Anatoli Kazharski
59227
Anatoli Kazharski  
Mike_Kharkov:

...

P.S. Уверен, что новичку (в программировании) подобные статьи о профилировании и отладке, вообще ни чего не дадут в плане получения навыков. )

Нужно не пробовать как-то, а взять и разобраться с этим раз и навсегда. Читайте справку по редактору кода (MetaEditor) и пробуйте. В справке всё очень подробно написано. Статьи на сайте тоже есть по этой теме (воспользуйтесь поиском). Если все разобрались, то и Вы сможете.

Увидел я допустим, что сообщение первое равняется 54-м. И что это мне дает?

Если обнуляете переменную при инициализации, то в самом начале будет ноль. 

P.S. После изменений скомпилируйте код снова, а то вдруг забыли. )) 

Alexander Laur
7917
Alexander Laur  
Mike_Kharkov:
 ...
Не подскажите каким образом можно подсчитать кол-во вызовов ф-ции:

Переменную counter нужно расположить до первого ВОЗМОЖНОГО прерывания функции оператором return()

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

Mike Kharkov
849
Mike Kharkov  
papaklass:

Переменную counter нужно расположить до первого ВОЗМОЖНОГО прерывания функции оператором return()

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

   Если вы имеете ввиду:
//функция формирующая торговый запрос на открытие позиции
//и проверки результата открытия
bool SendOrder(double price, double volume)
{
   counter++;
   MqlTradeRequest request = {0};
   MqlTradeResult  result  = {0};
  
//---заполняем поля торгового запроса
   request.action       = TRADE_ACTION_DEAL;    // Тип выполняемого действия
   request.symbol       = _Symbol;              // Имя торгового инструмента
   request.volume       = volume;               // Запрашиваемый объем сделки в лотах
   request.price        = price;                // Цена  
   request.type         = ORDER_TYPE_BUY;       // Тип ордера
   request.tp           = price + 450*_Point;   // Цена, по которой сработает Take Profit ордер при движении цены в благоприятном направлении
   request.sl           = 0;                    // Цена, по которой сработает Stop Loss ордер при движении цены в неблагоприятном направлении
   request.type_filling = ORDER_FILLING_FOK;    // Тип ордера по исполнению
   request.type_time    = ORDER_TIME_GTC;
   
//---проверим хватает ли средств для открытия позиции
   double margin = 0.0;
   
   if (!OrderCalcMargin(request.type, request.symbol, request.volume, request.price, margin))
      return(false);
   
   if (margin > AccountInfoDouble(ACCOUNT_FREEMARGIN))
      return(false);

   
//---отправка запроса на сервер и проверка результата отправки
   if (OrderSend(request,result))
      {
      return(true);
      }
   else
      Print(__FUNCTION__,"   При выставлении ордера произошла ошибка. Error = ",GetLastError());
                                    
   return(false);
}//---------------------------------------------------------------------------+
то при таком варианте в журнале самый первый вызов получает номер 8-мь.
Алексей Тарабанов
7328
Алексей Тарабанов  
Mike_Kharkov:
   Если вы имеете ввиду:
то при таком варианте в журнале самый первый вызов получает номер 8-мь.
Переименуйте переменную counter. 
Mike Kharkov
849
Mike Kharkov  
tara:
Переименуйте переменную counter. 
   В общем часть проблемы состояла в том что в журнале у меня не помещалась вся история, начиная с самого начала.
   Поэтому стартовый порядковый номер счетчика и был таким большим.(обрезалась история просто.)
   Далее заметил, что никогда не бывает(в принтах) порядкового номера 1!
   Решил это путем добавления принта(счетчика) в функцию вызова первого ордера.
   И пока остается ещё одна проблема - это то что после закрытия позиции счетчик вызова функции
   не обнуляется и открытие следующей позиции начинается с отсчета порядкового номера, который заканчивался на прошлой позиции.
   (если прошлая позиция имела 3-й номер ордера- то следующая позиция откроется начиная с 4-го порядкового номера(счетчика).)
   Не подскажите что можно прописать для этого случая?
   (точнее как это сделать наиболее правильно с семантической точки зрения.)
Artyom Trishkin
Модератор
80144
Artyom Trishkin  
Mike_Kharkov:
   В общем часть проблемы состояла в том что в журнале у меня не помещалась вся история, начиная с самого начала.
   Поэтому стартовый порядковый номер счетчика и был таким большим.(обрезалась история просто.)
   Далее заметил, что никогда не бывает(в принтах) порядкового номера 1!
   Решил это путем добавления принта(счетчика) в функцию вызова первого ордера.
   И пока остается ещё одна проблема - это то что после закрытия позиции счетчик вызова функции
   не обнуляется и открытие следующей позиции начинается с отсчета порядкового номера, который заканчивался на прошлой позиции.
   (если прошлая позиция имела 3-й номер ордера- то следующая позиция откроется начиная с 4-го порядкового номера(счетчика).)
   Не подскажите что можно прописать для этого случая?
   (точнее как это сделать наиболее правильно с семантической точки зрения.)
После успешного закрытия позиции, проверьте состояние счётчика и, если требуется, обнулите.
12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий