//+------------------------------------------------------------------+ //| OrderInfo.mqh | //| Copyright 2009-2020, MetaQuotes Software Corp. | //| http://www.mql5.com | //| Copyright 2022, Yuriy Bykov | //| https://www.mql5.com/ru/code/38861 | //| https://www.mql5.com/en/code/39161 | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, Yuriy Bykov" #property link "https://www.mql5.com/ru/users/antekov" #property version "1.00" #property strict #include enum ENUM_ORDER_STATE { ORDER_STATE_STARTED, // Ордер проверен на корректность, но еще не принят брокером ORDER_STATE_PLACED, // Ордер принят ORDER_STATE_CANCELED, // Ордер снят клиентом ORDER_STATE_PARTIAL, // Ордер выполнен частично ORDER_STATE_FILLED, // Ордер выполнен полностью ORDER_STATE_REJECTED, // Ордер отклонен ORDER_STATE_EXPIRED, // Ордер снят по истечении срока его действия ORDER_STATE_REQUEST_ADD, // Ордер в состоянии регистрации (выставление в торговую систему) ORDER_STATE_REQUEST_MODIFY, // Ордер в состоянии модификации (изменение его параметров) ORDER_STATE_REQUEST_CANCEL, // Ордер в состоянии удаления (удаление из торговой системы) }; enum ENUM_ORDER_TYPE_TIME { ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY }; enum ENUM_ORDER_TYPE_FILLING { ORDER_FILLING_FOK, ORDER_FILLING_IOC, ORDER_FILLING_RETURN }; //+------------------------------------------------------------------+ //| Class COrderInfo. | //| Appointment: Class for access to order info. | //| Derives from class CObject. | //+------------------------------------------------------------------+ class COrderInfo : public CObject { protected: ulong m_ticket; ENUM_ORDER_TYPE m_type; ENUM_ORDER_STATE m_state; datetime m_expiration; double m_volume_curr; double m_price_open; double m_stop_loss; double m_take_profit; public: COrderInfo(void); ~COrderInfo(void); //--- methods of access to protected data ulong Ticket(void) const { return(m_ticket); } //--- fast access methods to the integer order propertyes datetime TimeSetup(void) const; ulong TimeSetupMsc(void) const; datetime TimeDone(void) const; ulong TimeDoneMsc(void) const; ENUM_ORDER_TYPE OrderType(void) const; string TypeDescription(void) const; ENUM_ORDER_STATE State(void) const; string StateDescription(void) const; datetime TimeExpiration(void) const; ENUM_ORDER_TYPE_FILLING TypeFilling(void) const; string TypeFillingDescription(void) const; ENUM_ORDER_TYPE_TIME TypeTime(void) const; string TypeTimeDescription(void) const; long Magic(void) const; long PositionId(void) const; long PositionById(void) const; //--- fast access methods to the double order propertyes double VolumeInitial(void) const; double VolumeCurrent(void) const; double PriceOpen(void) const; double StopLoss(void) const; double TakeProfit(void) const; double PriceCurrent(void) const; double PriceStopLimit(void) const; //--- fast access methods to the string order propertyes string Symbol(void) const; string Comment(void) const; string ExternalId(void) const; //--- access methods to the API MQL5 functions bool InfoInteger(const ENUM_ORDER_PROPERTY_INTEGER prop_id, long &var) const; bool InfoDouble(const ENUM_ORDER_PROPERTY_DOUBLE prop_id, double &var) const; bool InfoString(const ENUM_ORDER_PROPERTY_STRING prop_id, string &var) const; //--- info methods string FormatType(string &str, const uint type) const; string FormatStatus(string &str, const uint status) const; string FormatTypeFilling(string &str, const uint type) const; string FormatTypeTime(string &str, const uint type) const; string FormatOrder(string &str) const; string FormatPrice(string &str, const double price_order, const double price_trigger, const uint digits) const; //--- method for select order bool Select(void); bool Select(const ulong ticket); bool SelectByIndex(const int index); //--- additional methods void StoreState(void); bool CheckState(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ COrderInfo::COrderInfo(void) : m_ticket(ULONG_MAX), m_type(WRONG_VALUE), //m_state(WRONG_VALUE), m_expiration(0), m_volume_curr(0.0), m_price_open(0.0), m_stop_loss(0.0), m_take_profit(0.0) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ COrderInfo::~COrderInfo(void) { } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TIME_SETUP" | //+------------------------------------------------------------------+ datetime COrderInfo::TimeSetup(void) const { return((datetime)OrderGetInteger(ORDER_TIME_SETUP)); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TIME_SETUP_MSC" | //+------------------------------------------------------------------+ ulong COrderInfo::TimeSetupMsc(void) const { return(OrderGetInteger(ORDER_TIME_SETUP_MSC)); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TIME_DONE" | //+------------------------------------------------------------------+ datetime COrderInfo::TimeDone(void) const { return((datetime)OrderGetInteger(ORDER_TIME_DONE)); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TIME_DONE_MSC" | //+------------------------------------------------------------------+ ulong COrderInfo::TimeDoneMsc(void) const { return(OrderGetInteger(ORDER_TIME_DONE_MSC)); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TYPE" | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE COrderInfo::OrderType(void) const { return((ENUM_ORDER_TYPE) ::OrderType()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TYPE" as string | //+------------------------------------------------------------------+ string COrderInfo::TypeDescription(void) const { string str; //--- return(FormatType(str, ::OrderType())); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_STATE" | //+------------------------------------------------------------------+ ENUM_ORDER_STATE COrderInfo::State(void) const { return((ENUM_ORDER_STATE)OrderGetInteger(ORDER_STATE)); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_STATE" as string | //+------------------------------------------------------------------+ string COrderInfo::StateDescription(void) const { string str; //--- return(FormatStatus(str, State())); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TIME_EXPIRATION" | //+------------------------------------------------------------------+ datetime COrderInfo::TimeExpiration(void) const { return(OrderExpiration()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TYPE_FILLING" | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_FILLING COrderInfo::TypeFilling(void) const { return((ENUM_ORDER_TYPE_FILLING)OrderGetInteger(ORDER_TYPE_FILLING)); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TYPE_FILLING" as string | //+------------------------------------------------------------------+ string COrderInfo::TypeFillingDescription(void) const { string str; //--- return(FormatTypeFilling(str, TypeFilling())); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TYPE_TIME" | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_TIME COrderInfo::TypeTime(void) const { datetime exp_time = TimeExpiration(); if(exp_time == 0) { return ORDER_TIME_GTC; } return ORDER_TIME_SPECIFIED; } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TYPE_TIME" as string | //+------------------------------------------------------------------+ string COrderInfo::TypeTimeDescription(void) const { string str; //--- return(FormatTypeTime(str, TypeFilling())); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_MAGIC" | //+------------------------------------------------------------------+ long COrderInfo::Magic(void) const { return(OrderMagicNumber()); } /* //+------------------------------------------------------------------+ //| Get the property value "ORDER_POSITION_ID" | //+------------------------------------------------------------------+ long COrderInfo::PositionId(void) const { return(OrderGetInteger(ORDER_POSITION_ID)); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_POSITION_BY_ID" | //+------------------------------------------------------------------+ long COrderInfo::PositionById(void) const { return(OrderGetInteger(ORDER_POSITION_BY_ID)); } */ //+------------------------------------------------------------------+ //| Get the property value "ORDER_VOLUME_INITIAL" | //+------------------------------------------------------------------+ double COrderInfo::VolumeInitial(void) const { return(OrderLots()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_VOLUME_CURRENT" | //+------------------------------------------------------------------+ double COrderInfo::VolumeCurrent(void) const { return(OrderLots()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_PRICE_OPEN" | //+------------------------------------------------------------------+ double COrderInfo::PriceOpen(void) const { return(OrderOpenPrice()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_SL" | //+------------------------------------------------------------------+ double COrderInfo::StopLoss(void) const { return(OrderStopLoss()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_TP" | //+------------------------------------------------------------------+ double COrderInfo::TakeProfit(void) const { return(OrderTakeProfit()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_PRICE_CURRENT" | //+------------------------------------------------------------------+ double COrderInfo::PriceCurrent(void) const { return(OrderOpenPrice()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_PRICE_STOPLIMIT" | //+------------------------------------------------------------------+ double COrderInfo::PriceStopLimit(void) const { return(0); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_SYMBOL" | //+------------------------------------------------------------------+ string COrderInfo::Symbol(void) const { return(OrderSymbol()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_COMMENT" | //+------------------------------------------------------------------+ string COrderInfo::Comment(void) const { return(OrderComment()); } //+------------------------------------------------------------------+ //| Get the property value "ORDER_EXTERNAL_ID" | //+------------------------------------------------------------------+ string COrderInfo::ExternalId(void) const { return(""); } /* //+------------------------------------------------------------------+ //| Access functions OrderGetInteger(...) | //+------------------------------------------------------------------+ bool COrderInfo::InfoInteger(const ENUM_ORDER_PROPERTY_INTEGER prop_id, long &var) const { return(OrderGetInteger(prop_id, var)); } //+------------------------------------------------------------------+ //| Access functions OrderGetDouble(...) | //+------------------------------------------------------------------+ bool COrderInfo::InfoDouble(const ENUM_ORDER_PROPERTY_DOUBLE prop_id, double &var) const { return(OrderGetDouble(prop_id, var)); } //+------------------------------------------------------------------+ //| Access functions OrderGetString(...) | //+------------------------------------------------------------------+ bool COrderInfo::InfoString(const ENUM_ORDER_PROPERTY_STRING prop_id, string &var) const { return(OrderGetString(prop_id, var)); } */ //+------------------------------------------------------------------+ //| Converts the order type to text | //+------------------------------------------------------------------+ string COrderInfo::FormatType(string &str, const uint type) const { //--- see the type switch(type) { case ORDER_TYPE_BUY_LIMIT: str = "BUY LIMIT"; break; case ORDER_TYPE_SELL_LIMIT: str = "SELL LIMIT"; break; case ORDER_TYPE_BUY_STOP: str = "buy stop"; break; case ORDER_TYPE_SELL_STOP: str = "sell stop"; break; default : str = "unknown order type " + (string)type; } //--- return the result return(str); } //+------------------------------------------------------------------+ //| Converts the order status to text | //+------------------------------------------------------------------+ string COrderInfo::FormatStatus(string &str, const uint status) const { //--- see the type switch(status) { case ORDER_STATE_STARTED: str = "started"; break; case ORDER_STATE_PLACED: str = "placed"; break; case ORDER_STATE_CANCELED: str = "canceled"; break; case ORDER_STATE_PARTIAL: str = "partial"; break; case ORDER_STATE_FILLED: str = "filled"; break; case ORDER_STATE_REJECTED: str = "rejected"; break; case ORDER_STATE_EXPIRED: str = "expired"; break; case ORDER_STATE_REQUEST_ADD: str = "request adding"; break; case ORDER_STATE_REQUEST_MODIFY: str = "request modifying"; break; case ORDER_STATE_REQUEST_CANCEL: str = "request cancelling"; break; default : str = "unknown order status " + (string)status; } //--- return the result return(str); } //+------------------------------------------------------------------+ //| Converts the order filling type to text | //+------------------------------------------------------------------+ string COrderInfo::FormatTypeFilling(string &str, const uint type) const { //--- see the type switch(type) { case ORDER_FILLING_RETURN: str = "return remainder"; break; case ORDER_FILLING_IOC: str = "cancel remainder"; break; case ORDER_FILLING_FOK: str = "fill or kill"; break; default: str = "unknown type filling " + (string)type; } //--- return the result return(str); } //+------------------------------------------------------------------+ //| Converts the type of order by expiration to text | //+------------------------------------------------------------------+ string COrderInfo::FormatTypeTime(string &str, const uint type) const { //--- see the type switch(type) { case ORDER_TIME_GTC: str = "gtc"; break; case ORDER_TIME_DAY: str = "day"; break; case ORDER_TIME_SPECIFIED: str = "specified"; break; case ORDER_TIME_SPECIFIED_DAY: str = "specified day"; break; default: str = "unknown type time " + (string)type; } //--- return the result return(str); } //+------------------------------------------------------------------+ //| Converts the order parameters to text | //+------------------------------------------------------------------+ string COrderInfo::FormatOrder(string &str) const { string type, price; long tmp_long; //--- set up string symbol_name = this.Symbol(); int digits = _Digits; if(SymbolInfoInteger(symbol_name, SYMBOL_DIGITS, tmp_long)) digits = (int)tmp_long; //--- form the order description str = StringFormat("#%I64u %s %s %s", Ticket(), FormatType(type, OrderType()), DoubleToString(VolumeInitial(), 2), symbol_name); //--- receive the price of the order FormatPrice(price, PriceOpen(), PriceStopLimit(), digits); //--- if there is price, write it if(price != "") { str += " at "; str += price; } //--- return the result return(str); } //+------------------------------------------------------------------+ //| Converts the order prices to text | //+------------------------------------------------------------------+ string COrderInfo::FormatPrice(string &str, const double price_order, const double price_trigger, const uint digits) const { string price, trigger; //--- Is there its trigger price? if(price_trigger) { price = DoubleToString(price_order, digits); trigger = DoubleToString(price_trigger, digits); str = StringFormat("%s (%s)", price, trigger); } else str = DoubleToString(price_order, digits); //--- return the result return(str); } //+------------------------------------------------------------------+ //| Selecting an order to access | //+------------------------------------------------------------------+ bool COrderInfo::Select(void) { return(OrderSelect((int)m_ticket, SELECT_BY_TICKET)); } //+------------------------------------------------------------------+ //| Selecting an order to access | //+------------------------------------------------------------------+ bool COrderInfo::Select(const ulong ticket) { if(OrderSelect((int)ticket, SELECT_BY_TICKET)) { m_ticket = ticket; return(true); } m_ticket = ULONG_MAX; //--- return(false); } //+------------------------------------------------------------------+ //| Select an order by the index | //+------------------------------------------------------------------+ bool COrderInfo::SelectByIndex(const int index) { if(OrderSelect(index, SELECT_BY_POS, MODE_TRADES)) { int type = OrderType(); if(1 < type && type < 6) { m_ticket = OrderTicket(); return(true); } } m_ticket = ULONG_MAX; return(false); //--- } //+------------------------------------------------------------------+ //| Stored order's current state | //+------------------------------------------------------------------+ void COrderInfo::StoreState(void) { m_type = OrderType(); m_state = State(); m_expiration = TimeExpiration(); m_volume_curr = VolumeCurrent(); m_price_open = PriceOpen(); m_stop_loss = StopLoss(); m_take_profit = TakeProfit(); } //+------------------------------------------------------------------+ //| Check order change | //+------------------------------------------------------------------+ bool COrderInfo::CheckState(void) { if(m_type == OrderType() && m_state == State() && m_expiration == TimeExpiration() && m_volume_curr == VolumeCurrent() && m_price_open == PriceOpen() && m_stop_loss == StopLoss() && m_take_profit == TakeProfit()) return(false); //--- return(true); } //+------------------------------------------------------------------+