/*+------------------------------------------------------------------+ //| ETE.mq5 | //| Calli | //| https://www.mql5.com/de/users/gooly | //+------------------------------------------------------------------*/ #property copyright "Calli" #property link "https://www.mql5.com/de/users/gooly" #property version "1.00" /////////////////////////////////////////// // // Debugging configuration // // Activate and Include debugging library #define LIB_DEBUG #define LIB_DEBUG_MQLAPI_TRACE #include // Activate tracing for OnInit #define DBG_TRACE_EXPERT_MAIN_ONINIT // Activate tracing for OnTick #define DBG_TRACE_EXPERT_MAIN_ONTICK // Activate tracing for confReq #define DBG_TRACE_ETE_INCL_CONFREQ // In case lib_debug is not available #ifndef LIB_DBG_DEBUG_MQH_INCLUDED #define PERF_COUNTER_BEGIN #define DBG_MSG_TRACE_BEGIN #define DBG_MSG_TRACE_RETURN return #define DBG_MSG_NOTRACE_RETURN return #define DBG_MSG_TRACE_RETURN_VAR(x) return(x) #define DBG_MSG_NOTRACE_RETURN_VAR(x) return(x) #define DBG_MSG(x) #define DBG_MSG_VAR(x) #define DBG_MSG_EVAL(x) x #define DBG_MSG_EVAL_CMNT(c, x) x #define DBG_ENUM_RESOLVER(x) #endif // /////////////////////////////////////////// // Include EasyTradeEvent #include "EasyTradeEvent 02.mqh" /* from EasyTradeEvent_INCL to enum €DeBug { €DebugNon, €DebugAll, €DebugSend, €DebugMatch, €DebugETE, €DebugConf, } WhatDebug; */ /* from EasyTradeEvent_INCL to know what to set: enum €DeBug { €DebugNon, €DebugAll, €DebugSend, €DebugMatch, €DebugETE, €DebugConf, } WhatDebug; */ // User input //## input datetime tStpLim = D'2022.02.03 02:00'; input int DEVI = 10; input ushort PlanA_Mag = 11; input double PlanA_pStp = 1.12670; input double PlanA_pLim = 1.13070; input int PlanA_secCheck = 10; // wait sec between trail check input ushort PlanB_Mag = 42; // Global variables static ulong mMktBu = 0, mStpBu = 0, _tCo = 0, _tCx = 0, _tCm = 0, _Mag = 0, debugMag = 0; static datetime tStpLimOrdSe = 0, tSetStpOrdBu = 0, tSetPenO = 0, tSetOpnPos = 0, tSetSL = 0, tSetTP = 0, tSetTPP = D'3000.12.12', NxtTry = D'3000.12.31', tCall = 0, tC = 0; static int EAStep = 0, noGlobCalls = 0, noSingCalls = 0; static bool IsLive = false, bStpLimOrdSe = false, bSetStpOrdBu = false, askTick = false; static MqlTick lstTick = {}; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ #ifdef DBG_TRACE_EXPERT_MAIN_ONINIT #undef DBG_TRACE_EXPERT_MAIN_ONINIT #define DBG_TRACE_EXPERT_MAIN_ONINIT(x) x #define DBG_TRACE_EXPERT_MAIN_ONINIT_RETURN(x) DBG_MSG_TRACE_RETURN_VAR(x) #else #define DBG_TRACE_EXPERT_MAIN_ONINIT(x) #define DBG_TRACE_EXPERT_MAIN_ONINIT_RETURN(x) DBG_MSG_NOTRACE_RETURN_VAR(x) #endif int OnInit() { DBG_TRACE_EXPERT_MAIN_ONINIT( DBG_MSG_TRACE_BEGIN; DBG_MSG_VAR(tStpLim); DBG_MSG_VAR(PlanA_pStp); DBG_MSG_VAR(PlanA_pLim); ); PERF_COUNTER_BEGIN; //--- // Do not use server related stuff in OnInit() SymbolInfoTick(_Symbol,lstTick); // start dld of qts tStpLimOrdSe = TimeCurrent() + 3*60; // Init debug level WhatDebug = €DebugMatch; DBG_TRACE_EXPERT_MAIN_ONINIT( DBG_MSG_VAR(lstTick); DBG_MSG_VAR(tStpLimOrdSe); DBG_MSG_VAR(WhatDebug); ); //--- DBG_TRACE_EXPERT_MAIN_ONINIT_RETURN(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ #ifdef DBG_TRACE_EXPERT_MAIN_ONTICK #undef DBG_TRACE_EXPERT_MAIN_ONTICK #define DBG_TRACE_EXPERT_MAIN_ONTICK(x) x #define DBG_TRACE_EXPERT_MAIN_ONTICK_RETURN DBG_MSG_TRACE_RETURN #else #define DBG_TRACE_EXPERT_MAIN_ONTICK(x) #define DBG_TRACE_EXPERT_MAIN_ONTICK_RETURN DBG_MSG_NOTRACE_RETURN #endif void OnTick() { DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_TRACE_BEGIN; DBG_MSG_VAR(_Symbol); ); PERF_COUNTER_BEGIN; // Static init static MqlTradeRequest reqClsBY = {}; static int nOpn = 0; static datetime kill = 0; static bool PrtEd = false; static bool opPosTpSL = false; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(reqClsBY); DBG_MSG_VAR(nOpn); DBG_MSG_VAR(kill); DBG_MSG_VAR(PrtEd); DBG_MSG_VAR(opPosTpSL); ); // Local init MqlTradeRequest req = {}; MqlTradeResult res = {}; string sym = _Symbol; StringToLower(sym); // Preinit tC = TimeCurrent(); SymbolInfoTick(_Symbol, lstTick); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(tC); DBG_MSG_VAR(lstTick); ); // Exit before input time is not reached if ( DBG_MSG_EVAL( tC < tStpLim ) ) { DBG_TRACE_EXPERT_MAIN_ONTICK_RETURN; } // not to get in wrong time period /*//## just to demonstate the usage of TimeCurrent or TickCount with space for the unique ID (0..999) of the users _tCo = IsLive ? GetTickCount64() : (ulong)tC; _tCx = ((IsLive ? GetTickCount64()/100 : (ulong)tC*10)*100); _tCm = ((IsLive ? GetTickCount64()/100 : (ulong)tC*10)*100) + GetTickCount()%100; // <= a random number as uniqe ID _Mag = _tCm%1000; */ DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(_tCo); DBG_MSG_VAR(_tCx); DBG_MSG_VAR(_tCm); DBG_MSG_VAR(_Mag); ); //-- 1. place a pending order stop-limit order if ( DBG_MSG_EVAL(!bStpLimOrdSe) && DBG_MSG_EVAL(tC > tStpLimOrdSe) ) { if ( true ) { // Die Grundidee hier ist eine Position mit einem kleinen Zeil teilweise zu schließen und den Rest weiterlaufen zu lassen // Dazu wird eine Stop-Limit-Order abgeschickt und dann eine zweite Sell-Limit-Order mit kleinerem Volumen, die, wenn getriggert, // teilweise die große Position schließt. Ein normaler TP würde ja immer die ganze Position schließen. // So kann beides auf einmal abgeschickt werden: Fire & Forget. // Große Order mit Vol = 3.5 (zur Wiedererkennung über Volume) //## int i = ArrayNew(oOrBU); // <= get a new element set to zero oOrBU[i].dir = €BUYSTOPLIMIT; oOrBU[i].kind = €BuyPlanA; oOrBU[i].uMag = ((IsLive ? GetTickCount64()/100 : (ulong)tC*10)*100) + PlanA_Mag; oOrBU[i].dOpn = PlanA_pLim; oOrBU[i].dStLim = PlanA_pStp; oOrBU[i].uDevOrInf= DEVI; oOrBU[i].dVol = 3.5; oOrBU[i].tDiff = PlanA_secCheck; oOrBU[i].dSL = oOrBU[i].dStLim - 300.0*_Point; // Stop Loss nicht angegeben oOrBU[i].dTP = oOrBU[i].dStLim + 700.0*_Point; // Take Profit nicht angegeben oOrBU[i].dUpd = oOrBU[i].dOpn + 0.8*(oOrBU[i].dTP + oOrBU[i].dTP); oOrBU[i].status = €Send; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG("####################### OK: place ORDER_TYPE_SELL_STOP_LIMIT & Limit_BUY to close"); DBG_MSG_VAR(oOrBU[i]); //##DBG_MSG_VAR(req); DBG_MSG_VAR(sym); DBG_MSG_VAR(TimeCurrent()); ); //## if( DBG_MSG_EVAL(!OrderSendAsync(req,res)) ) if( DBG_MSG_EVAL( sndOrder(oOrBU[i])==0 ) ) { /* Print(__LINE__," OrderSendAsync error ",err(_LastError)," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(tC)," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK)) ); // wenn die Anfrage konnte nicht gesendet werden, den Fehlercode anzeigen Print(__LINE__," ",prtRequ(req)); Print(__LINE__," ", prtResult(res)); */ Print(FunLine," Buy-Stop-Limit order failed reaction not yet defined."); //## chkFail(__FUNCTION__,req,res); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, } else { tradePenOrdTP(oOrBU[i], 1.2, 100.0*_Point); //## close partly by TP as pend Order // just for thos EA to set the trade sequence ... bStpLimOrdSe = true; tStpLimOrdSe = D'3000.12.31'; EAStep++; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(bStpLimOrdSe); DBG_MSG_VAR(tStpLimOrdSe); ); tSetSL = TimeCurrent() + 2*60; tSetTP = TimeCurrent() + 5*60; tSetPenO = TimeCurrent() + 5*60; tSetOpnPos = TimeCurrent() + 6*60; EAStep++; //int sz = ArraySize(match);ArrayResize(match,sz+1);match[sz][dPos]=res.order;match[sz][dMag]=req.magic; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(tSetSL); DBG_MSG_VAR(tSetTP); DBG_MSG_VAR(tSetPenO); DBG_MSG_VAR(tSetOpnPos); DBG_MSG_VAR(EAStep); ); } if(false) listOpMatch(FunLine); //## FunLine } //--- Sell Market order if ( DBG_MSG_EVAL_CMNT("not yet opened", !opPosTpSL) ) { // <= not yet opened //## int i = ArrayNew(oPoSE); // <= get a new element set to zero oPoSE[i].dir = €SELL; oPoSE[i].kind = €SellPlanB; oPoSE[i].uMag = ((IsLive ? GetTickCount64()/100 : (ulong)tC*10)*100) + PlanB_Mag; oPoSE[i].dOpn = lstTick.bid; oPoSE[i].uDevOrInf= DEVI; oPoSE[i].dVol = 2.7; oPoSE[i].dSL = lstTick.bid + 500.0*_Point; // Stop Loss nicht angegeben oPoSE[i].dTP = lstTick.bid - 100.0*_Point; // Take Profit nicht angegeben oPoSE[i].dUpd = oPoSE[i].dOpn + 0.8*(oPoSE[i].dTP + oPoSE[i].dTP); oPoSE[i].status = €Send; debugMag = req.magic; //--- bilde den Preis für die Pending Order //--- req.price=GetRandomPrice(req.type); //Print("\n####################### OK: place Market-Order Sell close\n",__LINE__," ",sym," ",req.magic," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment,"\n SELL with SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG("####################### OK: place Market-Order Sell close"); DBG_MSG_VAR(req); ); if ( sndOrder(oPoSE[i])==0) // FAILED //## if( DBG_MSG_EVAL(!OrderSendAsync(req,res)) ) { /* Print(__LINE__," OrderSendAsync Market-Order Sell error ",err(_LastError),"\n res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(tC)," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK)) ); // wenn die Anfrage konnte nicht gesendet werden, den Fehlercode anzeigen //Print(__LINE__," ",prtRequ(req));Print(__LINE__," ", prtResult(res)); */ Print(FunLine," Sell market order failed reaction not yet defined."); //## chkFail(FunLine, req,res); ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, } else { //## chkREQ(FunLine,req,res.order); opPosTpSL = true; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(opPosTpSL); ); } if(false) listOpMatch(FunLine); // for an easy check } } //-- 3. changing the SL of an pending order if ( true && DBG_MSG_EVAL(TimeCurrent() > tSetSL) ) { int o=ArraySize(oPoSE); //## OrdersTotal(); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(ArraySize(oPoSE)); //## ); while(o-- > 0) { /*//##ulong tckt = OrderGetTicket(o); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(tckt); ); */ //##if( DBG_MSG_EVAL_CMNT("skip buys, process only sells", OrderGetInteger(ORDER_TYPE)%2==0) ) //##{ continue; } // skip buys only sells //##if( DBG_MSG_EVAL(!tradeNewTPSLOrd(tckt, fmax(PlanA_pStp,PlanA_pLim) + 400.0*_Point)) ) // tradeNewTPSLOrd(oPoSE[o], oPoSE[o].dSL + 123.0*_Point) if( DBG_MSG_EVAL(!tradeNewTPSLOrd(oPoSE[o], oPoSE[o].dSL + 123.0*_Point)) ) // { DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(tC); DBG_MSG_VAR(SymbolInfoDouble(_Symbol,SYMBOL_ASK)); ); /* Print(__LINE__," OrderSendAsync error ",err(_LastError)," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(tC)," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," p:",_d2D(req.price)," sl:",_d2D(req.sl)," tp:",_d2D(req.tp) ); prtRequ(req); prtResult(res); */ //## Print(FunLine," Sell market order failed reaction not yet defined.");//## ResetLastError(); // err: 4756=ERR_TRADE_SEND_FAILED, 10013=TRADE_RETCODE_INVALID, } else { //Print("\n####################### OK: CHG ST || TP openOrders \n",__LINE__," ",sym," ",TimeToString(TimeCurrent(),TIME_SECONDS)," ",req.comment," MODIF ORD SL & TP r.ID: ",res.request_id," d.O: ",res.deal," r.O: ",res.order," r.ret: ",res.retcode); tSetSL = D'2022.10.05 09:40:00'; // sl change of an open poosition tSetTP = TimeCurrent()+ 3*60; // perform tp by closeBy of another position EAStep++; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG("####################### OK: CHG ST || TP openOrders "); DBG_MSG_VAR(res); DBG_MSG_VAR(sym); DBG_MSG_VAR(tSetSL); DBG_MSG_VAR(tSetTP); DBG_MSG_VAR(EAStep); ); } } if (false) listOpMatch(FunLine); } //-- 4. partially close 0.2 lot the open position with 1 lot. if ( true && DBG_MSG_EVAL(tC > tSetTP) && DBG_MSG_EVAL(PositionsTotal() > 0) ) { int p = ArraySize(oPoSE); //## PositionsTotal(); /*//##DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(PositionsTotal()); ); *///## while(p-- > 0) { ulong tckt = PositionSelectByTicket(oPoSE[p].uID); //## PositionGetTicket(p), //##mag = PositionGetInteger(POSITION_MAGIC); //## DBG_TRACE_EXPERT_MAIN_ONTICK( //## implicit conversion from 'number' to 'string' ETE.mq5 460 17 DBG_MSG_VAR(tckt); //##DBG_MSG_VAR(mag); ); if( DBG_MSG_EVAL_CMNT("no tickets", tckt == 0 )) { continue; } //## if( DBG_MSG_EVAL_CMNT("Not my magic number", mag%1000 == 0 )) //## { continue; } double pr = PositionGetDouble(POSITION_PROFIT) ; //PositionGetDouble(POSITION_PRICE_CURRENT); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(pr); ); if (DBG_MSG_EVAL( pr < 50.0 )) { continue; } // user decision //## if( DBG_MSG_EVAL_CMNT("closing 50% of the position", !tradeClosePartPos(tckt, 0.5*PositionGetDouble(POSITION_VOLUME))) ) if( DBG_MSG_EVAL_CMNT("closing 40% of the position", !tradeClosePartPos(oPoSE[p], 0.4*PositionGetDouble(POSITION_VOLUME))) ) { // closing 50% of the position /* Print(__LINE__," OrderSendAsync part Close error ",err(_LastError)," res.order ",res.retcode," ",err(res.retcode)," r.D: ",res.deal," r.O: ",res.order, "\ntC ",_t2All(tC)," ask: ",_d2D(SymbolInfoDouble(_Symbol,SYMBOL_ASK))," p:",_d2D(req.price)," sl:",_d2D(req.sl)," tp:",_d2D(req.tp) ); */ DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG(" OrderSendAsync part Close error "); //##DBG_MSG_VAR(res); DBG_MSG_VAR(tC); DBG_MSG_VAR(sym); DBG_MSG_VAR(SymbolInfoDouble(_Symbol,SYMBOL_ASK)); ); } else { //Print("\n####################### OK: Close Partially Position \n",__LINE__," ",sym," ",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); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG("####################### OK: Close Partially Position "); DBG_MSG_VAR(req); DBG_MSG_VAR(TimeCurrent()); DBG_MSG_VAR(sym); ); bSetStpOrdBu = true; tSetStpOrdBu = D'3000.12.31'; tSetSL = D'3000.12.31'; tSetTP = D'3000.12.31'; EAStep++; tSetTPP = tC + 5*60; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(bSetStpOrdBu); DBG_MSG_VAR(tSetStpOrdBu); DBG_MSG_VAR(tSetSL); DBG_MSG_VAR(tSetTP); DBG_MSG_VAR(EAStep); DBG_MSG_VAR(tSetTPP); ); } } // while } //-- 6. change the SL & TP of the open position if ( true && DBG_MSG_EVAL(tC > tSetTPP) && DBG_MSG_EVAL(PositionsTotal() > 0) ) { int p=ArraySize(oPoSE); //## int p=PositionsTotal(); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(p); ); while(p-->0) { ulong tckt = PositionGetTicket(p); //Print("\n####################### CHG SL & TP open Pos (TRADE_ACTION_SLTP). \n",__LINE__," ",TimeToString(TimeCurrent(),TIME_SECONDS)); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG("####################### CHG SL & TP open Pos (TRADE_ACTION_SLTP)."); //## DBG_MSG_VAR(tckt); DBG_MSG_VAR(TimeCurrent()); ); tradeMoveTPSLPos(oPoSE[p], 400.0*_Point); //## tradeMoveTPSLPos(tckt, 400.0*_Point, 500.0*_Point); tSetTPP = D'3000.12.31'; DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(tSetTPP); ); } } //-- 7. remove the EA after all postiones were closed if ( DBG_MSG_EVAL(EAStep >= 3) && DBG_MSG_EVAL(OrdersTotal()+PositionsTotal() == 0)) { if (kill== 0) { kill = TimeCurrent() + 60; } // let the debugger print his journal // print the trade history into the journal if (kill < TimeCurrent() ) { // check that ReqCHCK is empty or print conent int i = ArraySize(ReqCHCK); Print("\n",_t2All(TimeCurrent())," Time to kill me..\nFirst check confirmation list, sz:",i); while(i-->0) { Print(__LINE__," ",__FUNCTION__," LIST ReqCHCK[",i,"] o:",ReqCHCK[i].deviation," m: ",ReqCHCK[i].magic," ",_e2s(ReqCHCK[i].action)," ",_e2s(ReqCHCK[i].type)); } // same for match Print("\nPrintout Match"); listOpMatch(FunLine,"Final Printout Matches"); // Print the deals Print("\nPrintout of Deals"); if( DBG_MSG_EVAL_CMNT("History selected", HistorySelect( D'2021.01.05 00:00', TimeCurrent())) ) { int dls = HistoryDealsTotal(); DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG_VAR(dls); ); while(dls-- > 0) { ulong id = HistoryDealGetTicket(dls); ulong mag = HistoryDealGetInteger(id,DEAL_MAGIC); //if ( HistoryDealGetInteger(id,DEAL_ORDER) == 0) continue; //int d = ArrayRange(Deal2Ord,0); //while(d-->0) { //ulong id = Deal2Ord[d][0]; HistoryDealSelect(id); ulong deal_pos_id = HistoryDealGetInteger(id, DEAL_POSITION_ID); ulong deal_magic = HistoryDealGetInteger(id, DEAL_MAGIC); ulong deal_order = HistoryDealGetInteger(id, DEAL_ORDER); if( DBG_MSG_EVAL_CMNT("History entry incomplete, skipping", (deal_pos_id + deal_magic + deal_order) == 0) ) { continue; } DBG_TRACE_EXPERT_MAIN_ONTICK( DBG_MSG(" !!! adding deal_magic to if-condition may result in error, because deals magic could be not zero but not related to thhis EA !!!!"); DBG_MSG(" !!! Instead I suggest using (deal_magic != [THIS-EAs-MAGIC]) !!!!"); DBG_MSG_VAR(deal_pos_id); DBG_MSG_VAR(deal_magic); DBG_MSG_VAR(deal_order); ); Print("D[",dls,"] ",id,"\t",_e2s((ENUM_DEAL_ENTRY)HistoryDealGetInteger(id,DEAL_ENTRY)) ,"\tm ",HistoryDealGetInteger(id,DEAL_MAGIC) ,"\to ",HistoryDealGetInteger(id,DEAL_ORDER) ,"\tp ",HistoryDealGetInteger(id,DEAL_POSITION_ID) ,"\tRes:",_e2s((ENUM_DEAL_REASON)HistoryDealGetInteger(id,DEAL_REASON)) ,"\tTyp:",_e2s((ENUM_DEAL_TYPE)HistoryDealGetInteger(id,DEAL_TYPE)) ,"\ttC: ",_t2All((datetime)HistoryDealGetInteger(id,DEAL_TIME)) ); //} } } //ArrayPrint(OPN); ExpertRemove(); } } // Return DBG_TRACE_EXPERT_MAIN_ONTICK_RETURN; }