Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2709

 
Vitaly Muzichenko #:

В общем, у вас коде такой-же бардак, какой происходил всегда и до сих пор происходит - дурилка!

Вы путаете ордера и позиции. Нужно понимать, что Buy/Sell это не ордера, а позиции. Ордер не может быть закрыт - он может быть только удалён или перемещён, ордер не бывает ни прибыльным, ни убыточным.

Позицию нельзя удалить или переместить - только закрыть с прибылью или убытком.

--

P.S. Когда ГУРУ путаются и пишут что у них один ордер прибыльный, а другой убыточный = всегда хочется ответить, чтобы убыточный перенесли в прибыльную зону и закрыли оба.

Но так как у них это совершенно не ордер а позиция, а эти ГУРУ и об этом не знают, то перенести нельзя.

--

НЕ путайте ордера и позиции.

Vitaly Muzichenko #:

В общем, у вас коде такой-же бардак, какой происходил всегда и до сих пор происходит - дурилка!

Вы путаете ордера и позиции. Нужно понимать, что Buy/Sell это не ордера, а позиции. Ордер не может быть закрыт - он может быть только удалён или перемещён, ордер не бывает ни прибыльным, ни убыточным.

Позицию нельзя удалить или переместить - только закрыть с прибылью или убытком.

--

P.S. Когда ГУРУ путаются и пишут что у них один ордер прибыльный, а другой убыточный = всегда хочется ответить, чтобы убыточный перенесли в прибыльную зону и закрыли оба.

Но так как у них это совершенно не ордер а позиция, а эти ГУРУ и об этом не знают, то перенести нельзя.

--

НЕ путайте ордера и позиции.

Спасибо. Было очень поучительно... но не совсем понятно. В своем коде в функциях History ...Get я везде оперирую сделками(Deal), а не ордерами и не позициями. И я знаю что между позициями, сделками и ордерами в mql5  большая разница. С ордерами я оперирую только  в одном месте кода в функции HistoryOrdersTotal() что бы понимать сколько итераций делать в цикле.

Возможно в моем коде бардак, и возможно он дурилка ( думаю, что дурилкой Вы назвали именно мой код...). Но я  к сожалению бардака  не вижу пока. Я был бы Вам очень признателен, если бы Вы, то что мне нужно сделать в коде(логику кода) но без бардака изложили в своей версии кода. Я сравнил бы свой код с Вашим , и тогда в моей голове все разложилось бы по нужным полочкам. Все познается в сравнении...

А логика моего кода очень простая. В течении  1 дня я выставил 97  рыночных ордеров БАЙ и открыл столько же сделок , и почти все сделки закрылись по ТП или СЛ  до истечения этого 1 дня. Таким образом все мои сделки, позиции и ордера попали в список истории. И в коде мне нужно, пройтись в цикле по всему списку закрытых сделок , и выбрать из них однократно  только те сделки, которые закрылись по ТП и сохранить в переменные только 2 свойства этих выбранных сделок
1.Время закрытия сделки по ТП( как я это сделать, я понимаю)
2.Время открытия сделки, которая закрылась по ТП ( как это сделать я не понимаю до сих пор , и не понял из Вашего последнего поста)

 
ANDREY #:

Спасибо. Было очень поучительно... но не совсем понятно. В своем коде в функциях History ...Get я везде оперирую сделками(Deal), а не ордерами и не позициями. И я знаю что между позициями, сделками и ордерами в mql5  большая разница. С ордерами я оперирую только  в одном месте кода в функции HistoryOrdersTotal() что бы понимать сколько итераций делать в цикле.

Возможно в моем коде бардак, и возможно он дурилка ( думаю, что дурилкой Вы назвали именно мой код...). Но я  к сожалению бардака  не вижу пока. Я был бы Вам очень признателен, если бы Вы, то что мне нужно сделать в коде(логику кода) но без бардака изложили в своей версии кода. Я сравнил бы свой код с Вашим , и тогда в моей голове все разложилось бы по нужным полочкам. Все познается в сравнении...

А логика моего кода очень простая. В течении  1 дня я выставил 97  рыночных ордеров БАЙ и открыл столько же сделок , и почти все сделки закрылись по ТП или СЛ  до истечения этого 1 дня. Таким образом все мои сделки, позиции и ордера попали в список истории. И в коде мне нужно, 1 раз в час , пройтись в цикле по всему списку закрытых сделок , выбрать из них только те сделки, которые закрылись по ТП и сохранить в переменные только 2 свойства этих выбранных сделок
1.Время закрытия сделки по ТП( как я это сделать, я понимаю)
2.Время открытия сделки, которая закрылась по ТП ( как это сделать я не понимаю до сих пор , и не понял из Вашего последнего поста)

вы статью прочитали? 

см. time переменную может поможет....

Пример подобного алгоритма для подсчета прибылей и убытков:

