/*+------------------------------------------------------------------+ //| EasyTradeEvent.mqh | //| #include <= to copy & paste | //| Calli | //| https://www.mql5.com/de/users/gooly | It is as usual: the nomal case of sending an order is easy but its error handling is 100 times more complex and complicated :( The functionality of MQ's Trade.mqh is nice but it is not ideal (fast) in case if errors and it does not harmonize well with OnTradeTransaction(). OnTradeTransaction() is triggered from not at all to four times for one trading act set by a trader :( Imagine: speed matters for your EA, it is trading several symbols on different charts, suddenly the prices are moving up fast and your EA needs to act fast, normally it has to loop through all positions of all symbols and directions, but it only needs its own one ot two buy positions :( Therfore: two arrays are managed one for buys on for sells (oPoBU[],oPoSE[]), with their information and PositionSelectByTicket() exists a straight acces to the positions that matters to modify them (trail, close..) bypassing all the other existing positions. Several ideas and requirements are processed: 1) Find the single trigger of OnTradeTransaction() that matters. 2) If an order fails the request and the result are used to react. E.g. in case of requotes result has valid bid and ask which are used if the offset is not too big. 3) The magic number is used as an individual ID for the confirmation in OnTradeTransaction as sometimes the other IDs are missing :( Therefore the magic number is created by (ulong)TimeCurrent() which is enough if the trader (EA) doesn't send masses of orders.. 4) When an order was accepted by the server a function chkREQ() adds the sent reqest to the array ReqCHCK for confirmation via OnTradeTransaction(). 5) To pass required information some fields of the trade structs are abused like deviation. This way we do not need to declare, fill, administrate, and delete additional data structures just for the admin. We use what already exists :) 6) Here we use OrderSendAsync() as the EA quickly returns right after the order was accepted by the server in order to prepare the tracking of the sent order. 7) If OrderSendAsync() failed chkFail() tries to heal the problem or to inform the user (EA). 8) If OrderSendAsync() succeded chkREQ() is called to prepare the confirmation by OnTradeTransaction(). 9) In OnTradeTransaction(), the first thing that is collected is information about the various IDs (tickets, magic,...), what ever is available because often these values are not assigned :( 10)Then we go through a complicated and heterogeneous network of return codes of the structure MqlTradeResult and the types of the structure MqlTradeTransaction. I wish there were a simpler solution, but it would have to be offered by MetaQuotes, simply limited to what an EA needs for confirmation, error detection, and handling. Let's hope and pray ;) //+------------------------------------------------------------------*/ #property library #property copyright "Calli" #property link "https://www.mql5.com/de/users/gooly" #property version "1.00" #include "EasyTradeEvent_INCL 02.mqh" /*+------------------------------------------------------------------+ //| trading functions prepared for handling confirmation & errors | //| //| these function are meant to be used by the EAs/users | //| tradeClosePartPos(): close pos. partly by an opp. pend. Order //| tradeCloseTckt(): close pos. by #ticket & volume //| tradeCloseTcktByPos(): close pos1 (#t1) by pos2 (#t2) & mag //| tradeCloseOpnPos(): close specified position //| //| tradeMoveTPSLPos(): //| tradeNewTPSLPos(): //| tradeTrailTPSLPos(): //| tradeNewTPSLOrd(): //| prtOneOpnPos(): //| tradePenOrdTP(): set TP as Pending Order to partly close Pos. //| //| //| //+------------------------------------------------------------------*/ ulong sndOrder(_opTrd &ord, const string cmt="") { MqlTradeRequest rq={}; MqlTradeResult rs={}; MqlTradeCheckResult rc={}; bool newRecord = false; ulong pID = 0; switch (ord.dir) { case €BUY: case €SELL: rq.action = TRADE_ACTION_DEAL; // pending order rq.type = ORDER_TYPE_SELL; // Ordertyp rq.deviation = ord.uDevOrInf; rq.magic = ord.uMag; rq.symbol = _Symbol; // Instrument rq.volume = ord.dVol; // Volumen von 0.1 Lot rq.price = ord.dOpn; rq.sl = ord.dSL; rq.tp = ord.dTP; rq.comment = "Market-Order Sell Mag: "+(string)(rq.magic%1000000); break; case €BUYSTOP: case €SELLSTOP: case €BUYLIMIT: case €SELLLIMIT: case €BUYSTOPLIMIT: rq.action = TRADE_ACTION_PENDING; // pending order rq.type = ORDER_TYPE_BUY_STOP_LIMIT; // Ordertyp rq.deviation = ord.uDevOrInf; rq.symbol = _Symbol; // Instrument rq.magic = ord.uMag; rq.volume = ord.dVol; rq.price = ord.dOpn; rq.stoplimit = ord.dStLim; rq.sl = ord.dSL; rq.tp = ord.dTP; rq.comment = cmt != "" ? cmt : "BuyStpLimit Mag: "+(string)(rq.magic%1000000); // it mussn't be tooo long break; case €SELLSTOPLIMIT: default: return(0); } if( !OrderCheck(rq,rc) ) { ord.status = €Fail; Print(FunLine,"TRADE_RETCODE_NO_MONEY ",err(_LastError)," res.order ",rs.retcode," ",err(rs.retcode)," r.D: ",rs.deal," r.O: ",rs.order); Print(FunLine,prtRequ(rq)); Print(FunLine,prtReqCheck(rc)); return(0); // 0=failed } if (OrderSendAsync(rq,rs)) { ord.uID = rs.order; //Print("\n",FunLine," ####################### OK ",EnumToString(typ)," sent \n",__LINE__," ",_Symbol," ",rq.magic," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ", // rq.comment,"\n in:",_d2D(prc),"TP:",_d2D(rq.tp)," SL:",_d2D(rq.sl)," r.ID: ",rs.request_id," d.O: ",rs.deal," r.O: ",rs.order," r.ret: ",rs.retcode); chkREQ(FunLine,rq,rs.order); return(rs.order); } else { // FAILED :( Print(FunLine," OrderSendAsync error ",err(_LastError)," res.order ",rs.retcode," ",err(rs.retcode)," r.D: ",rs.deal," r.O: ",rs.order, "\ntC ",_t2All(TimeCurrent())," Cmt ",rq.comment); //Print(FunLine," ",prtRequ(rq)); //Print(FunLine," ", prtResult(rs)); if (_LastError == TRADE_RETCODE_NO_MONEY) { Print(FunLine," TRADE_RETCODE_NO_MONEY ",err(_LastError)," res.order ",rs.retcode," ",err(rs.retcode)," r.D: ",rs.deal," r.O: ",rs.order); Print(FunLine," ",prtRequ(rq)); Print(FunLine," ",prtReqCheck(rc)); return(0); } if (chkFail(FunLine,rq,rs)) { // with chkREQ(FunLine,rq,pID) in chkFail() pID = rs.order; ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, return(pID); } if (chkFail(FunLine,rq,rs)) { // next try // with chkREQ(FunLine,rq,pID) in chkFail() pID = rs.order; ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, return(pID); } } return(pID); } // use: tradePenOrdTP(oOrBU[i], 1.2, fmax(pLim,pStp), 100.0*_Point); bool tradePenOrdSL(_opTrd &ord, const double vol, const double diff) { MqlTradeRequest reqClsBY = {}; // ZeroMemory(reqClsBY); MqlTradeResult resClsBY = {}; // ZeroMemory(resClsBY); //DebugBreak(); if ( ord.dir % 2 == 0 ) { reqClsBY.type = ORDER_TYPE_SELL_STOP; // opposite direction reqClsBY.price = ord.dOpn - diff; } else { reqClsBY.type = ORDER_TYPE_BUY_STOP; // opposite direction reqClsBY.price = ord.dOpn + diff; } reqClsBY.action = TRADE_ACTION_PENDING; // pending order reqClsBY.magic = ord.uMag; reqClsBY.symbol = _Symbol; // Instrument reqClsBY.volume = vol; // Volumen von 0.1 Lot reqClsBY.comment = "penTrail SL Mag: "+(string)(ord.uMag%1000000); Print("\n",FunLine," ####################### OK: 1st. ORDER for _CLOSE_BY tC:",(string)(ulong)TimeCurrent()," => ", "\n BaseOrder: ",_e2s(ord.dir)," ",(string)ord.uID," ",(string)ord.uMag," @ ",_d2D(ord.dOpn)," ",TimeToString(TimeCurrent(),TIME_SECONDS), "\n ClsByOrd: ",_e2s(reqClsBY.type)," vol: ",reqClsBY.volume," cmt: ",reqClsBY.comment); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, if(!OrderSendAsync(reqClsBY,resClsBY)) { Print("\n",__FUNCTION__,"[",__LINE__,"] ################ FAIL: 1st. ORDER_TYPE_CLOSE_BY ########", "\n ORDER_TYPE_CLOSE_BY OrderSendAsync error ",err(_LastError)," res.order ",resClsBY.retcode, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK)) ); Print(FunLine,prtRequ(reqClsBY)); Print(FunLine,prtResult(resClsBY)); return( chkFail(FunLine,reqClsBY,resClsBY) ); //ExpertRemove(); } else { //DebugBreak(); int i = ArrayNew(match); match[i][matchPOS]=ord.uID; //should be triggered first match[i][matchMAG]=ord.uMag; match[i][matchCLS]=resClsBY.order; //when triggered should close by matchPOS chkREQ(FunLine,reqClsBY,resClsBY.order); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, return(true); } return(false); } // use: tradePenOrdTP(oOrBU[i], 1.2, fmax(pLim,pStp), 100.0*_Point); bool tradePenOrdTP(_opTrd &ord, const double vol, const double diff) { MqlTradeRequest reqClsBY = {}; // ZeroMemory(reqClsBY); MqlTradeResult resClsBY = {}; // ZeroMemory(resClsBY); if ( ord.dir % 2 == 0 ) { int i = ArrayNew(oOrSE); // <= get a new element set to zero reqClsBY.type = ORDER_TYPE_SELL_LIMIT; // opposite direction oOrSE[i].dir = €SELLLIMIT; // opposite direction oOrSE[i].dOpn = ord.dOpn + diff; oOrSE[i].kind = €CloseBy; oOrSE[i].uMag = ord.uMag; oOrSE[i].uDevOrInf = DEVI; oOrSE[i].dVol = vol; oOrSE[i].status = €Send; reqClsBY.action = TRADE_ACTION_PENDING; // pending order reqClsBY.price = oOrSE[i].dOpn; reqClsBY.magic = ord.uMag; reqClsBY.symbol = _Symbol; // Instrument reqClsBY.volume = oOrSE[i].dVol; // Volumen von 0.1 Lot reqClsBY.comment = "penTrail TP Mag: "+(string)(ord.uMag%1000000); } else { int i = ArrayNew(oOrBU); // <= get a new element set to zero reqClsBY.type = ORDER_TYPE_BUY_LIMIT; // opposite direction oOrBU[i].dir = €BUYLIMIT; // opposite direction oOrBU[i].dOpn = ord.dOpn - diff; oOrBU[i].kind = €CloseBy; oOrBU[i].uMag = ord.uMag; oOrBU[i].uDevOrInf = DEVI; oOrBU[i].dVol = vol; oOrBU[i].status = €Send; reqClsBY.action = TRADE_ACTION_PENDING; // pending order reqClsBY.price = oOrBU[i].dOpn; reqClsBY.magic = ord.uMag; reqClsBY.symbol = _Symbol; // Instrument reqClsBY.volume = oOrBU[i].dVol; // Volumen von 0.1 Lot reqClsBY.comment = "penTrail TP Mag: "+(string)(ord.uMag%1000000); } Print("\n",FunLine," ####################### OK: 1st. ORDER for _CLOSE_BY tC:",(string)(ulong)TimeCurrent()," => ", "\n BaseOrder: ",_e2s(ord.dir)," ",(string)ord.uID," ",(string)ord.uMag," @ ",_d2D(ord.dOpn)," ",TimeToString(TimeCurrent(),TIME_SECONDS), "\n ClsByOrd: ",_e2s(reqClsBY.type)," p: ",_d2D(reqClsBY.price)," vol: ",reqClsBY.volume," cmt: ",reqClsBY.comment); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, 10015Invalid price in the request if(!OrderSendAsync(reqClsBY,resClsBY)) { Print("\n",__FUNCTION__,"[",__LINE__,"] ################ FAIL: 1st. ORDER_TYPE_CLOSE_BY ########", "\n ORDER_TYPE_CLOSE_BY OrderSendAsync error ",err(_LastError)," res.order ",resClsBY.retcode, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK)) ); Print(FunLine,prtRequ(reqClsBY)); Print(FunLine,prtResult(resClsBY)); return( chkFail(FunLine,reqClsBY,resClsBY) ); //ExpertRemove(); } else { //DebugBreak(); int m = ArrayNew(match); match[m][matchPOS]=ord.uID; //should be triggered first match[m][matchMAG]=ord.uMag; match[m][matchCLS]=resClsBY.order; //when triggered should close by matchPOS chkREQ(FunLine,reqClsBY,resClsBY.order); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, return(true); } return(false); } bool tradeCloseOpnPos(_opTrd &op[]) { int i = ArraySize(op), sz = i; if (sz<1) return(false); while(i-->0) { if (WhatDebug == €DebugConf || WhatDebug == €DebugAll) Print(__FUNCTION__,"[",__LINE__,"] CHECK cls #",op[i].uID," => ",prtOneOpnPos(op[i].uID,FunLine)); DeBugORDER = op[i].uID; bool ok = tradeCloseTckt(op[i].uID); if (!ok) { // tradeCloseTckt(op[i].uID)) { Print(__FUNCTION__,"[",__LINE__,"] CLOSE #",op[i].uID," FAILED ",prtOneOpnPos(op[i].uID,FunLine)); } //else already closed so array access error: Print(__FUNCTION__,"[",__LINE__,"] CLOSE #",oPO[i].uID," OK ",prtOneOpnPos(i)); } return(true); } //use: tradeCloseTckt(ticket) //, const ulong deviation=5); bool tradeCloseTckt(const ulong ticket, const ulong deviation=0) { //--- check stopped if(IsStopped()) return(false); if(!PositionSelectByTicket(ticket)) { adminRmvOpPos(ticket); return(true); } MqlTradeRequest req;MqlTradeResult res; ZeroMemory(req);ZeroMemory(res); req.symbol = PositionGetString(POSITION_SYMBOL); if ( ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) ) { req.type = ORDER_TYPE_SELL; req.price = SymbolInfoDouble(req.symbol,SYMBOL_BID); } else { req.type = ORDER_TYPE_BUY; req.price = SymbolInfoDouble(req.symbol,SYMBOL_ASK); } req.action = TRADE_ACTION_DEAL; req.position = ticket; req.volume = PositionGetDouble(POSITION_VOLUME); req.magic = PositionGetInteger(POSITION_MAGIC); req.deviation = deviation>0 ? deviation : 10; Print("\n",__FUNCTION__,"[",__LINE__,"] ####################### OK: POS Close 1st TRY tC:",(string)(ulong)TimeCurrent()," => ",(string)req.magic,"\n ",_Symbol," ",req.magic," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment,"\n SELL-STOP with SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); if(OrderSendAsync(req,res)) { //DebugBreak(); chkREQ(FunLine,req,res.order); DeBugORDER = res.order; Print(__FUNCTION__,"[",__LINE__,"] check started DeBugORDER: ",DeBugORDER); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, return(true); } else { Print("\n",__FUNCTION__,"[",__LINE__,"] ################ FAIL: POS Close 1st TRY ########\n ORDER_TYPE_CLOSE OrderSendAsync error ",err(_LastError)," res.order ",res.retcode, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK)) ); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); bool ok = chkFail(FunLine,req,res); if (ok) return(true); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); ok = chkFail(FunLine,req,res); if (ok) return(true); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); ok = chkFail(FunLine,req,res); if (ok) return(true); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); return(chkFail(FunLine,req,res)); //ExpertRemove(); } return(false); } //use: if(!tradeClosePartPos(tckt, 0.01); bool tradeClosePartPos(_opTrd &ord, const double volCls) { // first check position if (!PositionSelectByTicket(ord.uID)) return(false); MqlTradeRequest req={}; MqlTradeResult res={}; req.type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY; req.action = TRADE_ACTION_DEAL; // Typ der Transaktion req.position = ord.uID; req.price = PositionGetDouble(POSITION_PRICE_CURRENT); req.volume = volCls; req.symbol = PositionGetString(POSITION_SYMBOL); req.deviation = 10; req.comment = "cls Pos partially ("+_d22(PositionGetDouble(POSITION_VOLUME))+") Mag: "+(string)(ord.uMag%100000); Print("\n",FunLine," ####################### OK: Close Partially Position", "\n Pos tckt: ",ord.uID," mag:",ord.uMag," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment, "\n vol: ",PositionGetDouble(POSITION_VOLUME)," => clsVol: ",_d22(volCls)," => newVol ",_d22(PositionGetDouble(POSITION_VOLUME) - volCls)); if(!OrderSendAsync(req,res)) { Print(__FUNCTION__,"[",__LINE__,"] OrderSendAsync error ",err(_LastError)," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," bid: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_BID))," pCurr:",_d2D(req.price) ); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); return( chkFail(FunLine,req,res) ); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, } else { chkREQ(FunLine,req,res.order); return(true); } return(false); } //use: tradeCloseTcktByPos(t1, t2, mag); bool tradeCloseTcktByPos(const ulong t1, const ulong t2, const ulong m) { //--- check position existence if(!PositionSelectByTicket(t1)) return(false); string symbol=PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); if(!PositionSelectByTicket(t2)) 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); MqlTradeRequest req={}; MqlTradeResult res={}; //--- setting request req.action = TRADE_ACTION_CLOSE_BY; req.position = t1; req.position_by = t2; req.magic = m; //--- close position Print("\n",__FUNCTION__,"[",__LINE__,"] ####################### OK: Close 1 by 1 \n t1:",t1," t2:",t2," m:",m," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment,"\n MODIF POS SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); if (!OrderSendAsync(req,res)) { Print(__FUNCTION__,"[",__LINE__,"] OrderSendAsync Cls 1by1 error ",err(_LastError)," t1:",t1," t2:",t2," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," bid: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_BID))," pCurr:",_d2D(req.price) ); return( chkFail(FunLine,req,res) ); } else { chkREQ(FunLine,req,res.order); return(true); } } // use tradeNewTPSLPos(tckt, nSL:ask|bid +/- 400.0*_Point, nTP:ask|bid -/+ 200.0*_Point); bool tradeNewTPSLPos(const ulong tckt, const double nSL=0., const double nTP=0., const string from="") { if (nSL + nTP < _Point) return(false); if (!PositionSelectByTicket(tckt)) { Print(__FILE__,"[",__LINE__,"] tckt:",tckt," not found from: ",from," err:",err());return(false);} //DebugBreak(); MqlTradeRequest req={}; MqlTradeResult res={}; req.action = TRADE_ACTION_SLTP; // Typ der Transaktion req.position = tckt; req.price = PositionGetDouble(POSITION_PRICE_CURRENT); req.symbol = PositionGetString(POSITION_SYMBOL); req.magic = PositionGetInteger(POSITION_MAGIC); // MagicNumber der Position req.sl = (nSL>0.) ? nSL : PositionGetDouble(POSITION_SL); req.tp = (nTP>0.) ? nTP : PositionGetDouble(POSITION_TP); req.comment = "chg Pos "+(string)tckt+" sl:"+_d2D(nSL)+" tp:"+_d2D(nTP); if(false) prtRequ(req,__LINE__); if(!OrderSendAsync(req,res)) { Print(__FUNCTION__,"[",__LINE__,"] OrderSendAsync error ",err(_LastError)," from: ",from," res.order ",res.retcode," ",err(res.retcode)," tckt: ",tckt," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," bid: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_BID))," pCurr:",_d2D(req.price), " req.sl",_d2D(req.sl)," nSL",_d2D(nSL)," req.tp",_d2D(req.tp)," nTP",_d2D(nTP) ); return( chkFail(FunLine,req,res) ); } else { //Print("\n",__FUNCTION__,"[",__LINE__,"] ####################### OK:CHG SL/TP Position \n from: ",from," m:",req.magic," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment," MODIF POS SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); chkREQ(FunLine,req,res.order); return(true); } return(false); } // use tradeMoveTPSLPos(tckt, 400.0*_Point, 200.0*_Point); bool tradeMoveTPSLPos(_opTrd &ord, const double nSL=0., const double nTP=0.) { if (!PositionSelectByTicket(ord.uID)) return(false); MqlTradeRequest req={}; MqlTradeResult res={}; double dir = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY ? 1.0 : -1.0; req.action = TRADE_ACTION_SLTP; // Typ der Transaktion req.position = ord.uID; req.price = PositionGetDouble(POSITION_PRICE_CURRENT); req.symbol = PositionGetString(POSITION_SYMBOL); req.magic = PositionGetInteger(POSITION_MAGIC); // MagicNumber der Position if(nSL>0.) req.sl = req.price - dir*nSL; if(nTP>0.) req.tp = req.price + dir*nTP; req.comment = "chg Pos "+(string)ord.uID+" sl:"+_d2D(nSL)+" tp:"+_d2D(nTP); if(!OrderSendAsync(req,res)) { Print(FunLine," OrderSendAsync error ",err(_LastError)," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," bid: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_BID))," pCurr:",_d2D(req.price) ); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); return( chkFail(FunLine,req,res) ); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, } else { Print("\n",__FUNCTION__,"[",__LINE__,"] ####################### OK: CHG SL/TP Position \n mag:",req.magic," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment,"\n MODIF POS SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); chkREQ(FunLine,req,req.position); return(true); } return(false); } // use tradeMoveTPSLPos(tckt, 400.0*_Point, 200.0*_Point); bool tradeTrailTPSLPos(const ulong tckt, const int nSL=0, const int nTP=0, const €SetMoveTpSl newTpSl=€MoveTpSl) { if (!PositionSelectByTicket(tckt) || nSL+nTP==0) return(false); MqlTradeRequest req={}; MqlTradeResult res={}; double dir = PositionGetInteger(POSITION_TYPE)%2 == 0 ? 1.0 : -1.0; // Type % 2 == all BUYs double pnt = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL),SYMBOL_POINT); req.price = PositionGetDouble(POSITION_PRICE_CURRENT); if (newTpSl==€MoveTpSl) { if(nSL>0.) req.sl = PositionGetDouble(POSITION_SL) - dir*nSL*pnt; if(nTP>0.) req.tp = PositionGetDouble(POSITION_TP) + dir*nTP*pnt; } else { if(nSL>0.) req.sl = req.price - dir*nSL*pnt; if(nTP>0.) req.tp = req.price + dir*nTP*pnt; } req.action = TRADE_ACTION_SLTP; // Typ der Transaktion req.position = tckt; req.symbol = PositionGetString(POSITION_SYMBOL); req.magic = PositionGetInteger(POSITION_MAGIC); // MagicNumber der Position req.comment = "chg Pos "+(string)tckt+" sl:"+_d21(nSL)+" tp:"+_d21(nTP); if(!OrderSendAsync(req,res)) { Print(__FUNCTION__,"[",__LINE__,"] OrderSendAsync error ",err(_LastError)," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," bid: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_BID))," pCurr:",_d2D(req.price) ); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); return( chkFail(FunLine,req,res) ); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, } else { Print("\n",__FUNCTION__,"[",__LINE__,"] ####################### OK: Set SL, TP of Position \n ",req.magic," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment," MODIF POS SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); chkREQ(FunLine,req,res.order); return(true); } return(false); } // use tradeNewTPSLOrd(tradeNewTPSLOrd, 400.0*_Point); bool tradeNewTPSLOrd(_opTrd &ord, const double nSL=0., const double nTP=0.) { if (!OrderSelect(ord.uID)) return(false); MqlTradeRequest req={}; MqlTradeResult res={}; req.symbol = OrderGetString(ORDER_SYMBOL); req.action = TRADE_ACTION_MODIFY; // Typ der Transaktion req.magic = OrderGetInteger(ORDER_MAGIC); // MagicNumber der Order req.order = ord.uID; req.stoplimit = OrderGetDouble(ORDER_PRICE_STOPLIMIT); req.price = OrderGetDouble(ORDER_PRICE_OPEN); // use of ORDER_PRICE_CURRENT will trigger the pend.order. immediately ;) req.sl = nSL>0. ? nSL : OrderGetDouble(ORDER_SL); req.tp = nTP>0. ? nTP : OrderGetDouble(ORDER_TP); req.type_time = (ENUM_ORDER_TYPE_TIME)OrderGetInteger(ORDER_TYPE_TIME); req.expiration = (datetime)OrderGetInteger(ORDER_TIME_EXPIRATION); req.comment = "chg Ord "+(string)(ord.uID%100000)+" sl:"+_d2D(nSL)+" tp:"+_d2D(nTP); if(!OrderSendAsync(req,res)) { Print(__FUNCTION__,"[",__LINE__,"] OrderSendAsync error ",err(_LastError)," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(TimeCurrent())," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," bid: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_BID))," pCurr:",_d2D(req.price) ); Print(FunLine,prtRequ(req)); Print(FunLine,prtResult(res)); return( chkFail(FunLine,req,res) ); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, } else { Print("\n",__FUNCTION__,"[",__LINE__,"] ####################### OK: chg OpnOrd SL, TP \n ",req.magic," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment," MODIF POS SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); chkREQ(FunLine,req,res.order); return(true); } return(false); } // Kochbuch OnTradeTransaction: OnTradeTransaction 1.1316999999999999 void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { ulong p = fmax(trans.position,request.position), // ticket number of a position o = fmax3(trans.order,request.order,result.order), // ticket number of an order d = fmax(trans.deal,result.deal), // ticket number of a deal pB = fmax(trans.position_by,request.position_by), // ticket number of a conjugated position m = request.magic, mP=0,mO=0,mD=0; // magic number string sym = fmax(trans.symbol,request.symbol), // symbol sQts = ""; if (StringLen(sym)<4) DebugBreak(); ResetLastError(); if (false && ( m%1000 == 55 && TimeCurrent() > D'2022.02.03 02:23:00')) { // 2023.01.09 15:16:15 take profit triggered #16 buy 1 EURUSD 1.06942 sl: 1.06488 tp: 1.07017 [#17 sell 1 EURUSD at 1.07017] //if ( TimeCurrent()>D'2022.02.03 14:40:59' && OrdersTotal() == 0 ) { //if ( true && (TimeCurrent()>D'2022.02.03 01:59:58' || (DeBugORDER>0 && (DeBugORDER == o || DeBugORDER == p)) )) { if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; if(o>0 && OrderSelect(o)) mO = (ulong)OrderGetInteger(ORDER_MAGIC); else mO=1; if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; MqlTick lT; SymbolInfoTick(_Symbol,lT); sQts=StringFormat("ask:%s bid:%s",_d2D(lT.ask),_d2D(lT.bid)); Print(__FUNCTION__,"[",__LINE__,"] mag:",m," nOrd:",OrdersTotal(),", nPos:",PositionsTotal(),", ",sQts); prtListOpnOrdr(); prtListOpnPos(); prtOneOpnPos(p, FunLine); listOpMatch(FunLine); ArrayPrint(ReqCHCK); Print(__FUNCTION__,"[",__LINE__,"] DEBUG res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," mO:",mO," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)," res.ret;",result.retcode); //Print(FunLine,prtTrans(trans)); //Print(FunLine,prtRequ(request)); //Print(FunLine,prtResult(result)); DebugBreak(); } int iConf = -2147483648; //--- first case result returns success == 10009 if (result.retcode==10009) { switch (request.action) { case TRADE_ACTION_DEAL: if(p>0 && o>p) { if(false)Print(__FUNCTION__,"[",__LINE__,"] TRIG (Part.) CLS res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); iConf = confReq(sym, m, trans, request); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] szReq: ",ArraySize(ReqCHCK)," ",prtRequ(request,__LINE__ )); return; } else if (p>0 && o==p) { if (m==0) { if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; m = fmax(mD,mP); } if(false)Print(__FUNCTION__,"[",__LINE__,"] TRIG OPN new MKT-POS a) res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); iConf = confReq(sym, m, trans, request); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] szReq: ",ArraySize(ReqCHCK)," ",prtRequ(request,__LINE__ )); return; } else if (d>0 && o>0 && m>0) { if (HistoryDealSelect(d)) if(false)Print(FunLine,__LINE__,prtHistDeal(d)); if(true) iConf = confReq(sym, m, trans, request); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] already confirmed new MKT-POS b) res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); else Print(__FUNCTION__,"[",__LINE__,"] TRIG OPN new MKT-POS b) res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); return; } else { if(true)Print(__FUNCTION__,"[",__LINE__,"] ???? TRADE_ACTION_DEAL res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } return; case TRADE_ACTION_PENDING: if(OrderSelect(o)) m = (ulong)OrderGetInteger(ORDER_MAGIC); else m=1; if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG Pend:Accpt res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); iConf = confReq(sym, m, trans, request, result); if (iConf==-1) Print(FunLine," szReq: ",ArraySize(ReqCHCK));//," ",prtRequ(request,__LINE__ )); return; case TRADE_ACTION_SLTP: if(false)Print(FunLine," TRIG CHG SL,TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); iConf = confReq(sym, request.magic, trans, request); if (iConf==-1) Print(FunLine," szReq: ",ArraySize(ReqCHCK)," ",prtRequ(request,__LINE__ )); else Print(FunLine," ADMIN openPos Arrays"); return; case TRADE_ACTION_MODIFY: if(OrderSelect(o)) m = (ulong)OrderGetInteger(ORDER_MAGIC); else { m=1; if(true) Print(FunLine," TRIG CHG SL, TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } if (m>1) { iConf = confReq(sym, m, trans, request); if (iConf==-1) Print(FunLine," szReq: ",ArraySize(ReqCHCK)," ",prtRequ(request,__LINE__ )); else Print(FunLine," ADMIN openPos Arrays"); // order not fpund => already processed } return; /* default: if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; if(o>0 && OrderSelect(o)) mO = (ulong)OrderGetInteger(ORDER_MAGIC); else mO=1; if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if (mP>1 || mO>1) if(false)Print(__FUNCTION__,"[",__LINE__,"] SKIP trans.type==TRADE_TRANSACTION_HISTORY_ADD res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," mO:",mO," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); */ } //--- second case the type of trans is needed HISTORY_ADD: } else if (trans.type==TRADE_TRANSACTION_HISTORY_ADD) { // #p > 0 && #po == #p if (p==o && p>0 && trans.order_type> ORDER_TYPE_SELL ) { // pending order send? if(PositionSelectByTicket(p)) m = (ulong)PositionGetInteger(POSITION_MAGIC); else m=1; iConf = confReq(sym, m, trans, request); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] szReq: ",ArraySize(ReqCHCK));//," ",prtRequ(request,__LINE__ )); int i = getOpMatch(m,p); if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG Pend:POS res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n match:",i," iConf:",iConf," tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); //listOpMatch();//int i = getOpMatch(mag, //prtListOpnOrdr(); //prtListOpnPos(); //ArrayPrint(ReqCHCK); return; // #p > 0 && #o > #p } else if (p>0 && o>p && d>0) { if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; ENUM_DEAL_ENTRY how = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(d,DEAL_ENTRY); // DEAL_ENTRY_OUT ENUM_DEAL_REASON why = (ENUM_DEAL_REASON)HistoryDealGetInteger(d,DEAL_REASON); // DEAL_REASON_EXPERT if(false)Print(__FUNCTION__,"[",__LINE__,"] TRIG CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); if ( how == DEAL_ENTRY_OUT_BY || how == DEAL_ENTRY_OUT ) { //if(false)Print(FunLine,prtHistDeal(d));Print(FunLine,prtTrans(trans)); //Print(FunLine,prtRequ(request));Print(FunLine,prtResult(result)); int i = getOpMatch(m,p); iConf = confReq(sym, mD, p, how); if (iConf==-1) Print(FunLine," szReq: ",ArraySize(ReqCHCK)," match:",i," iConf:",iConf); listOpMatch(FunLine,"TRADE_TRANSACTION_HISTORY_ADD"); } else if ( mP!=1) { if(true)Print(FunLine," SL,TP TRIGG res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } else if (p>0 && mP==1 ) { if(true)Print(FunLine," SL,TP TRIGG POS CLSD res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } else { if(true)Print(FunLine," SL,TP ??? res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } return; } /* else { if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; if(o>0 && OrderSelect(o)) mO = (ulong)OrderGetInteger(ORDER_MAGIC); else mO=1; if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if (mP>1 || mO>1) if(false)Print(__FUNCTION__,"[",__LINE__,"] SKIP trans.type==TRADE_TRANSACTION_HISTORY_ADD res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," mO:",mO," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } */ //--- third case the type of trans is needed DEAL_ADD with #deal !=0: } else if (p>0 && o==p && d>0 && trans.type==TRADE_TRANSACTION_DEAL_ADD) { if(false) Print(__FUNCTION__,"[",__LINE__,"] SKIP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," mO:",mO," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)," res.ret;",result.retcode); if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; if(HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if( mD>1 ) { ENUM_DEAL_ENTRY how = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(d,DEAL_ENTRY); // DEAL_ENTRY_OUT ENUM_DEAL_REASON why = (ENUM_DEAL_REASON)HistoryDealGetInteger(d,DEAL_REASON); // DEAL_REASON_EXPERT int i = getOpMatch(mD,p); if(false)Print(__FUNCTION__,"[",__LINE__,"] TRIG SellStop CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n match[:",i,"] how:",_e2s(how)," why:",_e2s(why),"tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); if ( how == DEAL_ENTRY_IN ) { if ( i<0 ) { // no match iConf = confReq(sym, mD, trans, request); if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG SellStop CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n match[:",i,"] confREQ:",iConf," how:",_e2s(how)," why:",_e2s(why),"tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); //if (iConf==-1) } else { //Print(FunLine,prtHistDeal(d));Print(FunLine,prtTrans(trans)); //Print(FunLine,prtRequ(request));Print(FunLine,prtResult(result)); iConf = confReq(sym, mD, p, how); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] szReq: ",ArraySize(ReqCHCK));//," ",prtRequ(request,__LINE__ )); if(false) listOpMatch(FunLine,"TRADE_TRANSACTION_DEAL_ADD, DEAL_ENTRY_IN"); i = getOpMatch(mD,p); if (tradeCloseTcktByPos(match[i][matchPOS],match[i][matchCLS],match[i][matchMAG])) { if(rmvOpMatch(i)) if(true)Print(__FUNCTION__,"[",__LINE__,"] OK DEAL_ENTRY_IN rmv err: ",err()); } else if(false)Print(__FUNCTION__,"[",__LINE__,"] FAIL DEAL_ENTRY_IN rmv err: ",err()); } } else if ( how == DEAL_ENTRY_OUT_BY || how == DEAL_ENTRY_OUT ) { //Print(FunLine,prtHistDeal(d));Print(FunLine,prtTrans(trans)); //Print(FunLine,prtRequ(request));Print(FunLine,prtResult(result)); iConf = confReq(sym, mD, p, how); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] szReq: ",ArraySize(ReqCHCK)," ",prtRequ(request,__LINE__ )); listOpMatch(FunLine,"TRADE_TRANSACTION_DEAL_ADD, DEAL_ENTRY_IN"); i = getOpMatch(mD,p); if (tradeCloseTcktByPos(match[i][matchPOS],match[i][matchCLS],match[i][matchMAG])) { if(rmvOpMatch(i)) if(true)Print(__FUNCTION__,"[",__LINE__,"] OK DEAL_ENTRY_OUT_BY rmv err: ",err()); } else if(false)Print(__FUNCTION__,"[",__LINE__,"] FAIL DEAL_ENTRY_OUT_BY rmv err: ",err()); } else if ( why == DEAL_REASON_TP || why == DEAL_REASON_SL ) { if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } else { if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG TRADE_TRANSACTION_DEAL_ADD res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } } else { if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; if(o>0 && OrderSelect(o)) mO = (ulong)OrderGetInteger(ORDER_MAGIC); else mO=1; if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if (mP>1 || mO>1) if(true)Print(__FUNCTION__,"[",__LINE__,"] SKIP trans.type==TRADE_TRANSACTION_DEAL_ADD res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," mO:",mO," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } } else if (p>0 && o>p && trans.type==TRADE_TRANSACTION_DEAL_ADD) { if(HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if( mD>1 ) { ENUM_DEAL_ENTRY how = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(d,DEAL_ENTRY); // DEAL_ENTRY_OUT ENUM_DEAL_REASON why = (ENUM_DEAL_REASON)HistoryDealGetInteger(d,DEAL_REASON); // DEAL_REASON_EXPERT //Print(__FUNCTION__,"[",__LINE__,"] TRIG CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",mD," ",err(), // "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); if ( why == DEAL_REASON_TP ) { ulong idCls = adminRmvOpPos(p,trans.price); if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",mD," CLOSE id:",idCls," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } else if (why == DEAL_REASON_SL ) { ulong idCls = adminRmvOpPos(p,trans.price); if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",mD," CLOSE id:",idCls," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } else if ( how == DEAL_ENTRY_OUT_BY || how == DEAL_ENTRY_OUT ) { //if(false)Print(FunLine,prtHistDeal(d));Print(FunLine,prtTrans(trans)); //Print(FunLine,prtRequ(request));Print(FunLine,prtResult(result)); if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG CLS POS by SL or TP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",mD," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); iConf = confReq(sym, mD, p, how); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] szReq: ",ArraySize(ReqCHCK)," ",prtRequ(request,__LINE__ )); } else { if(true)Print(__FUNCTION__,"[",__LINE__,"] TRIG TRADE_TRANSACTION_DEAL_ADD res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",mD," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } } else { if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; if(o>0 && OrderSelect(o)) mO = (ulong)OrderGetInteger(ORDER_MAGIC); else mO=1; if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if (mP>1 || mO>1) Print(__FUNCTION__,"[",__LINE__,"] partial Close (Market) res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," mO:",mO," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } } else if (o>0 && trans.type==TRADE_TRANSACTION_ORDER_UPDATE && (trans.order_type==ORDER_TYPE_BUY_LIMIT || trans.order_type==ORDER_TYPE_SELL_LIMIT)) { if(OrderSelect(o)) m = (ulong)OrderGetInteger(ORDER_MAGIC); else m=1; if(true)Print(__FUNCTION__,"[",__LINE__,"] StpLim => LIM res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mag:",m," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); iConf = confReq(sym, m, trans, request); if (iConf==-1) Print(__FUNCTION__,"[",__LINE__,"] szReq: ",ArraySize(ReqCHCK) );//," ",prtRequ(request,__LINE__ )); } else if (false) { if(p>0 && PositionSelectByTicket(p)) mP = (ulong)PositionGetInteger(POSITION_MAGIC); else mP=1; if(o>0 && OrderSelect(o)) mO = (ulong)OrderGetInteger(ORDER_MAGIC); else mO=1; if(d>0 && HistoryDealSelect(d)) mD = (ulong)HistoryDealGetInteger(d,DEAL_MAGIC); else mD=1; if (mP>1 || mO>1) Print(__FUNCTION__,"[",__LINE__,"] SKIP res:",result.retcode," d:",d," p:",p," o:",o," pB:",pB," rO:",result.order," mD:",mD," mP:",mP," mO:",mO," ",err(), "\n tr.type:",_e2s(trans.type)," tr.orT:",_e2s(trans.order_type)," rq.act:",_e2s(request.action)," rq.typ:",_e2s(request.type)); } return; }