ETE/EasyTradeEvent 02.mqh

884 lines
100 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:53:15 +02:00
<EFBFBD><EFBFBD>/*+------------------------------------------------------------------+
//| EasyTradeEvent.mqh |
//| #include <EasyTradeEvent.mqh> <= 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 <EFBFBD> BUY:
case <EFBFBD> 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 <EFBFBD> BUYSTOP:
case <EFBFBD> SELLSTOP:
case <EFBFBD> BUYLIMIT:
case <EFBFBD> SELLLIMIT:
case <EFBFBD> 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 <EFBFBD> SELLSTOPLIMIT:
default: return(0);
}
if( !OrderCheck(rq,rc) ) {
ord.status = <EFBFBD> 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 = <EFBFBD> SELLLIMIT; // opposite direction
oOrSE[i].dOpn = ord.dOpn + diff;
oOrSE[i].kind = <EFBFBD> CloseBy;
oOrSE[i].uMag = ord.uMag;
oOrSE[i].uDevOrInf = DEVI;
oOrSE[i].dVol = vol;
oOrSE[i].status = <EFBFBD> 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 = <EFBFBD> BUYLIMIT; // opposite direction
oOrBU[i].dOpn = ord.dOpn - diff;
oOrBU[i].kind = <EFBFBD> CloseBy;
oOrBU[i].uMag = ord.uMag;
oOrBU[i].uDevOrInf = DEVI;
oOrBU[i].dVol = vol;
oOrBU[i].status = <EFBFBD> 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 == <EFBFBD> DebugConf || WhatDebug == <EFBFBD> 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 <EFBFBD> SetMoveTpSl newTpSl=<EFBFBD> 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==<EFBFBD> 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;
}