input long my_magic=111;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
// --- определение границ требуемой торговой истории
   datetime end=TimeCurrent();                 // текущее серверное время
   datetime start=end-PeriodSeconds(PERIOD_D1);// установим начало на сутки назад
//--- запросим в кэш программы нужный интервал торговой истории
   HistorySelect(start,end);
//--- получим количество сделок в истории
   int deals=HistoryDealsTotal();

   int returns=0;
   double profit=0;
   double loss=0;
//--- пройдем по всем сделкам в истории
   for(int i=0;i<deals;i++)
     {
      //--- получим тикет сделки по ее индексу в списке
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0) // получили в кэш сделку, работаем с ней
        {
         string symbol             =HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
         datetime time             =HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         ulong order               =HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
         long order_magic          =HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
         long pos_ID               =HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
         ENUM_DEAL_ENTRY entry_type=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);

         //--- обрабатываем сделки с указанным DEAL_MAGIC
         if(order_magic==my_magic)
           {
            //... необходимые действия
           }

         //--- посчитаем убытки и прибыли с фиксаций результата
         if(entry_type==DEAL_ENTRY_OUT)
           {
            //--- увеличим количество сделок 
            returns++;
            //--- результат фиксации
            double result=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
            //--- занесем положительный результат в суммарную прибыль
            if(result>0) profit+=result;
            //--- занесем отрицательный результат в суммарный убыток
            if(result<0) loss+=result;
           }
        }
      else // неудачная попытка получения сделки
        {
         PrintFormat("Не удалось выбрать сделку с индексом %d. Ошибка %d",
                     i,GetLastError());
        }
     }
   //--- выведем результаты подсчетов
   PrintFormat("Всего %d сделок с фиксаций результата. Прибыль=%.2f , Убыток= %.2f",
               returns,profit,loss);
  }
Важно: всегда внимательно относитесь ко всем случаям вызова функции HistorySelect()! Необдуманные и избыточные загрузки всей доступной торговой истории в кэш mql5-программы ухудшат ее производительность.
Ордерa, позиции и сделки в MetaTrader 5
Ордерa, позиции и сделки в MetaTrader 5
  • 2011.01.05
  • www.mql5.com
Надежный торговый робот не может быть создан без понимания механизмов работы торговой системы MetaTrader 5. Клиентский терминал получает от торгового сервера информацию о позициях, ордерах и сделках. Чтобы правильно обработать эти данные средствами MQL5 необходимо хорошо представлять как происходит взаимодействие mql5-программы и среды исполнения терминала.
 
Roman Shiredchenko #:
//--- пройдем по всем сделкам в истории

Большое спасибо за помощь. Мне нужно научиться вычислять  вот что....

Например, в 18:00 открылась сделка БАЙ . А в 18:30 эта сделка закрылась по ТП сделкой СЛ. Данные сделки  БАЙ и СЕЛ есть в списке истории ордеров, позиций, сделок.
Выбрать в цикле  из истории данную сделку СЕЛ  я научился. Сохранить в переменную свойство этой сделки - время открытия СЕЛ (18:30)(оно же время закрытия БАЙ) я научился. А вот одновременно  сохранить в другую переменную время открытия (18:00) закрытой сделки БАЙ я пока не умею.

ВОПРОС 

Поскольку логика Вашего кода сильно отличается от того что мне нужно, скажите в каком месте Вашего кода я могу научиться делать то чему хочу научиться? Или в каком месте статьи? А именно научиться сохранять в переменную время открытия сделки которая закрылась по ТП. В Вашем коде сохраняется в переменную время открытия сделки, которая закрылась по ТП?

 
ANDREY #:

Большое спасибо за помощь. Мне нужно научиться вычислять  вот что....

Например, в 18:00 открылась сделка БАЙ . А в 18:30 эта сделка закрылась по ТП сделкой СЛ. Данные сделки  БАЙ и СЕЛ есть в списке истории ордеров, позиций, сделок.
Выбрать в цикле  из истории данную сделку СЕЛ  я научился. Сохранить в переменную свойство этой сделки - время открытия СЕЛ (18:30)(оно же время закрытия БАЙ) я научился. А вот одновременно  сохранить в другую переменную время открытия (18:00) закрытой сделки БАЙ я пока не умею.

ВОПРОС 

Поскольку логика Вашего кода сильно отличается от того что мне нужно, скажите в каком месте Вашего кода я могу научиться делать то чему хочу научиться? Или в каком месте статьи? А именно научиться сохранять в переменную время открытия сделки которая закрылась по ТП. В Вашем коде сохраняется в переменную время открытия сделки, которая закрылась по ТП?

попробуйте разобраться в IN и OUT и поэкспериментировать: 

input long my_magic = 111;

