//+------------------------------------------------------------------+ //| Trade.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include #include "OrderInfo.mqh" #include "HistoryOrderInfo.mqh" #include "PositionInfo.mqh" #include "DealInfo.mqh" //+------------------------------------------------------------------+ //| enumerations | //+------------------------------------------------------------------+ enum ENUM_LOG_LEVELS { LOG_LEVEL_NO =0, LOG_LEVEL_ERRORS=1, LOG_LEVEL_ALL =2 }; //+------------------------------------------------------------------+ //| Class CTrade. | //| Appointment: Class trade operations. | //| Derives from class CObject. | //+------------------------------------------------------------------+ class CTrade : public CObject { protected: MqlTradeRequest m_request; // request data MqlTradeResult m_result; // result data MqlTradeCheckResult m_check_result; // result check data bool m_async_mode; // trade mode ulong m_magic; // expert magic number ulong m_deviation; // deviation default ENUM_ORDER_TYPE_FILLING m_type_filling; ENUM_ACCOUNT_MARGIN_MODE m_margin_mode; //--- ENUM_LOG_LEVELS m_log_level; public: CTrade(void); ~CTrade(void); //--- methods of access to protected data void LogLevel(const ENUM_LOG_LEVELS log_level) { m_log_level=log_level; } void Request(MqlTradeRequest &request) const; ENUM_TRADE_REQUEST_ACTIONS RequestAction(void) const { return(m_request.action); } string RequestActionDescription(void) const; ulong RequestMagic(void) const { return(m_request.magic); } ulong RequestOrder(void) const { return(m_request.order); } ulong RequestPosition(void) const { return(m_request.position); } ulong RequestPositionBy(void) const { return(m_request.position_by); } string RequestSymbol(void) const { return(m_request.symbol); } double RequestVolume(void) const { return(m_request.volume); } double RequestPrice(void) const { return(m_request.price); } double RequestStopLimit(void) const { return(m_request.stoplimit); } double RequestSL(void) const { return(m_request.sl); } double RequestTP(void) const { return(m_request.tp); } ulong RequestDeviation(void) const { return(m_request.deviation); } ENUM_ORDER_TYPE RequestType(void) const { return(m_request.type); } string RequestTypeDescription(void) const; ENUM_ORDER_TYPE_FILLING RequestTypeFilling(void) const { return(m_request.type_filling); } string RequestTypeFillingDescription(void) const; ENUM_ORDER_TYPE_TIME RequestTypeTime(void) const { return(m_request.type_time); } string RequestTypeTimeDescription(void) const; datetime RequestExpiration(void) const { return(m_request.expiration); } string RequestComment(void) const { return(m_request.comment); } //--- void Result(MqlTradeResult &result) const; uint ResultRetcode(void) const { return(m_result.retcode); } string ResultRetcodeDescription(void) const; int ResultRetcodeExternal(void) const { return(m_result.retcode_external); } ulong ResultDeal(void) const { return(m_result.deal); } ulong ResultOrder(void) const { return(m_result.order); } double ResultVolume(void) const { return(m_result.volume); } double ResultPrice(void) const { return(m_result.price); } double ResultBid(void) const { return(m_result.bid); } double ResultAsk(void) const { return(m_result.ask); } string ResultComment(void) const { return(m_result.comment); } //--- void CheckResult(MqlTradeCheckResult &check_result) const; uint CheckResultRetcode(void) const { return(m_check_result.retcode); } string CheckResultRetcodeDescription(void) const; double CheckResultBalance(void) const { return(m_check_result.balance); } double CheckResultEquity(void) const { return(m_check_result.equity); } double CheckResultProfit(void) const { return(m_check_result.profit); } double CheckResultMargin(void) const { return(m_check_result.margin); } double CheckResultMarginFree(void) const { return(m_check_result.margin_free); } double CheckResultMarginLevel(void) const { return(m_check_result.margin_level); } string CheckResultComment(void) const { return(m_check_result.comment); } //--- trade methods void SetAsyncMode(const bool mode) { m_async_mode=mode; } void SetExpertMagicNumber(const ulong magic) { m_magic=magic; } void SetDeviationInPoints(const ulong deviation) { m_deviation=deviation; } void SetTypeFilling(const ENUM_ORDER_TYPE_FILLING filling) { m_type_filling=filling; } bool SetTypeFillingBySymbol(const string symbol); void SetMarginMode(void) { m_margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE); } //--- methods for working with positions bool PositionOpen(const string symbol,const ENUM_ORDER_TYPE order_type,const double volume, const double price,const double sl,const double tp,const string comment=""); bool PositionModify(const string symbol,const double sl,const double tp); bool PositionModify(const ulong ticket,const double sl,const double tp); bool PositionClose(const string symbol,const ulong deviation=ULONG_MAX); bool PositionClose(const ulong ticket,const ulong deviation=ULONG_MAX); bool PositionCloseBy(const ulong ticket,const ulong ticket_by); bool PositionClosePartial(const string symbol,const double volume,const ulong deviation=ULONG_MAX); bool PositionClosePartial(const ulong ticket,const double volume,const ulong deviation=ULONG_MAX); //--- methods for working with pending orders bool OrderOpen(const string symbol,const ENUM_ORDER_TYPE order_type,const double volume, const double limit_price,const double price,const double sl,const double tp, ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC,const datetime expiration=0, const string comment=""); bool OrderModify(const ulong ticket,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 OrderDelete(const ulong ticket); //--- additions methods bool Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment=""); bool Sell(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment=""); bool BuyLimit(const double volume,const double price,const string symbol=NULL,const double sl=0.0,const double tp=0.0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC,const datetime expiration=0,const string comment=""); bool BuyStop(const double volume,const double price,const string symbol=NULL,const double sl=0.0,const double tp=0.0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC,const datetime expiration=0,const string comment=""); bool SellLimit(const double volume,const double price,const string symbol=NULL,const double sl=0.0,const double tp=0.0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC,const datetime expiration=0,const string comment=""); bool SellStop(const double volume,const double price,const string symbol=NULL,const double sl=0.0,const double tp=0.0, const ENUM_ORDER_TYPE_TIME type_time=ORDER_TIME_GTC,const datetime expiration=0,const string comment=""); //--- method check virtual double CheckVolume(const string symbol,double volume,double price,ENUM_ORDER_TYPE order_type); virtual bool OrderCheck(const MqlTradeRequest &request,MqlTradeCheckResult &check_result); virtual bool OrderSend(const MqlTradeRequest &request,MqlTradeResult &result); //--- info methods void PrintRequest(void) const; void PrintResult(void) const; //--- positions string FormatPositionType(string &str,const uint type) const; //--- orders string FormatOrderType(string &str,const uint type) const; string FormatOrderStatus(string &str,const uint status) const; string FormatOrderTypeFilling(string &str,const uint type) const; string FormatOrderTypeTime(string &str,const uint type) const; string FormatOrderPrice(string &str,const double price_order,const double price_trigger,const uint digits) const; //--- trade request string FormatRequest(string &str,const MqlTradeRequest &request) const; string FormatRequestResult(string &str,const MqlTradeRequest &request,const MqlTradeResult &result) const; protected: bool FillingCheck(const string symbol); bool ExpirationCheck(const string symbol); bool OrderTypeCheck(const string symbol); void ClearStructures(void); bool IsStopped(const string function); bool IsHedging(void) const { return(m_margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING); } //--- position select depending on netting or hedging bool SelectPosition(const string symbol); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CTrade::CTrade(void) : m_async_mode(false), m_magic(0), m_deviation(10), m_type_filling(ORDER_FILLING_FOK), m_log_level(LOG_LEVEL_ERRORS) { SetMarginMode(); //--- initialize protected data ClearStructures(); //--- check programm mode if(MQLInfoInteger(ENUM_MQL_INFO_INTEGER::MQL_TESTER)) m_log_level=LOG_LEVEL_ALL; if(MQLInfoInteger(ENUM_MQL_INFO_INTEGER::MQL_OPTIMIZATION)) m_log_level=LOG_LEVEL_NO; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CTrade::~CTrade(void) { } //+------------------------------------------------------------------+ //| Get the request structure | //+------------------------------------------------------------------+ void CTrade::Request(MqlTradeRequest &request) const { request.action =m_request.action; request.magic =m_request.magic; request.order =m_request.order; request.symbol =m_request.symbol; request.volume =m_request.volume; request.price =m_request.price; request.stoplimit =m_request.stoplimit; request.sl =m_request.sl; request.tp =m_request.tp; request.deviation =m_request.deviation; request.type =m_request.type; request.type_filling=m_request.type_filling; request.type_time =m_request.type_time; request.expiration =m_request.expiration; request.comment =m_request.comment; request.position =m_request.position; request.position_by =m_request.position_by; } //+------------------------------------------------------------------+ //| Get the trade action as string | //+------------------------------------------------------------------+ string CTrade::RequestActionDescription(void) const { string str; //--- FormatRequest(str,m_request); //--- return(str); } //+------------------------------------------------------------------+ //| Get the order type as string | //+------------------------------------------------------------------+ string CTrade::RequestTypeDescription(void) const { string str; //--- FormatOrderType(str,(uint)m_request.order); //--- return(str); } //+------------------------------------------------------------------+ //| Get the order type filling as string | //+------------------------------------------------------------------+ string CTrade::RequestTypeFillingDescription(void) const { string str; //--- FormatOrderTypeFilling(str,m_request.type_filling); //--- return(str); } //+------------------------------------------------------------------+ //| Get the order type time as string | //+------------------------------------------------------------------+ string CTrade::RequestTypeTimeDescription(void) const { string str; //--- FormatOrderTypeTime(str,m_request.type_time); //--- return(str); } //+------------------------------------------------------------------+ //| Get the result structure | //+------------------------------------------------------------------+ void CTrade::Result(MqlTradeResult &result) const { result.retcode =m_result.retcode; result.deal =m_result.deal; result.order =m_result.order; result.volume =m_result.volume; result.price =m_result.price; result.bid =m_result.bid; result.ask =m_result.ask; result.comment =m_result.comment; result.request_id=m_result.request_id; result.retcode_external=m_result.retcode_external; } //+------------------------------------------------------------------+ //| Get the retcode value as string | //+------------------------------------------------------------------+ string CTrade::ResultRetcodeDescription(void) const { string str; //--- FormatRequestResult(str,m_request,m_result); //--- return(str); } //+------------------------------------------------------------------+ //| Get the check result structure | //+------------------------------------------------------------------+ void CTrade::CheckResult(MqlTradeCheckResult &check_result) const { //--- copy structure check_result.retcode =m_check_result.retcode; check_result.balance =m_check_result.balance; check_result.equity =m_check_result.equity; check_result.profit =m_check_result.profit; check_result.margin =m_check_result.margin; check_result.margin_free =m_check_result.margin_free; check_result.margin_level=m_check_result.margin_level; check_result.comment =m_check_result.comment; } //+------------------------------------------------------------------+ //| Get the check retcode value as string | //+------------------------------------------------------------------+ string CTrade::CheckResultRetcodeDescription(void) const { string str; MqlTradeResult result; //--- result.retcode=m_check_result.retcode; FormatRequestResult(str,m_request,result); //--- return(str); } //+------------------------------------------------------------------+ //| Open position | //+------------------------------------------------------------------+ bool CTrade::PositionOpen(const string symbol,const ENUM_ORDER_TYPE order_type,const double volume, const double price,const double sl,const double tp,const string comment) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- clean ClearStructures(); //--- check if(order_type!=ORDER_TYPE_BUY && order_type!=ORDER_TYPE_SELL) { m_result.retcode=TRADE_RETCODE_INVALID; m_result.comment="Invalid order type"; return(false); } //--- setting request m_request.action =TRADE_ACTION_DEAL; m_request.symbol =symbol; m_request.magic =m_magic; m_request.volume =volume; m_request.type =order_type; m_request.price =price; m_request.sl =sl; m_request.tp =tp; m_request.deviation=m_deviation; //--- check order type if(!OrderTypeCheck(symbol)) return(false); //--- check filling if(!FillingCheck(symbol)) return(false); m_request.comment=comment; //--- action and return the result return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Modify specified opened position | //+------------------------------------------------------------------+ bool CTrade::PositionModify(const string symbol,const double sl,const double tp) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- check position existence if(!SelectPosition(symbol)) return(false); //--- clean ClearStructures(); //--- setting request m_request.action =TRADE_ACTION_SLTP; m_request.symbol =symbol; m_request.magic =m_magic; m_request.sl =sl; m_request.tp =tp; m_request.position=PositionGetInteger(POSITION_TICKET); //--- action and return the result return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Modify specified opened position | //+------------------------------------------------------------------+ bool CTrade::PositionModify(const ulong ticket,const double sl,const double tp) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- check position existence if(!PositionSelectByTicket(ticket)) return(false); //--- clean ClearStructures(); //--- setting request m_request.action =TRADE_ACTION_SLTP; m_request.position=ticket; m_request.symbol =PositionGetString(POSITION_SYMBOL); m_request.magic =m_magic; m_request.sl =sl; m_request.tp =tp; //--- action and return the result return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Close specified opened position | //+------------------------------------------------------------------+ bool CTrade::PositionClose(const string symbol,const ulong deviation) { bool partial_close=false; int retry_count =10; uint retcode =TRADE_RETCODE_REJECT; //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- clean ClearStructures(); //--- check filling if(!FillingCheck(symbol)) return(false); do { //--- check if(SelectPosition(symbol)) { if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { //--- prepare request for close BUY position m_request.type =ORDER_TYPE_SELL; m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID); } else { //--- prepare request for close SELL position m_request.type =ORDER_TYPE_BUY; m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); } } else { //--- position not found m_result.retcode=retcode; return(false); } //--- setting request m_request.action =TRADE_ACTION_DEAL; m_request.symbol =symbol; m_request.volume =PositionGetDouble(POSITION_VOLUME); m_request.magic =m_magic; m_request.deviation=(deviation==ULONG_MAX) ? m_deviation : deviation; m_request.position =PositionGetInteger(POSITION_TICKET); //--- check volume double max_volume=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX); if(m_request.volume>max_volume) { m_request.volume=max_volume; partial_close=true; } else partial_close=false; //--- hedging? just send order if(IsHedging()) return(OrderSend(m_request,m_result)); //--- order send if(!OrderSend(m_request,m_result)) { if(--retry_count!=0) continue; if(retcode==TRADE_RETCODE_DONE_PARTIAL) m_result.retcode=retcode; return(false); } //--- WARNING. If position volume exceeds the maximum volume allowed for deal, //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, //--- but partially. It is decreased by the maximum volume allowed for deal. if(m_async_mode) break; retcode=TRADE_RETCODE_DONE_PARTIAL; if(partial_close) Sleep(1000); } while(partial_close); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Close specified opened position | //+------------------------------------------------------------------+ bool CTrade::PositionClose(const ulong ticket,const ulong deviation) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- check position existence if(!PositionSelectByTicket(ticket)) return(false); string symbol=PositionGetString(POSITION_SYMBOL); //--- clean ClearStructures(); //--- check filling if(!FillingCheck(symbol)) return(false); //--- check if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { //--- prepare request for close BUY position m_request.type =ORDER_TYPE_SELL; m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID); } else { //--- prepare request for close SELL position m_request.type =ORDER_TYPE_BUY; m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); } //--- setting request m_request.action =TRADE_ACTION_DEAL; m_request.position =ticket; m_request.symbol =symbol; m_request.volume =PositionGetDouble(POSITION_VOLUME); m_request.magic =m_magic; m_request.deviation=(deviation==ULONG_MAX) ? m_deviation : deviation; //--- close position return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Close one position by other | //+------------------------------------------------------------------+ bool CTrade::PositionCloseBy(const ulong ticket,const ulong ticket_by) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- check hedging mode if(!IsHedging()) return(false); //--- check position existence if(!PositionSelectByTicket(ticket)) return(false); string symbol=PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if(!PositionSelectByTicket(ticket_by)) return(false); string symbol_by=PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE type_by=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); //--- check positions if(type==type_by) return(false); if(symbol!=symbol_by) return(false); //--- clean ClearStructures(); //--- check filling if(!FillingCheck(symbol)) return(false); //--- setting request m_request.action =TRADE_ACTION_CLOSE_BY; m_request.position =ticket; m_request.position_by=ticket_by; m_request.magic =m_magic; //--- close position return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Partial close specified opened position (for hedging mode only) | //+------------------------------------------------------------------+ bool CTrade::PositionClosePartial(const string symbol,const double volume,const ulong deviation) { uint retcode=TRADE_RETCODE_REJECT; //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- for hedging mode only if(!IsHedging()) return(false); //--- clean ClearStructures(); //--- check filling if(!FillingCheck(symbol)) return(false); //--- check if(SelectPosition(symbol)) { if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { //--- prepare request for close BUY position m_request.type =ORDER_TYPE_SELL; m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID); } else { //--- prepare request for close SELL position m_request.type =ORDER_TYPE_BUY; m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); } } else { //--- position not found m_result.retcode=retcode; return(false); } //--- check volume double position_volume=PositionGetDouble(POSITION_VOLUME); if(position_volume>volume) position_volume=volume; //--- setting request m_request.action =TRADE_ACTION_DEAL; m_request.symbol =symbol; m_request.volume =position_volume; m_request.magic =m_magic; m_request.deviation=(deviation==ULONG_MAX) ? m_deviation : deviation; m_request.position =PositionGetInteger(POSITION_TICKET); //--- hedging? just send order return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Partial close specified opened position (for hedging mode only) | //+------------------------------------------------------------------+ bool CTrade::PositionClosePartial(const ulong ticket,const double volume,const ulong deviation) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- for hedging mode only if(!IsHedging()) return(false); //--- check position existence if(!PositionSelectByTicket(ticket)) return(false); string symbol=PositionGetString(POSITION_SYMBOL); //--- clean ClearStructures(); //--- check filling if(!FillingCheck(symbol)) return(false); //--- check if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { //--- prepare request for close BUY position m_request.type =ORDER_TYPE_SELL; m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID); } else { //--- prepare request for close SELL position m_request.type =ORDER_TYPE_BUY; m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK); } //--- check volume double position_volume=PositionGetDouble(POSITION_VOLUME); if(position_volume>volume) position_volume=volume; //--- setting request m_request.action =TRADE_ACTION_DEAL; m_request.position =ticket; m_request.symbol =symbol; m_request.volume =position_volume; m_request.magic =m_magic; m_request.deviation=(deviation==ULONG_MAX) ? m_deviation : deviation; //--- close position return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Installation pending order | //+------------------------------------------------------------------+ bool CTrade::OrderOpen(const string symbol,const ENUM_ORDER_TYPE order_type,const double volume,const double limit_price, const double price,const double sl,const double tp, ENUM_ORDER_TYPE_TIME type_time,const datetime expiration,const string comment) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- clean ClearStructures(); //--- check filling if(!FillingCheck(symbol)) return(false); //--- check order type if(order_type==ORDER_TYPE_BUY || order_type==ORDER_TYPE_SELL) { m_result.retcode=TRADE_RETCODE_INVALID; m_result.comment="Invalid order type"; return(false); } //--- check order expiration if(type_time==ORDER_TIME_GTC && expiration==0) { int exp=(int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE); if((exp&SYMBOL_EXPIRATION_GTC)!=SYMBOL_EXPIRATION_GTC) { //--- if you place order for an unlimited time and if placing of such orders is prohibited //--- try to place order with expiration at the end of the day if((exp&SYMBOL_EXPIRATION_DAY)!=SYMBOL_EXPIRATION_DAY) { //--- if even this is not possible - error Print(__FUNCTION__,": Error: Unable to place order without explicitly specified expiration time"); m_result.retcode=TRADE_RETCODE_INVALID_EXPIRATION; m_result.comment="Invalid expiration type"; return(false); } type_time=ORDER_TIME_DAY; } } //--- setting request m_request.action =TRADE_ACTION_PENDING; m_request.symbol =symbol; m_request.magic =m_magic; m_request.volume =volume; m_request.type =order_type; m_request.stoplimit =limit_price; m_request.price =price; m_request.sl =sl; m_request.tp =tp; m_request.type_time =type_time; m_request.expiration =expiration; //--- check order type if(!OrderTypeCheck(symbol)) return(false); //--- check filling if(!FillingCheck(symbol)) { m_result.retcode=TRADE_RETCODE_INVALID_FILL; Print(__FUNCTION__+": Invalid filling type"); return(false); } //--- check expiration if(!ExpirationCheck(symbol)) { m_result.retcode=TRADE_RETCODE_INVALID_EXPIRATION; Print(__FUNCTION__+": Invalid expiration type"); return(false); } m_request.comment=comment; //--- action and return the result return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Modify specified pending order | //+------------------------------------------------------------------+ bool CTrade::OrderModify(const ulong ticket,const double price,const double sl,const double tp, const ENUM_ORDER_TYPE_TIME type_time,const datetime expiration,const double stoplimit) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- check order existence if(!OrderSelect(ticket)) return(false); //--- clean ClearStructures(); //--- setting request m_request.symbol =OrderGetString(ORDER_SYMBOL); m_request.action =TRADE_ACTION_MODIFY; m_request.magic =m_magic; m_request.order =ticket; m_request.price =price; m_request.stoplimit =stoplimit; m_request.sl =sl; m_request.tp =tp; m_request.type_time =type_time; m_request.expiration =expiration; //--- action and return the result return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Delete specified pending order | //+------------------------------------------------------------------+ bool CTrade::OrderDelete(const ulong ticket) { //--- check stopped if(IsStopped(__FUNCTION__)) return(false); //--- clean ClearStructures(); //--- setting request m_request.action =TRADE_ACTION_REMOVE; m_request.magic =m_magic; m_request.order =ticket; //--- action and return the result return(OrderSend(m_request,m_result)); } //+------------------------------------------------------------------+ //| Output full information of request to log | //+------------------------------------------------------------------+ void CTrade::PrintRequest(void) const { if(m_log_level0.0) volume=stepvol*(MathFloor(lots/stepvol)-1); //--- double minvol=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN); if(volumeLOG_LEVEL_ERRORS) PrintFormat(__FUNCTION__+": %s [%s]",FormatRequest(action,request),FormatRequestResult(fmt,request,result)); } else { if(m_log_level>LOG_LEVEL_NO) PrintFormat(__FUNCTION__+": %s [%s]",FormatRequest(action,request),FormatRequestResult(fmt,request,result)); } //--- return the result return(res); } //+------------------------------------------------------------------+ //| Position select depending on netting or hedging | //+------------------------------------------------------------------+ bool CTrade::SelectPosition(const string symbol) { bool res=false; //--- if(IsHedging()) { uint total=PositionsTotal(); for(uint i=0; i