// #define VIRTUAL_TESTER // Запуск в виртуальном торговом окружении // #define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания // #define VIRTUAL_CLOSEALL_BYEND // Закрывает принудительно все ордера в конце тестирования // #define VIRTUAL_ONTESTER_FORMULA ::AccountBalance() // Что возвращать в OnTester в режиме VIRTUAL_TESTER #include "Orders.mqh" #define __VIRTUAL__ #ifdef __MQL5__ #ifndef OP_BUY #define OP_BUY ORDER_TYPE_BUY #endif // OP_BUY #ifndef OP_SELL #define OP_SELL ORDER_TYPE_SELL #endif // OP_SELL #ifndef OP_BUYLIMIT #define OP_BUYLIMIT ORDER_TYPE_BUY_LIMIT #endif // OP_BUYLIMIT #ifndef OP_SELLLIMIT #define OP_SELLLIMIT ORDER_TYPE_SELL_LIMIT #endif // OP_SELLLIMIT #ifndef OP_BUYSTOP #define OP_BUYSTOP ORDER_TYPE_BUY_STOP #endif // OP_BUYSTOP #ifndef OP_SELLSTOP #define OP_SELLSTOP ORDER_TYPE_SELL_STOP #endif // OP_SELLSTOP #else // __MQL5__ #ifndef Bid #define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID) #endif // Bid #ifndef Ask #define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK) #endif // Ask #endif // __MQL5__ class VIRTUAL_DELETE { public: ~VIRTUAL_DELETE( void ) { VIRTUAL::DeleteAll(); } }; typedef void (*STRATEGY)( void ); int VirtualMemory( const int NewValue = 0, const int Value = 0, const bool SetFlag = false ) { static int PrevValue; if (SetFlag) PrevValue = Value; return(SetFlag ? NewValue : PrevValue); } template T VirtualMacrosFunc( const T Value ) { VIRTUAL::SelectByHandle(VirtualMemory()); return(Value); } #define _V(A, B) VirtualMacrosFunc(VIRTUAL::SelectByHandle(VirtualMemory((A), VIRTUAL::GetHandle(), true)) ? (B) : NULL) class VIRTUAL { private: static ORDERS* Orders[]; static ORDERS* SelectOrders; static int CountHandles; static const VIRTUAL_DELETE VirtualDelete; public: static int Create( const double dBalance = 0, datetime StartTime = 0, const bool bNetting = false ) { // static int CountHandles = 1; // Нельзя, т.к. будет инициализация после всех глобальных переменных. const int Pos = ::ArrayResize(VIRTUAL::Orders, VIRTUAL::Total() + 1) - 1; if (!StartTime) StartTime = ::MQLInfoInteger(MQL_TESTER) ? ::TimeCurrent() : (datetime)::SymbolInfoInteger(_Symbol, SYMBOL_TIME); if ((VIRTUAL::Orders[Pos] = new ORDERS(VIRTUAL::CountHandles, StartTime)) != NULL) { #ifdef VIRTUAL_TESTER MqlTick Tick = {0}; ::SymbolInfoTick(_Symbol, Tick); // Даже если получить тик не удалось. if (::MQLInfoInteger(MQL_TESTER)) // Без этого на реале можно нарваться на ситуацию, когда виртуальный тик имеет время больше реального. { Tick.time = ::TimeCurrent(); // Для получения корректного TimeCurrent() в OnInit и ранее. Tick.time_msc = (long)Tick.time * 1000; } VIRTUAL::Orders[Pos].NewTick(Tick); // Для полноценной работы в виртуале в OnInit и ранее. #endif // VIRTUAL_TESTER VIRTUAL::Orders[Pos].Set(dBalance, bNetting); VIRTUAL::CountHandles++; } return(VIRTUAL::Orders[Pos] ? VIRTUAL::Orders[Pos].Handle : -1); } static bool Delete( void ) { bool Res = (VIRTUAL::SelectOrders != NULL); if (Res) { const int Size = VIRTUAL::Total(); for (int i = 0; i < Size; i++) if (Res = (VIRTUAL::Orders[i] == VIRTUAL::SelectOrders)) { for (int j = i; j < Size - 1; j++) VIRTUAL::Orders[i] = VIRTUAL::Orders[i + 1]; ::ArrayResize(VIRTUAL::Orders, Size - 1); delete VIRTUAL::SelectOrders; VIRTUAL::SelectOrders = NULL; } } return(Res); } static void DeleteAll( void ) { for (int i = VIRTUAL::Total() - 1; i >= 0; i--) delete VIRTUAL::Orders[i]; return; } static void NewTick( const MqlTick &Tick ) { if (VIRTUAL::SelectOrders) VIRTUAL::SelectOrders.NewTick(Tick); return; } static void NewTick( const MqlTick &Ticks[], const STRATEGY Strategy = NULL ) { const int Size = ::ArraySize(Ticks); if (Strategy) for (int i = 0; (i < Size) && (!::IsStopped()); i++) { VIRTUAL::NewTick(Ticks[i]); Strategy(); //Comment(ToString(5)); } else for (int i = 0; i < Size; i++) VIRTUAL::NewTick(Ticks[i]); return; } static void NewTick( void ) { static MqlTick Tick = {0}; if (VIRTUAL::SelectOrders && ::SymbolInfoTick(_Symbol, Tick)) VIRTUAL::NewTick(Tick); return; } static int Total( void ) { return(::ArraySize(VIRTUAL::Orders)); } static int GetHandle( void ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.Handle : 0); } static bool IsNetting( void ) { static const bool RealNetting = #ifdef __MQL5__ !((ENUM_ACCOUNT_MARGIN_MODE)::AccountInfoInteger(ACCOUNT_MARGIN_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #else // __MQL5__ false #endif //__MQL5__ ; return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.IsNetting() : RealNetting); } static string ToString( const int LastHistoryOrders = 0, const bool Pending = true ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.ToString(LastHistoryOrders, Pending) : NULL); } static bool SelectByIndex( const int Index = 0 ) { const bool Res = (Index >= 0) && (Index <= VIRTUAL::Total()); if (Res) VIRTUAL::SelectOrders = Index ? VIRTUAL::Orders[Index - 1] : NULL; return(Res); } static bool SelectByHandle( const int Handle = 0 ) { bool Res = (Handle >= 0); if (Res && (Handle != VIRTUAL::GetHandle())) { if (Handle) { Res = false; const int Size = VIRTUAL::Total(); for (int i = 0; i < Size; i++) if (Res = (VIRTUAL::Orders[i].Handle == Handle)) { VIRTUAL::SelectOrders = VIRTUAL::Orders[i]; break; } } else VIRTUAL::SelectOrders = NULL; } return(Res); } static void Stop( void ) { if (VIRTUAL::SelectOrders) VIRTUAL::SelectOrders.Stop(); return; } static datetime VirtualTimeCurrent( void ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.TimeCurrent() : ::TimeCurrent()); } static datetime VirtualTimeCurrent( MqlDateTime &StructTime ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.TimeCurrent(StructTime) : ::TimeCurrent(StructTime)); } static bool VirtualSymbolInfoTick( const string Symb, MqlTick &Tick ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.SymbolInfoTick(Symb, Tick) : ::SymbolInfoTick(Symb, Tick)); } static double VirtualSymbolInfoDouble( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.SymbolInfoDouble(Symb, Property) : ::SymbolInfoDouble(Symb, Property)); } static bool VirtualSymbolInfoDouble( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property, double &Value ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.SymbolInfoDouble(Symb, Property, Value) : ::SymbolInfoDouble(Symb, Property, Value)); } static long VirtualSymbolInfoInteger( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.SymbolInfoInteger(Symb, Property) : ::SymbolInfoInteger(Symb, Property)); } static long VirtualSymbolInfoInteger( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property, long &Value ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.SymbolInfoInteger(Symb, Property, Value) : ::SymbolInfoInteger(Symb, Property, Value)); } static long VirtualAccountInfoInteger( const ENUM_ACCOUNT_INFO_INTEGER Property ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.AccountInfoInteger(Property) : ::AccountInfoInteger(Property)); } static double VirtualAccountInfoDouble( const ENUM_ACCOUNT_INFO_DOUBLE Property ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.AccountInfoDouble(Property) : ::AccountInfoDouble(Property)); } static double VirtualAccountBalance( void ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.AccountBalance() : ::AccountInfoDouble(ACCOUNT_BALANCE)); } static double VirtualAccountEquity( void ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.AccountEquity() : ::AccountInfoDouble(ACCOUNT_EQUITY)); } static double VirtualAccountProfit( void ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.AccountProfit() : ::AccountInfoDouble(ACCOUNT_PROFIT)); } static bool VirtualOrderSelect( const TICKET_TYPE Index, const int Select, const int Pool = MODE_TRADES ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrderSelect(Index, Select, Pool) : #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderSelect(Index, Select, Pool) #else // __MT4ORDERS__ false #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderSelect(Index, Select, Pool) #endif // __MQL5__ ); } static bool VirtualOrderClose( const TICKET_TYPE Ticket, const double dLots, const double Price, const int SlipPage, const color Arrow_Color = clrNONE ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrderClose(Ticket, dLots, Price) : #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderClose(Ticket, dLots, Price, SlipPage, Arrow_Color) #else // __MT4ORDERS__ false #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderClose(Ticket, dLots, Price, SlipPage, Arrow_Color) #endif // __MQL5__ ); } static bool VirtualOrderModify( const TICKET_TYPE Ticket, const double Price, const double SL, const double TP, const datetime Expiration, const color Arrow_Color = clrNONE ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrderModify(Ticket, Price, SL, TP, Expiration) : #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderModify(Ticket, Price, SL, TP, Expiration, Arrow_Color) #else // __MT4ORDERS__ false #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderModify(Ticket, Price, SL, TP, Expiration, Arrow_Color) #endif // __MQL5__ ); } static bool VirtualOrderCloseBy( const TICKET_TYPE Ticket, const TICKET_TYPE Opposite, const color Arrow_Color = clrNONE ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrderCloseBy(Ticket, Opposite) : #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderCloseBy(Ticket, Opposite, Arrow_Color) #else // __MT4ORDERS__ false #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderCloseBy(Ticket, Opposite, Arrow_Color) #endif // __MQL5__ ); } static bool VirtualOrderDelete( const TICKET_TYPE Ticket, const color Arrow_Color = clrNONE ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrderDelete(Ticket) : #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderDelete(Ticket, Arrow_Color) #else // __MT4ORDERS__ false #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderDelete(Ticket, Arrow_Color) #endif // __MQL5__ ); } static TICKET_TYPE VirtualOrderSend( const string Symb, const int Type, const double dVolume, const double Price, const int SlipPage, const double SL, const double TP, const string comment = NULL, const MAGIC_TYPE magic = 0, const datetime dExpiration = 0, color arrow_color = clrNONE ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrderSend(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration) : #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderSend(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration, arrow_color) #else // __MT4ORDERS__ false #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderSend(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration, arrow_color) #endif // __MQL5__ ); } static int VirtualOrdersTotal( void ) { return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.OrdersTotal2() : #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrdersTotal() #else // __MT4ORDERS__ false #endif // __MT4ORDERS__ #else // __MQL5__ ::OrdersTotal() #endif // __MQL5__ ); } static void VirtualOrderPrint( void ) { if (VIRTUAL::SelectOrders) VIRTUAL::SelectOrders.OrderPrint(); else #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderPrint(); #else // __MT4ORDERS__ ::Print(""); #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderPrint(); #endif // __MQL5__ return; } #define ORDERFUNCTION(NAME,T) \ static T VirtualOrder##NAME( void ) \ { \ return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.Order##NAME() : ORDERFUNCTION(sHistoryTotal, int) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrdersHistoryTotal() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrdersHistoryTotal() #endif // __MQL5__ ); } ORDERFUNCTION(Ticket, TICKET_TYPE) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderTicket() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderTicket() #endif // __MQL5__ ); } ORDERFUNCTION(Type, int) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderType() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderType() #endif // __MQL5__ ); } ORDERFUNCTION(Lots, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderLots() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderLots() #endif // __MQL5__ ); } ORDERFUNCTION(OpenPrice, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderOpenPrice() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderOpenPrice() #endif // __MQL5__ ); } ORDERFUNCTION(OpenTime, datetime) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderOpenTime() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderOpenTime() #endif // __MQL5__ ); } ORDERFUNCTION(StopLoss, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderStopLoss() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderStopLoss() #endif // __MQL5__ ); } ORDERFUNCTION(TakeProfit, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderTakeProfit() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderTakeProfit() #endif // __MQL5__ ); } ORDERFUNCTION(ClosePrice, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderClosePrice() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderClosePrice() #endif // __MQL5__ ); } ORDERFUNCTION(CloseTime, datetime) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderCloseTime() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderCloseTime() #endif // __MQL5__ ); } ORDERFUNCTION(Expiration, datetime) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderExpiration() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderExpiration() #endif // __MQL5__ ); } ORDERFUNCTION(MagicNumber, MAGIC_TYPE) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderMagicNumber() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderMagicNumber() #endif // __MQL5__ ); } ORDERFUNCTION(Profit, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderProfit() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderProfit() #endif // __MQL5__ ); } ORDERFUNCTION(Commission, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderCommission() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderCommission() #endif // __MQL5__ ); } ORDERFUNCTION(Swap, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderSwap() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderSwap() #endif // __MQL5__ ); } ORDERFUNCTION(Symbol, string) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderSymbol() #else // __MT4ORDERS__ NULL #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderSymbol() #endif // __MQL5__ ); } ORDERFUNCTION(Comment, string) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderComment() #else // __MT4ORDERS__ NULL #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderComment() #endif // __MQL5__ ); } ORDERFUNCTION(OpenTimeMsc, long) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderOpenTimeMsc() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ (long)::OrderOpenTime() * 1000 #endif // __MQL5__ ); } ORDERFUNCTION(CloseTimeMsc, long) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderCloseTimeMsc() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ (long)::OrderCloseTime() * 1000 #endif // __MQL5__ ); } ORDERFUNCTION(OpenPriceRequest, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderOpenPriceRequest() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderOpenPrice() #endif // __MQL5__ ); } ORDERFUNCTION(ClosePriceRequest, double) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderClosePriceRequest() #else // __MT4ORDERS__ 0 #endif // __MT4ORDERS__ #else // __MQL5__ ::OrderClosePrice() #endif // __MQL5__ ); } ORDERFUNCTION(OpenReason, ENUM_DEAL_REASON) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderOpenReason() #else // __MT4ORDERS__ DEAL_REASON_CLIENT #endif // __MT4ORDERS__ #else // __MQL5__ DEAL_REASON_CLIENT #endif // __MQL5__ ); } ORDERFUNCTION(CloseReason, ENUM_DEAL_REASON) #ifdef __MQL5__ #ifdef __MT4ORDERS__ ::OrderCloseReason() #else // __MT4ORDERS__ DEAL_REASON_CLIENT #endif // __MT4ORDERS__ #else // __MQL5__ DEAL_REASON_CLIENT #endif // __MQL5__ ); } #undef ORDERFUNCTION static int Tester( const MqlTick &Ticks[], const STRATEGY Strategy, const double Balance = 0, const bool Stop = true, const bool bNetting = false ) { const int Handle = VIRTUAL::GetHandle(); const bool Res = ::ArraySize(Ticks) && VIRTUAL::SelectByHandle(VIRTUAL::Create(Balance, Ticks[0].time - Ticks[0].time % (24 * 3600), bNetting)); if (Res) { VIRTUAL::NewTick(Ticks, Strategy); if (Stop) VIRTUAL::Stop(); } return(Res ? Handle : -1);; } }; ////+------------------------------------------------------------------+ ////| INFO: Подключенине DoEasy | ////+------------------------------------------------------------------+ //#define order am_order //#define list am_list //#include //#undef order //#undef list // ////+------------------------------------------------------------------+ static ORDERS* VIRTUAL::Orders[]; static ORDERS* VIRTUAL::SelectOrders = NULL; static int VIRTUAL::CountHandles = 1; static const VIRTUAL_DELETE VIRTUAL::VirtualDelete; #define AccountBalance VIRTUAL::VirtualAccountBalance #define AccountEquity VIRTUAL::VirtualAccountEquity #define AccountProfit VIRTUAL::VirtualAccountProfit #ifdef OrdersTotal #undef OrdersTotal #endif // OrdersTotal #define OrderSelect VIRTUAL::VirtualOrderSelect #define OrderClose VIRTUAL::VirtualOrderClose #define OrderModify VIRTUAL::VirtualOrderModify #define OrderCloseBy VIRTUAL::VirtualOrderCloseBy #define OrderDelete VIRTUAL::VirtualOrderDelete #define OrdersTotal VIRTUAL::VirtualOrdersTotal #define OrderSend VIRTUAL::VirtualOrderSend #define OrderPrint VIRTUAL::VirtualOrderPrint #define OrdersHistoryTotal VIRTUAL::VirtualOrdersHistoryTotal #define OrderTicket VIRTUAL::VirtualOrderTicket #define OrderType VIRTUAL::VirtualOrderType #define OrderLots VIRTUAL::VirtualOrderLots #define OrderOpenPrice VIRTUAL::VirtualOrderOpenPrice #define OrderOpenTime VIRTUAL::VirtualOrderOpenTime #define OrderStopLoss VIRTUAL::VirtualOrderStopLoss #define OrderTakeProfit VIRTUAL::VirtualOrderTakeProfit #define OrderClosePrice VIRTUAL::VirtualOrderClosePrice #define OrderCloseTime VIRTUAL::VirtualOrderCloseTime #define OrderExpiration VIRTUAL::VirtualOrderExpiration #define OrderMagicNumber VIRTUAL::VirtualOrderMagicNumber #define OrderProfit VIRTUAL::VirtualOrderProfit #define OrderCommission VIRTUAL::VirtualOrderCommission #define OrderSwap VIRTUAL::VirtualOrderSwap #define OrderSymbol VIRTUAL::VirtualOrderSymbol #define OrderComment VIRTUAL::VirtualOrderComment #define OrderOpenTimeMsc VIRTUAL::VirtualOrderOpenTimeMsc #define OrderCloseTimeMsc VIRTUAL::VirtualOrderCloseTimeMsc #define OrderOpenPriceRequest VIRTUAL::VirtualOrderOpenPriceRequest #define OrderClosePriceRequest VIRTUAL::VirtualOrderClosePriceRequest #define TimeCurrent VIRTUAL::VirtualTimeCurrent #define SymbolInfoTick VIRTUAL::VirtualSymbolInfoTick #define SymbolInfoInteger VIRTUAL::VirtualSymbolInfoInteger #define SymbolInfoDouble VIRTUAL::VirtualSymbolInfoDouble #define AccountInfoInteger VIRTUAL::VirtualAccountInfoInteger #define AccountInfoDouble VIRTUAL::VirtualAccountInfoDouble #ifdef VIRTUAL_TESTER #include "Sync.mqh" sinput bool VirtualTester = false; sinput bool ReverseDeals = false; const int VirtualHandle = VirtualTester ? VIRTUAL::Create() : 0; const int ReverseHandle = ReverseDeals ? VIRTUAL::Create() : 0; const bool VirtualInit = VIRTUAL::SelectByHandle(ReverseDeals ? ReverseHandle : VirtualHandle); void OnTick( void ) { VIRTUAL::NewTick(); if (ReverseHandle) { VIRTUAL::SelectByHandle(VirtualHandle); VIRTUAL::NewTick(); // Comment(VIRTUAL::ToString()); VIRTUAL::SelectByHandle(ReverseHandle); SYNC::Positions(VirtualHandle, true); } ::OldOnTick2(); if (ReverseHandle) SYNC::Positions(VirtualHandle, true); // Comment(VIRTUAL::ToString()); return; } #ifndef BESTINTERVAL_ONTESTER double OnTester() { VIRTUAL::SelectByHandle(VirtualHandle); #ifdef VIRTUAL_CLOSEALL_BYEND VIRTUAL::Stop(); #endif // VIRTUAL_CLOSEALL_BYEND #ifdef VIRTUAL_ONTESTER_FORMULA return(VIRTUAL_ONTESTER_FORMULA); #else // VIRTUAL_ONTESTER_FORMULA //return(::AccountEquity()); return ::OldOnTester2(); #endif // VIRTUAL_ONTESTER_FORMULA } #define OnTester OldOnTester2 #endif // BESTINTERVAL_ONTESTER #define OnTick OldOnTick2 // TesterBenchmark.mqh ? #endif // VIRTUAL_TESTER