//+------------------------------------------------------------------+
//| Script program start function                                |
//+------------------------------------------------------------------+
void OnStart()
{
   // --- определение границ требуемой торговой истории
   datetime end = TimeCurrent();
   datetime start = end - PeriodSeconds(PERIOD_D1); // сутки назад

   if (!HistorySelect(start, end))
   {
      PrintFormat("Не удалось загрузить торговую историю. Ошибка %d", GetLastError());
      return;
   }

   int deals = HistoryDealsTotal();
   int tp_count = 0;
   double total_profit = 0, total_loss = 0;

   // --- массив для хранения времени открытия сделок, закрытых по ТП
   datetime tp_open_times[];
   ArrayResize(tp_open_times, deals);

   for (int i = 0; i < deals; i++)
   {
      ulong deal_ticket = HistoryDealGetTicket(i);
      if (deal_ticket == 0)
      {
         PrintFormat("Ошибка получения сделки с индексом %d. Код ошибки: %d", i, GetLastError());
         continue;
      }

      long order_magic = HistoryDealGetInteger(deal_ticket, DEAL_MAGIC);
      ENUM_DEAL_ENTRY entry_type = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket, DEAL_ENTRY);
      double profit_val = HistoryDealGetDouble(deal_ticket, DEAL_PROFIT);
      long pos_ID = HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID);

      // --- проверяем: нужный magic, выход из позиции, прибыль > 0 (ТП)
      if (order_magic == my_magic && entry_type == DEAL_ENTRY_OUT && profit_val > 0)
      {
         // --- ищем время открытия для этой позиции
         datetime open_time = FindOpenTimeForPosition(pos_ID, start, end);

         if (open_time != 0) // сделка открытия найдена
         {
            // --- сохраняем время открытия
            tp_open_times[tp_count] = open_time;
            tp_count++;

            // --- выводим время ОТКРЫТИЯ сделки
            PrintFormat("Сделка закрыта по ТП. Позиция ID: %d, Время открытия: %s, Прибыль: %.2f",
                       pos_ID, TimeToString(open_time), profit_val);
         }
         else
         {
            PrintFormat("Для позиции ID %d не найдено время открытия", pos_ID);
         }

         // --- общий подсчёт прибыли/убытков
         if (profit_val > 0) total_profit += profit_val;
         else total_loss += profit_val;
      }
   }

   // --- итоговая статистика
   PrintFormat("Всего сделок с фиксацией результата: %d. Прибыль=%.2f, Убыток=%.2f", deals, total_profit, total_loss);
   PrintFormat("Найдено %d сделок, закрытых по ТП, с сохранённым временем открытия.", tp_count);
}

//+------------------------------------------------------------------+
//| Функция для поиска времени ОТКРЫТИЯ позиции по её ID            |
//+------------------------------------------------------------------+
datetime FindOpenTimeForPosition(long position_id, datetime start, datetime end)
{
   if (!HistorySelect(start, end)) return 0;

   int deals = HistoryDealsTotal();

   for (int i = 0; i < deals; i++)
   {
      ulong deal_ticket = HistoryDealGetTicket(i);
      if (deal_ticket > 0)
      {
         long pos_ID = HistoryDealGetInteger(deal_ticket, DEAL_POSITION_ID);
         ENUM_DEAL_ENTRY entry_type = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket, DEAL_ENTRY);

         // --- ищем сделку ОТКРЫТИЯ (DEAL_ENTRY_IN) для указанного ID позиции
         if (pos_ID == position_id && entry_type == DEAL_ENTRY_IN)
         {
            return HistoryDealGetInteger(deal_ticket, DEAL_TIME); // время открытия
         }
      }
   }
   return 0; // не найдено
}
 
ANDREY #:

Большое спасибо за помощь. Мне нужно научиться вычислять  вот что....

Например, в 18:00 открылась сделка БАЙ . А в 18:30 эта сделка закрылась по ТП сделкой СЛ. Данные сделки  БАЙ и СЕЛ есть в списке истории ордеров, позиций, сделок.
Выбрать в цикле  из истории данную сделку СЕЛ  я научился. Сохранить в переменную свойство этой сделки - время открытия СЕЛ (18:30)(оно же время закрытия БАЙ) я научился. А вот одновременно  сохранить в другую переменную время открытия (18:00) закрытой сделки БАЙ я пока не умею.

ВОПРОС 

Поскольку логика Вашего кода сильно отличается от того что мне нужно, скажите в каком месте Вашего кода я могу научиться делать то чему хочу научиться? Или в каком месте статьи? А именно научиться сохранять в переменную время открытия сделки которая закрылась по ТП. В Вашем коде сохраняется в переменную время открытия сделки, которая закрылась по ТП?

struct st
  {
   datetime          in;
   datetime          out;
  };
