EA-Setka-2/Libs/Virtual/Virtual.mqh
super.admin a4b861dd93 convert
2025-05-30 14:50:44 +02:00

890 lines
No EOL
50 KiB
MQL5

// #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 <typename T>
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 <Artmedia70\DoEasy\Engine.mqh>
//#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<ISTIME>(VirtualHandle, true);
}
::OldOnTick2();
if (ReverseHandle)
SYNC::Positions<ISTIME>(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