Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXI): Торговые классы - Базовый кроссплатформенный торговый объект" - страница 3

 
Artyom Trishkin:
Если вам нужно сравнить торговую заявку и позицию, то самый простой способ - установить идентификатор позиции (не волшебный). Каждая заявка имеет свой идентификатор. Магию советника можно оставить одной для всех позиций. Тогда по идентификатору (он записан в магии позиции или ордера и никогда не потеряется) можно в любой момент точно сопоставить заявку и позицию/ордер.

Это что-то вроде этого?

Торговый запрос:

ulong order_magic = m_engine.SetCompositeMagicNumber(m_magic, 0, 0, m_order_id);
bool submit_ok    = m_engine.PlaceBuyLimit(m_lot_size, m_symbol, m_entry, m_hard_stop, m_ratio_target, order_magic, m_comment, m_expiry);

Обработчик события:

void CMyRobot::EngineEventHandler(int event_id, const long &lparam, const double &dparam, const string &sparam, bool testing, long chart_id)
{
   if (sparam != m_symbol) return;                                                  //--- пропустите обработку событий при несовпадении символов

   if (event_id > SERIES_EVENTS_NO_EVENT && event_id < SERIES_EVENTS_NEXT_CODE) {   //--- ОБРАБОТКА СОБЫТИЙ ВРЕМЕННЫХ РЯДОВ
      if (event_id == SERIES_EVENTS_NEW_BAR) {                                      // Событие "новый бар": lparam = период | dparam = дата/время
         this.RefreshAllIndicators(1);
         this.ExecuteFSM(1, chart_id);                                              // выполняем конечный автомат (NB: индекс нового бара = 1)
      }
   }
   else
   if (event_id > TRADE_EVENT_NO_EVENT && event_id < TRADE_EVENTS_NEXT_CODE) {      //--- ОБРАБОТКА ТОРГОВЫХ СОБЫТИЙ
      CArrayObj *event_list = m_engine.GetListAllOrdersEvents();                    // получить список торговых событий
      if (event_list == NULL) return;
      
      //--- вычисляем сдвиг индекса события относительно конца списка
      //--- при обратном тестировании значение сдвига передается в параметре 'lparam' обработчику события
      //--- в обычной работе торговые события отправляются по одному и обрабатываются в OnChartEvent().
      int shift = testing ? (int)lparam : 0;
      CEvent *event = event_list.At(event_list.Total() - 1 - shift);
      if (event == NULL || event.GetPendReqID() != m_order_id) return;
      
      switch (event.TypeEvent())
      {
         case TRADE_EVENT_PENDING_ORDER_PLASED:                                     //--- размещен отложенный ордер
            if (m_state_curr == FSM_PENDING_ORDER && m_ticket == WRONG_VALUE)
                m_ticket = event.TicketOrderEvent();
            break;
      
         // ...
      }
   }
}
 

Проблема: метод CEvent::GetPendReqID(), который мне нужен, находится выше protected!! Есть идеи получше, без необходимости изменять исходный код DoEasy? По моему скромному мнению, эти методы должны быть публичными;-)

class CEvent : public CObject
  {
//...
protected:
//--- Возвращаем (1) указанное магическое число, ID (2) первой группы, (3) второй группы, (4) ожидающий запрос от значения магического числа
   ushort            GetMagicID(void)                          const { return ushort(this.Magic() & 0xFFFF);                                 }
   uchar             GetGroupID1(void)                         const { return uchar(this.Magic()>>16) & 0x0F;                                }
   uchar             GetGroupID2(void)                         const { return uchar((this.Magic()>>16) & 0xF0)>>4;                           }
   uchar             GetPendReqID(void)                        const { return uchar(this.Magic()>>24) & 0xFF;                                }
//...
};
 
Dima Diall :

Проблема: метод CEvent::GetPendReqID(), который мне нужен, находится выше protected !! Есть идеи получше, без необходимости изменять исходный код DoEasy? По моему скромному мнению, эти методы должны быть публичными;-)

Вам нужно следить за классом CEngine - только он дает доступ к библиотеке пользовательским программам.

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

 
Artyom Trishkin:

Вам нужно посмотреть класс CEngine - только он дает доступ к библиотеке пользовательским программам.

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

Не могли бы вы привести пример? Я смотрю на класс CEngine и вижу, что можно извлечь список событий, проверить их тип и т.д... так что я могу получить доступ к каждому событию, но не нахожу очевидного способа прочитать конкретные детали события, упакованные в магическое число (группы и ID запроса) из объекта CEngine - как я вижу, мне все еще нужно читать эту информацию непосредственно из экземпляров объекта CEvent, как в моем примере обработчика событий выше в методе четного обработчика моего робота, т.е. CEvent:GetPendReq()

class CEngine
  {
//...
//...
//--- Возвращает (1) список событий ордера, сделки и позиции, (2) базовый объект торгового события по индексу и (3) количество новых торговых событий
   CArrayObj           *GetListAllOrdersEvents(void)                    { return this.m_events.GetList();                     }
   CEventBaseObj       *GetTradeEventByIndex(const int index)           { return this.m_events.GetTradeEventByIndex(index);   }
   int                  GetTradeEventsTotal(void)                 const { return this.m_events.GetTradeEventsTotal();         }
//--- Сброс последнего торгового события
   void                 ResetLastTradeEvent(void)                       { this.m_events.ResetLastTradeEvent();                }
//--- Возвращаем (1) последнее торговое событие, (2) последнее событие в свойствах счета и (3) последнее событие в свойствах символа
   ENUM_TRADE_EVENT     LastTradeEvent(void)                      const { return this.m_last_trade_event;                     }
   int                  LastAccountEvent(void)                    const { return this.m_last_account_event;                   }
   int                  LastSymbolsEvent(void)                    const { return this.m_last_symbol_event;                    }
//--- Верните флаг (1) хеджевого счета, (2) работы в тестере, (3) события счета, (4) события символа и (5) торгового события
   bool                 IsHedge(void)                             const { return this.m_is_hedge;                             }
   bool                 IsTester(void)                            const { return this.m_is_tester;                            }
   bool                 IsAccountsEvent(void)                     const { return this.m_accounts.IsEvent();                   }
   bool                 IsSymbolsEvent(void)                      const { return this.m_symbols.IsEvent();                    }
   bool                 IsTradeEvent(void)                        const { return this.m_events.IsEvent();                     }
//...
//...
  };
 
Dima Diall :

Не могли бы вы привести мне пример? Я смотрю на класс CEngine и вижу, что можно извлечь список событий, проверить их тип и т. Д., Поэтому я могу получить доступ к каждому событию, но не нахожу очевидного способа прочитать конкретные детали событий, упакованные в магическое число (группа и идентификатор запроса) из объекта CEngine - Как я вижу, мне все еще нужно читать эту информацию непосредственно из экземпляров объекта CEvent, как в моем примере обработчика событий выше в методе обработчика четных событий моего робота, то есть CEvent :: GetPendReqID ()

Подождите немного, пожалуйста. Следующая статья в ru-сегменте будет посвящена советникам, и там я постараюсь все объяснить.

 
Artyom Trishkin:

Подождите немного, пожалуйста. Следующая статья в ru-сегменте будет посвящена советникам, и там я постараюсь все объяснить.

Хорошо, круто - спасибо...