st mSt[];
//+------------------------------------------------------------------+
void OnStart()
  {
   datetime  from_date = iTime(_Symbol, PERIOD_D1, 0);
   datetime  to_date = TimeCurrent();
   DealsTime(from_date, to_date);
  }
//+------------------------------------------------------------------+
int DealsTime(datetime  from_date, datetime  to_date)
  {
   int size = 0;
   long position_ID = 0;

   if(HistorySelect(from_date, to_date))
     {
      int total = HistoryDealsTotal();
      ArrayResize(mSt, total);

      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
        {
         ulong ticket = HistoryDealGetTicket(i);
         if(ticket > 0)
            if(HistoryDealGetInteger(ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
              {
               mSt[size].out = (datetime)HistoryDealGetInteger(ticket, DEAL_TIME);
               position_ID = HistoryDealGetInteger(ticket, DEAL_POSITION_ID);
               for(int x = i - 1; x >= 0; x--)
                 {
                  ticket = HistoryDealGetTicket(x);
                  if(position_ID == HistoryDealGetInteger(ticket, DEAL_POSITION_ID))
                    {
                     mSt[size].in = (datetime)HistoryDealGetInteger(ticket, DEAL_TIME);
                     size++;
                     break;
                    }
                 }
              }
        }
     }

   ArrayResize(mSt, size);

   ArrayPrint(mSt);
   return size;
  }
//+------------------------------------------------------------------+
Скрипт. Распечатает все закрытые сегодня позиции, при условии, что открыты они были тоже сегодня. Не будет правильно работать, если позиции закрывались частями.
 
ANDREY #:

Спасибо. Было очень поучительно... но не совсем понятно. В своем коде в функциях History ...Get я везде оперирую сделками(Deal), а не ордерами и не позициями. И я знаю что между позициями, сделками и ордерами в mql5  большая разница. С ордерами я оперирую только  в одном месте кода в функции HistoryOrdersTotal() что бы понимать сколько итераций делать в цикле.

Возможно в моем коде бардак, и возможно он дурилка ( думаю, что дурилкой Вы назвали именно мой код...). Но я  к сожалению бардака  не вижу пока. Я был бы Вам очень признателен, если бы Вы, то что мне нужно сделать в коде(логику кода) но без бардака изложили в своей версии кода. Я сравнил бы свой код с Вашим , и тогда в моей голове все разложилось бы по нужным полочкам. Все познается в сравнении...

А логика моего кода очень простая. В течении  1 дня я выставил 97  рыночных ордеров БАЙ и открыл столько же сделок , и почти все сделки закрылись по ТП или СЛ  до истечения этого 1 дня. Таким образом все мои сделки, позиции и ордера попали в список истории. И в коде мне нужно, пройтись в цикле по всему списку закрытых сделок , и выбрать из них однократно  только те сделки, которые закрылись по ТП и сохранить в переменные только 2 свойства этих выбранных сделок
1.Время закрытия сделки по ТП( как я это сделать, я понимаю)
2.Время открытия сделки, которая закрылась по ТП ( как это сделать я не понимаю до сих пор , и не понял из Вашего последнего поста)

Если вы перебираете сделки, то и запрашивать надо количество сделок. Ордеров в истории может быть меньше чем сделок.

Если хотите получить время открытия позиции, то ищите сделку DEAL_ENTRY_IN а для получения времени закрытия ищите сделку DEAL_ENTRY_OUT

Они связаны идентификатором позиции.

Документация по MQL5: HistorySelectByPosition / Торговые функции
Документация по MQL5: HistorySelectByPosition / Торговые функции
  • www.mql5.com
Запрашивает историю сделок и ордеров, имеющих указанный идентификатор позиции. Параметры position_id [in]  Идентификатор позиции, который...
 
Roman Shiredchenko #:

попробуйте разобраться в IN и OUT и поэкспериментировать: 

Спасибо...уже теплее...
 
Aleksandr Slavskii #:
Скрипт. Распечатает все закрытые сегодня позиции, при условии, что открыты они были тоже сегодня. Не будет правильно работать, если позиции закрывались частями.
Спасибо. То есть если позиции закрылись сегодня, но открылись не сегодня .... тогда не распечатает. Мне это не подходит. Мне нужно вычислять время открытия закрытых позиций .... При этом время открытия закрытой позиции  может быть в любой день.
 
Alexey Viktorov #:

Если вы перебираете сделки, то и запрашивать надо количество сделок. Ордеров в истории может быть меньше чем сделок.

Если хотите получить время открытия позиции, то ищите сделку DEAL_ENTRY_IN а для получения времени закрытия ищите сделку DEAL_ENTRY_OUT

Они связаны идентификатором позиции.

Спасибо. Мне кажется Ваш ответ самый релевантный для меня.
 
ANDREY #:
Мне это не подходит. 

Понятно, в код даже не заглянул.

Удачи в освоении MQL оно будет долгим.