//+------------------------------------------------------------------+ //| PendingOrders.mqh | //| Copyright 2016, Vasiliy Sokolov, St-Petersburg, Russia | //| https://www.mql5.com/ru/users/c-4 | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, Vasiliy Sokolov." #property link "https://www.mql5.com/ru/users/c-4" #include #include "Dictionary.mqh" //+------------------------------------------------------------------+ //| Класс представляющий отложенный ордер | //+------------------------------------------------------------------+ class CPendingOrder : public CObject { private: ulong m_ticket; CTrade m_trade; public: CPendingOrder(ulong ticket); ulong ExpertMagic(void); string Symbol(void); string Comment(void); ENUM_ORDER_TYPE Type(void); ENUM_ORDER_STATE State(void); ENUM_ORDER_TYPE_FILLING TypeFilling(void); ENUM_ORDER_TYPE_TIME TypeTime(void); ulong Ticket(void); datetime TimeExp(void); datetime TimeDone(void); datetime TimeSetup(void); long TimeSetupMsc(void); long TimeDoneMsc(void); long PositionID(void); long PositionByID(void); double VolumeInit(void); double VolumeCurrent(void); double PriceOpen(void); double PriceCurrent(void); double StopLoss(void); double TakeProfit(void); bool IsMain(string symbol, ulong magic); bool Modify(const double price,const double sl,const double tp, const ENUM_ORDER_TYPE_TIME type_time,const datetime expiration,const double stoplimit=0.0); bool Modify(double price); bool Delete(void); ENUM_POSITION_TYPE Direction(void); }; //+------------------------------------------------------------------+ //| Создаем класс отложенного ордера | //+------------------------------------------------------------------+ CPendingOrder::CPendingOrder(ulong ticket) { if(!OrderSelect(ticket)) m_ticket = 0; else m_ticket = ticket; } //+------------------------------------------------------------------+ //| Модифицирует отложенный ордер | //+------------------------------------------------------------------+ bool CPendingOrder::Modify(const double price,const double sl,const double tp, const ENUM_ORDER_TYPE_TIME type_time,const datetime expiration,const double stoplimit=0.0) { return m_trade.OrderModify(m_ticket, price, sl, tp, type_time, expiration, stoplimit); } //+------------------------------------------------------------------+ //| Модифицирует отложенный ордер | //+------------------------------------------------------------------+ bool CPendingOrder::Modify(double price) { return m_trade.OrderModify(m_ticket, price, StopLoss(), TakeProfit(), TypeTime(), TimeExp(), 0.0); } //+------------------------------------------------------------------+ //| Удаляет отложенный ордер | //+------------------------------------------------------------------+ bool CPendingOrder::Delete(void) { return m_trade.OrderDelete(m_ticket); } //+------------------------------------------------------------------+ //| Возвращает истину, если ордер принадлежит эксперту с указанным | //| магическим номером и инструменте. Возвращает ложь в противном | //| случае. | //+------------------------------------------------------------------+ bool CPendingOrder::IsMain(string symbol,ulong magic) { if(ExpertMagic() == magic && Symbol() == symbol) return true; return false; } //+------------------------------------------------------------------+ //| Возвращает магический номер ордера | //+------------------------------------------------------------------+ ulong CPendingOrder::ExpertMagic(void) { if(!OrderSelect(m_ticket))return 0; return OrderGetInteger(ORDER_MAGIC); } //+------------------------------------------------------------------+ //| Возвращает символ ордера | //+------------------------------------------------------------------+ string CPendingOrder::Symbol(void) { if(!OrderSelect(m_ticket))return ""; return OrderGetString(ORDER_SYMBOL); } //+------------------------------------------------------------------+ //| Возвращает комментарий ордера | //+------------------------------------------------------------------+ string CPendingOrder::Comment(void) { if(!OrderSelect(m_ticket))return ""; return OrderGetString(ORDER_COMMENT); } //+------------------------------------------------------------------+ //| Возвращает тип ордера | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE CPendingOrder::Type(void) { if(!OrderSelect(m_ticket))return 0; return (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE); } //+------------------------------------------------------------------+ //| Возвращает состояние ордера | //+------------------------------------------------------------------+ ENUM_ORDER_STATE CPendingOrder::State(void) { if(!OrderSelect(m_ticket))return 0; return (ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE); } //+------------------------------------------------------------------+ //| Возвращает тип исполнения ордера | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_FILLING CPendingOrder::TypeFilling(void) { if(!OrderSelect(m_ticket))return 0; return (ENUM_ORDER_TYPE_FILLING)OrderGetInteger(ORDER_TYPE_FILLING); } //+------------------------------------------------------------------+ //| Тип времени исполнения ордера | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_TIME CPendingOrder::TypeTime(void) { if(!OrderSelect(m_ticket))return 0; return (ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME); } //+------------------------------------------------------------------+ //| Тикет ордера | //+------------------------------------------------------------------+ ulong CPendingOrder::Ticket(void) { if(!OrderSelect(m_ticket))return 0; return (ulong)OrderGetInteger(ORDER_TICKET); } //+------------------------------------------------------------------+ //| Время экспирации ордера | //+------------------------------------------------------------------+ datetime CPendingOrder::TimeExp(void) { if(!OrderSelect(m_ticket))return 0; return (datetime)OrderGetInteger(ORDER_TIME_EXPIRATION); } //+------------------------------------------------------------------+ //| Время исполнения ордера | //+------------------------------------------------------------------+ datetime CPendingOrder::TimeDone(void) { if(!OrderSelect(m_ticket))return 0; return (datetime)OrderGetInteger(ORDER_TIME_DONE); } //+------------------------------------------------------------------+ //| Время установки ордера | //+------------------------------------------------------------------+ datetime CPendingOrder::TimeSetup(void) { if(!OrderSelect(m_ticket))return 0; return (datetime)OrderGetInteger(ORDER_TIME_SETUP); } //+------------------------------------------------------------------+ //| Время установки ордера в миллисекундах | //+------------------------------------------------------------------+ long CPendingOrder::TimeSetupMsc(void) { if(!OrderSelect(m_ticket))return 0; return OrderGetInteger(ORDER_TIME_SETUP_MSC); } //+------------------------------------------------------------------+ //| Время исполнения ордера в миллисекундах | //+------------------------------------------------------------------+ long CPendingOrder::TimeDoneMsc(void) { if(!OrderSelect(m_ticket))return 0; return OrderGetInteger(ORDER_TIME_DONE_MSC); } //+------------------------------------------------------------------+ //| ID позиции, которой принадлежит ордер | //+------------------------------------------------------------------+ long CPendingOrder::PositionID(void) { if(!OrderSelect(m_ticket))return 0; return OrderGetInteger(ORDER_POSITION_ID); } //+------------------------------------------------------------------+ //| ID позиции, которой принадлежит ордер для хеджинговых счетов | //+------------------------------------------------------------------+ long CPendingOrder::PositionByID(void) { if(!OrderSelect(m_ticket))return 0; return OrderGetInteger(ORDER_POSITION_BY_ID); } //+------------------------------------------------------------------+ //| Инициирующий объем ордера | //+------------------------------------------------------------------+ double CPendingOrder::VolumeInit(void) { if(!OrderSelect(m_ticket))return 0.0; return OrderGetDouble(ORDER_VOLUME_INITIAL); } //+------------------------------------------------------------------+ //| Исполненный объем ордера | //+------------------------------------------------------------------+ double CPendingOrder::VolumeCurrent(void) { if(!OrderSelect(m_ticket))return 0.0; return OrderGetDouble(ORDER_VOLUME_CURRENT); } //+------------------------------------------------------------------+ //| Цена открытия ордера | //+------------------------------------------------------------------+ double CPendingOrder::PriceOpen(void) { if(!OrderSelect(m_ticket))return 0.0; return OrderGetDouble(ORDER_PRICE_OPEN); } //+------------------------------------------------------------------+ //| Цена открытия ордера | //+------------------------------------------------------------------+ double CPendingOrder::PriceCurrent(void) { if(!OrderSelect(m_ticket))return 0.0; return OrderGetDouble(ORDER_PRICE_CURRENT); } //+------------------------------------------------------------------+ //| Стоп-лосс ордера | //+------------------------------------------------------------------+ double CPendingOrder::StopLoss(void) { if(!OrderSelect(m_ticket))return 0.0; return OrderGetDouble(ORDER_SL); } //+------------------------------------------------------------------+ //| Тейк-профит ордера | //+------------------------------------------------------------------+ double CPendingOrder::TakeProfit(void) { if(!OrderSelect(m_ticket))return 0.0; return OrderGetDouble(ORDER_TP); } //+------------------------------------------------------------------+ //| Направление ордера | //+------------------------------------------------------------------+ ENUM_POSITION_TYPE CPendingOrder::Direction(void) { if(!OrderSelect(m_ticket))return POSITION_TYPE_BUY; switch((ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE)) { case ORDER_TYPE_BUY: case ORDER_TYPE_BUY_LIMIT: case ORDER_TYPE_BUY_STOP: case ORDER_TYPE_BUY_STOP_LIMIT: return POSITION_TYPE_BUY; default: return POSITION_TYPE_SELL; } return POSITION_TYPE_BUY; } //+------------------------------------------------------------------+ //| Класс для работы с отложенными ордерами | //+------------------------------------------------------------------+ class COrdersEnvironment { private: CDictionary m_orders; // Общее количество всех отложенных ордеров public: COrdersEnvironment(void); int Total(void); CPendingOrder* GetOrder(int index); }; //+------------------------------------------------------------------+ //| Необходимо знать текущий символ и магический номер эксперта | //+------------------------------------------------------------------+ COrdersEnvironment::COrdersEnvironment(void) { } //+------------------------------------------------------------------+ //| Возвращает отложенный ордер | //+------------------------------------------------------------------+ CPendingOrder* COrdersEnvironment::GetOrder(int index) { ulong ticket = OrderGetTicket(index); if(ticket == 0) return NULL; int total = m_orders.Total(); if(m_orders.ContainsKey(ticket)) return m_orders.GetObjectByKey(ticket); if(!OrderSelect(ticket)) return NULL; CPendingOrder* order = new CPendingOrder(ticket); m_orders.AddObject(ticket, order); return order; } //+------------------------------------------------------------------+ //| Возвращает количество отложенных ордеров | //+------------------------------------------------------------------+ int COrdersEnvironment::Total(void) { return OrdersTotal(); }