Новая версия платформы MetaTrader 5 build 1730: Проекты в MetaEditor и синтетические инструменты - страница 3

 
Renat Fatkhullin:
этот кусок кода я писал год назад по справке(значит там были такие рекомендации), и все работало и работает на терминалах которые еще не успели обновиться
 
Pavel Kolchin:
этот кусок кода я писал год назад по справке(значит там были такие рекомендации), и все работало и работает на терминалах которые еще не успели обновиться

1) вы сделали заявление, прямо противоречащее документации и здравому смыслу

2) вы не показали кода

3) ошибка в другом месте возможно

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

 
Renat Fatkhullin:

было (и работало)

      int t_pt=PositionsTotal()-1;for(int i=0;i<=t_pt;i++){
         if(!PositionSelectByTicket(PositionGetTicket(i))){continue;}
         if(!HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER))){continue;}
         int t_hdt=HistoryDealsTotal()-1;for(int j=0;j<=t_hdt;j++){
            if(!HistoryDealGetTicket(j)){continue;}
            if(HistoryDealGetInteger(j,DEAL_MAGIC)==int_num){...}
         }
      }

теперь чтобы работало сделал так

      int t_pt=PositionsTotal()-1;for(int i=0;i<=t_pt;i++){
         if(!PositionSelectByTicket(PositionGetTicket(i))){continue;}
         if(!HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER))){continue;}
         int t_hdt=HistoryDealsTotal()-1;for(int j=0;j<=t_hdt;j++){
            ulong t_hdgt=HistoryDealGetTicket(j);if(!t_hdgt){continue;}
            if(HistoryDealGetInteger(t_hdgt,DEAL_MAGIC)==int_num){...}
         }
      }
 
Pavel Kolchin:

было (и работало)

теперь чтобы работало сделал так

Во первых, код написан в режиме самострела. Так писать категорически нельзя - в нем ошибок наделано наверняка немало.

Во вторых, вы утверждаете, что раньше вот такой код работал?

      int t_hdt=HistoryDealsTotal()-1;
      for(int j=0;j<=t_hdt;j++)
        {
         if(!HistoryDealGetTicket(j))
            continue;
         if(HistoryDealGetInteger(j,DEAL_MAGIC)==int_num)
           {
           }
        }

Вы же передаете индекс j вместо тикета. Он и не должен был работать.

Только в тестере иногда получалось, да и то не на всех операциях. Просто там индексы от нуля могли попадать на номера тикетов, начинающиеся с единицы.

Мое мнение - безусловно ошибки в вашем коде и работа в тестере без проверок на демо/реальных счетах.

 
Renat Fatkhullin:

Вы же передаете индекс j вместо тикета. Он и не должен был работать.

но работал, вот у меня еще не все терминалы обновились)

      string com = "";
      
      int t_pt=PositionsTotal()-1;for(int i=0;i<=t_pt;i++){
         if(!PositionSelectByTicket(PositionGetTicket(i))){continue;}
         if(!HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER))){continue;}
         int t_hdt=HistoryDealsTotal()-1;for(int j=0;j<=t_hdt;j++){
            if(!HistoryDealGetTicket(j)){continue;}

            com+="j="+j+"\n";
            com+="HistoryDealGetInteger(j,DEAL_TICKET)="+HistoryDealGetInteger(j,DEAL_TICKET)+"\n";
            com+="HistoryDealGetInteger(j,DEAL_TIME)="+HistoryDealGetInteger(j,DEAL_TIME)+"\n";
            com+="HistoryDealGetString(j,DEAL_SYMBOL)="+HistoryDealGetString(j,DEAL_SYMBOL)+"\n";
            com+="HistoryDealGetInteger(j,DEAL_TYPE)="+HistoryDealGetInteger(j,DEAL_TYPE)+"\n";
            com+="HistoryDealGetDouble(j,DEAL_VOLUME)="+HistoryDealGetDouble(j,DEAL_VOLUME)+"\n";
            com+="HistoryDealGetDouble(j,DEAL_PRICE)="+HistoryDealGetDouble(j,DEAL_PRICE)+"\n";
         }
      }
      Comment(com);



кстати зачем нужно было узнавать номер тикета если мы "всегда" сюда передавали номер тикета?

HistoryDealGetInteger(deal_ticket,DEAL_TICKET);
 

Я проверю. 

 

Вот ваш код, оформленный и правильно переписанный:

void OnStart(void)
  {
   string com="";
   int    t_pt=PositionsTotal();
//--- пройдемся по всем позициям
   for(int i=0;i<t_pt;i++)
     {
      //--- выберем очередную открытую позицию по индексу
      if(!PositionGetTicket(i))
         continue;
      //--- отфильтруем историю по идентификатору позиций
      if(!HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER)))
         continue;
      //--- пройдемся по новому отфильтрованному списку сделок 
      int t_hdt=HistoryDealsTotal();

      for(int j=0;j<t_hdt;j++)
        {
         ulong ticket=HistoryDealGetTicket(j);
         //--- если смогли получить тикет по индексу
         if(ticket)
           {
            com+="j="+j+"\n";
            com+="HistoryDealGetInteger(j,DEAL_TICKET)="+HistoryDealGetInteger(ticket,DEAL_TICKET)+"\n";
            com+="HistoryDealGetInteger(j,DEAL_TIME)="+HistoryDealGetInteger(ticket,DEAL_TIME)+"\n";
            com+="HistoryDealGetString(j,DEAL_SYMBOL)="+HistoryDealGetString(ticket,DEAL_SYMBOL)+"\n";
            com+="HistoryDealGetInteger(j,DEAL_TYPE)="+HistoryDealGetInteger(ticket,DEAL_TYPE)+"\n";
            com+="HistoryDealGetDouble(j,DEAL_VOLUME)="+HistoryDealGetDouble(ticket,DEAL_VOLUME)+"\n";
            com+="HistoryDealGetDouble(j,DEAL_PRICE)="+HistoryDealGetDouble(ticket,DEAL_PRICE)+"\n";
           }
        }
     }
   Comment(com);
//---
  }

У вас на самом деле была ошибка в передаче индекса j вместо номера тикета в функциях HistoryDealGetXXXX.

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

В 1730 билде мы нашли и исправили эту ошибку(теперь сбрасываем кеш при неудаче поиска), в результате чего проявилась ваша ошибка обращения по неверному тикету.

 
Renat Fatkhullin:

я понимаю что сейчас правильно так, но остается два вопроса


о какой дальнейшей обработке идет речь?


HistoryDealGetInteger(deal_ticket,DEAL_TICKET);

зачем предусмотрено свойство DEAL_TICKET, если для вызова функции HistoryDealGetInteger() обязательно необходимо знать тикет сделки?

 
Pavel Kolchin:

я понимаю что сейчас правильно так, но остается два вопроса

о какой дальнейшей обработке идет речь?

Посмотрите статью Ордерa, позиции и сделки в MetaTrader 5 - для того чтобы работать со свойствами ордера/позиции/сделки, необходимы их предварительно выбрать. То есть получить эти данные в кеш для последующего считывания (обработки)
 
Pavel Kolchin:

HistoryDealGetInteger(deal_ticket,DEAL_TICKET);

зачем предусмотрено свойство DEAL_TICKET, если для вызова функции HistoryDealGetInteger() обязательно необходимо знать тикет сделки?

Эти свойства были добавлены позже для единообразия. Так как являются такими же атрибутами торговой сущности как и остальные свойства.

Получилось немного "масло масляное".