2663 lines
		
	
	
		
			No EOL
		
	
	
		
			174 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
			
		
		
	
	
			2663 lines
		
	
	
		
			No EOL
		
	
	
		
			174 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
// #define VIRTUAL_TESTER // Запуск в виртуальном торговом окружении
 | 
						|
// #define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания
 | 
						|
// #define VIRTUAL_CLOSEALL_BYEND // Закрывает принудительно все ордера в конце тестирования
 | 
						|
// #define VIRTUAL_ONTESTER_FORMULA ::AccountBalance() // Что возвращать в OnTester в режиме VIRTUAL_TESTER
 | 
						|
// #define VIRTUAL_SNAPSHOT_REFRESHTIME 1000 // Время жизни снепшота для обновления. В MT5 требует подключенной MT4Orders.mqh
 | 
						|
// #define VIRTUAL_SNAPSHOT_WITHOUT_HISTORY // Отказ от снепшота истории для повышения производительности
 | 
						|
// #define VIRTUAL_TESTER_FAST // Возможно, это ускорит советник в Тестере.
 | 
						|
// #define VIRTUAL_COUNTER // Счетчик.
 | 
						|
// #define VIRTUAL_ALTERNATIVE // Альтернативная скорость расчетов
 | 
						|
// #define VIRTUAL_NOCHECK_NULL // Не проверять (VIRTUAL::SelectOrders != NULL) - ускорение.
 | 
						|
// #define VIRTUAL_SELECTORDERS_OBJECT // Работа с выбраным окружением без указателей, отключает мультивалютку.
 | 
						|
// #define VIRTUAL_ORDERSELECT_WITHOUT_COPY // OrderSelect без копирования ORDER-структуры, отключает мультивалютку.
 | 
						|
 | 
						|
#ifndef __MQL5__
 | 
						|
  #ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
    #undef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
  #endif // #ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
#endif // #ifndef __MQL5__
 | 
						|
 | 
						|
#ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  #include "Snapshot.mqh"
 | 
						|
#endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
 | 
						|
#ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
  #include "Orders.mqh"
 | 
						|
 | 
						|
  #define VIRTUAL_SELECTORDERS_MACROS(A, B) B
 | 
						|
#else // #ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
  #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY
 | 
						|
    #include "Orders.mqh"
 | 
						|
  #else // #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY
 | 
						|
    #include "Multi_Orders.mqh"
 | 
						|
  #endif // #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY #else
 | 
						|
 | 
						|
  #define VIRTUAL_SELECTORDERS_MACROS(A, B) A
 | 
						|
#endif // #ifdef VIRTUAL_SELECTORDERS_OBJECT #else
 | 
						|
 | 
						|
#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
 | 
						|
 | 
						|
  #define VIRTUAL_POINTER VIRTUAL::POINTER
 | 
						|
#else // __MQL5__
 | 
						|
  #ifndef Bid
 | 
						|
    #define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
 | 
						|
  #endif // Bid
 | 
						|
 | 
						|
  #ifndef Ask
 | 
						|
    #define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
 | 
						|
  #endif // Ask
 | 
						|
 | 
						|
  // https://www.mql5.com/ru/forum/438060/page5#comment_44601847
 | 
						|
  #define private public
 | 
						|
  #define protected public
 | 
						|
 | 
						|
  #define VIRTUAL_POINTER POINTER
 | 
						|
#endif // __MQL5__
 | 
						|
 | 
						|
class VIRTUAL_DELETE
 | 
						|
{
 | 
						|
private:
 | 
						|
/*
 | 
						|
  static int VirtualMemory( const int NewValue = 0, const int Value = 0, const bool SetFlag = false )
 | 
						|
  {
 | 
						|
    static int PrevValue[100];
 | 
						|
    static int Pos = 0;
 | 
						|
 | 
						|
    if (SetFlag)
 | 
						|
      PrevValue[Pos++] = Value;
 | 
						|
 | 
						|
    return(SetFlag ? NewValue : PrevValue[--Pos]);
 | 
						|
  }
 | 
						|
*/
 | 
						|
public:
 | 
						|
  ~VIRTUAL_DELETE( void )
 | 
						|
  {
 | 
						|
    VIRTUAL::DeleteAll();
 | 
						|
 | 
						|
  #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
    VIRTUAL::SnapshotDelete();
 | 
						|
  #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  }
 | 
						|
/*
 | 
						|
  template <typename T>
 | 
						|
  static T VirtualMacrosFunc( const T Value )
 | 
						|
  {
 | 
						|
    VIRTUAL::SelectByHandle(VIRTUAL_DELETE::VirtualMemory());
 | 
						|
 | 
						|
    return(Value);
 | 
						|
  }
 | 
						|
*/
 | 
						|
  template <typename T>
 | 
						|
  static const T VirtualMacrosFunc2( const bool, const T /*&*/ Value, const bool )
 | 
						|
  {
 | 
						|
    return(Value);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// #define _V(A, B) VIRTUAL_DELETE::VirtualMacrosFunc(VIRTUAL::SelectByHandle(VIRTUAL_DELETE::VirtualMemory((A), VIRTUAL::GetHandle(), true)) ? (B) : NULL)
 | 
						|
 | 
						|
// Выбирает A(Handle)-окружение, выполняет B и возвращает предыдущее окружение.
 | 
						|
#define _V(A, B) VIRTUAL_DELETE::VirtualMacrosFunc2(VIRTUAL::SelectFromStack(), (B), VIRTUAL::ToStack() && VIRTUAL::SelectByHandle(A))
 | 
						|
 | 
						|
// Выбирает A(POINTER)-окружение, выполняет B и возвращает предыдущее окружение.
 | 
						|
#define _VP(A, B) VIRTUAL_DELETE::VirtualMacrosFunc2(VIRTUAL::SelectFromStack(), (B), VIRTUAL::ToStack() && (A).Select())
 | 
						|
 | 
						|
// Выбирает A(Index)-окружение, выполняет B и возвращает предыдущее окружение.
 | 
						|
#define _VI(A, B) VIRTUAL_DELETE::VirtualMacrosFunc2(VIRTUAL::SelectFromStack(), (B), VIRTUAL::ToStack() && VIRTUAL::SelectByIndex(A))
 | 
						|
 | 
						|
// Выбирает A(HANDLE_INDEX)-окружение, выполняет B и возвращает предыдущее окружение.
 | 
						|
#define _VI2(A, B) VIRTUAL_DELETE::VirtualMacrosFunc2(VIRTUAL::SelectFromStack(), (B), VIRTUAL::ToStack() && VIRTUAL::SelectByIndex((A).Index, (A).Handle))
 | 
						|
 | 
						|
#define TEMPNAME(A) TmpVS##A
 | 
						|
 | 
						|
#define _VS(A)                         \
 | 
						|
  class VS                             \
 | 
						|
  {                                    \
 | 
						|
  public:                              \
 | 
						|
    VS( const int Handle )             \
 | 
						|
    {                                  \
 | 
						|
      VIRTUAL::ToStack();              \
 | 
						|
                                       \
 | 
						|
      VIRTUAL::SelectByHandle(Handle); \
 | 
						|
    }                                  \
 | 
						|
                                       \
 | 
						|
    ~VS( void )                        \
 | 
						|
    {                                  \
 | 
						|
      VIRTUAL::SelectFromStack();      \
 | 
						|
    }                                  \
 | 
						|
  } TEMPNAME(__LINE__)(A);
 | 
						|
 | 
						|
#define _VSP(A)                            \
 | 
						|
  class VSP                                \
 | 
						|
  {                                        \
 | 
						|
  public:                                  \
 | 
						|
    VSP( const VIRTUAL_POINTER &Pointer )  \
 | 
						|
    {                                      \
 | 
						|
      VIRTUAL::ToStack();                  \
 | 
						|
                                           \
 | 
						|
      Pointer.Select();                    \
 | 
						|
    }                                      \
 | 
						|
                                           \
 | 
						|
    ~VSP( void )                           \
 | 
						|
    {                                      \
 | 
						|
      VIRTUAL::SelectFromStack();          \
 | 
						|
    }                                      \
 | 
						|
  } TEMPNAME(__LINE__)(A);
 | 
						|
 | 
						|
#define _VSI(A)                      \
 | 
						|
  class VSI                          \
 | 
						|
  {                                  \
 | 
						|
  public:                            \
 | 
						|
    VSI( const int Index )           \
 | 
						|
    {                                \
 | 
						|
      VIRTUAL::ToStack();            \
 | 
						|
                                     \
 | 
						|
      VIRTUAL::SelectByIndex(Index); \
 | 
						|
    }                                \
 | 
						|
                                     \
 | 
						|
    ~VSI( void )                     \
 | 
						|
    {                                \
 | 
						|
      VIRTUAL::SelectFromStack();    \
 | 
						|
    }                                \
 | 
						|
  } TEMPNAME(__LINE__)(A);
 | 
						|
 | 
						|
#define _VSI2(A)                                  \
 | 
						|
  class VSI2                                      \
 | 
						|
  {                                               \
 | 
						|
  public:                                         \
 | 
						|
    VSI2( VIRTUAL::HANDLE_INDEX &HandleIndex )    \
 | 
						|
    {                                             \
 | 
						|
      VIRTUAL::ToStack();                         \
 | 
						|
                                                  \
 | 
						|
      VIRTUAL::SelectByIndex(HandleIndex.Index,   \
 | 
						|
                             HandleIndex.Handle); \
 | 
						|
                 }                                \
 | 
						|
                                                  \
 | 
						|
    ~VSI2( void )                                 \
 | 
						|
    {                                             \
 | 
						|
      VIRTUAL::SelectFromStack();                 \
 | 
						|
    }                                             \
 | 
						|
  } TEMPNAME(__LINE__)(A);
 | 
						|
 | 
						|
// #undef TEMPNAME // Нельзя расскомментировать!!!
 | 
						|
 | 
						|
class TICKS_ARRAY
 | 
						|
{
 | 
						|
public:
 | 
						|
  MqlTick Ticks[];
 | 
						|
};
 | 
						|
 | 
						|
class VIRTUAL
 | 
						|
{
 | 
						|
private:
 | 
						|
  static const VIRTUAL_DELETE VirtualDelete;
 | 
						|
  static ORDERS* Orders[];
 | 
						|
  static int CountHandles;
 | 
						|
 | 
						|
  static ORDERS* StackOrders[100];
 | 
						|
  static int StackPos;
 | 
						|
 | 
						|
#ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  static SNAPSHOT* SnapshotPtr;
 | 
						|
  static SNAPSHOT* SnapshotPtrBackup;
 | 
						|
#endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
 | 
						|
  static ORDERS* GetMyPointer( ORDERS* Ptr )
 | 
						|
  {
 | 
						|
    return(VIRTUAL_SELECTORDERS_MACROS(Ptr, (VIRTUAL::SelectOrders.MyPointer == Ptr)
 | 
						|
                                              ? &VIRTUAL::SelectOrders
 | 
						|
                                              : Ptr));
 | 
						|
  }
 | 
						|
 | 
						|
protected:
 | 
						|
  static ORDERS VIRTUAL_SELECTORDERS_MACROS(*SelectOrders, SelectOrders);
 | 
						|
 | 
						|
  static bool IsVirtual( void )
 | 
						|
  {
 | 
						|
  #ifdef __MQL5__
 | 
						|
    #ifdef __MT4ORDERS__
 | 
						|
      return((bool)(VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)));
 | 
						|
    #else // #ifdef __MT4ORDERS__
 | 
						|
      #ifdef VIRTUAL_NOCHECK_NULL
 | 
						|
        return(true);
 | 
						|
      #else // #ifdef VIRTUAL_NOCHECK_NULL
 | 
						|
        return((bool)(VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)));
 | 
						|
      #endif // #ifdef VIRTUAL_NOCHECK_NULL #else
 | 
						|
    #endif // #ifdef __MT4ORDERS__ #else
 | 
						|
  #else // #ifdef __MQL5__
 | 
						|
    return((bool)(VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)));
 | 
						|
  #endif // #ifdef __MQL5__ #else
 | 
						|
  }
 | 
						|
 | 
						|
public:
 | 
						|
  // DBL_MIN - тип Неттинга и размер баланса берутся с текущего счета.
 | 
						|
  static int Create( const double dBalance = DBL_MIN, 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);
 | 
						|
 | 
						|
    const bool FlagRes = ((VIRTUAL::Orders[Pos] = new ORDERS(VIRTUAL::CountHandles, StartTime)) != NULL);
 | 
						|
 | 
						|
    if (FlagRes)
 | 
						|
    {
 | 
						|
    #ifdef VIRTUAL_TESTER
 | 
						|
      MqlTick Tick = {};
 | 
						|
 | 
						|
      ::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++;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      ::ArrayResize(VIRTUAL::Orders, Pos);
 | 
						|
 | 
						|
    return(FlagRes ? VIRTUAL::Orders[Pos].Handle : -1);
 | 
						|
  }
 | 
						|
 | 
						|
  static int Create( const string FileName, const bool FileCommon = false )
 | 
						|
  {
 | 
						|
    const int Pos = ::ArrayResize(VIRTUAL::Orders, VIRTUAL::Total() + 1) - 1;
 | 
						|
 | 
						|
    const bool FlagRes = ((VIRTUAL::Orders[Pos] = new ORDERS(VIRTUAL::CountHandles)) != NULL) &&
 | 
						|
                         VIRTUAL::Orders[Pos].Load(FileName, FileCommon);
 | 
						|
 | 
						|
    if (!FlagRes)
 | 
						|
    {
 | 
						|
      if (VIRTUAL::Orders[Pos] != NULL)
 | 
						|
        delete VIRTUAL::Orders[Pos];
 | 
						|
 | 
						|
      ::ArrayResize(VIRTUAL::Orders, Pos);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      VIRTUAL::CountHandles++;
 | 
						|
 | 
						|
    return(FlagRes ? VIRTUAL::Orders[Pos].Handle : -1);
 | 
						|
  }
 | 
						|
 | 
						|
  // DBL_MIN - тип Неттинга и размер баланса берутся с текущего счета.
 | 
						|
  static int CreateMulti( const SYMBOL_BASE &sSymbols[], const double dBalance = DBL_MIN,
 | 
						|
                          datetime StartTime = 0, const bool bNetting = false )
 | 
						|
  {
 | 
						|
//    static int CountHandles = 1; // Нельзя, т.к. будет инициализация после всех глобальных переменных.
 | 
						|
 | 
						|
    const int Size = ::ArraySize(sSymbols);
 | 
						|
    int Res = -1;
 | 
						|
 | 
						|
    if (Size)
 | 
						|
    {
 | 
						|
      const int Pos = ::ArrayResize(VIRTUAL::Orders, VIRTUAL::Total() + 1) - 1;
 | 
						|
 | 
						|
      if (!StartTime)
 | 
						|
        StartTime = ::TimeCurrent();
 | 
						|
 | 
						|
      if ((VIRTUAL::Orders[Pos] = (Size > 1) ?
 | 
						|
                                             #ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
                                               NULL
 | 
						|
                                             #else // #ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
                                               #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY
 | 
						|
                                                 NULL
 | 
						|
                                               #else // #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY
 | 
						|
                                                 new MULTI_ORDERS(VIRTUAL::CountHandles, StartTime, sSymbols)
 | 
						|
                                               #endif // #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY #else
 | 
						|
                                             #endif // #ifdef VIRTUAL_SELECTORDERS_OBJECT #else
 | 
						|
                                             : new ORDERS(VIRTUAL::CountHandles, StartTime, sSymbols[0])) != NULL)
 | 
						|
      {
 | 
						|
        VIRTUAL::Orders[Pos].Set(dBalance, bNetting);
 | 
						|
 | 
						|
        VIRTUAL::CountHandles++;
 | 
						|
 | 
						|
        Res = VIRTUAL::Orders[Pos].Handle;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        ::ArrayResize(VIRTUAL::Orders, Pos);
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static int CreateMulti( const string &sSymbols[], const double dBalance = DBL_MIN,
 | 
						|
                          datetime StartTime = 0, const bool bNetting = false )
 | 
						|
  {
 | 
						|
//    static int CountHandles = 1; // Нельзя, т.к. будет инициализация после всех глобальных переменных.
 | 
						|
 | 
						|
    SYMBOL_BASE sSymbols2[];
 | 
						|
 | 
						|
    for (uint i = ::ArrayResize(sSymbols2, ::ArraySize(sSymbols)); (bool)i--;)
 | 
						|
      sSymbols2[i] = sSymbols[i];
 | 
						|
 | 
						|
    return(VIRTUAL::CreateMulti(sSymbols2, dBalance, StartTime, bNetting));
 | 
						|
  }
 | 
						|
 | 
						|
  static int CreateSingle( const SYMBOL_BASE &sSymbol, const double dBalance = DBL_MIN,
 | 
						|
                           datetime StartTime = 0, const bool bNetting = false )
 | 
						|
  {
 | 
						|
//    const SYMBOL_BASE sSymbols[] = {sSymbol}; // https://www.mql5.com/ru/forum/462835/page27#comment_52788664
 | 
						|
    SYMBOL_BASE sSymbols[1];
 | 
						|
    sSymbols[0] = sSymbol;
 | 
						|
 | 
						|
    return(VIRTUAL::CreateMulti(sSymbols, dBalance, StartTime, bNetting));
 | 
						|
  }
 | 
						|
 | 
						|
  static int CreateSingle( const string sSymbol = NULL, const double dBalance = DBL_MIN,
 | 
						|
                           datetime StartTime = 0, const bool bNetting = false )
 | 
						|
  {
 | 
						|
//    const SYMBOL_BASE sSymbols[] = {sSymbol}; // https://www.mql5.com/ru/forum/462835/page27#comment_52788664
 | 
						|
    // const SYMBOL_BASE sSymbol2 = sSymbol; // https://www.mql5.com/ru/forum/492248/page3#comment_57718727
 | 
						|
    SYMBOL_BASE sSymbol2; sSymbol2 = sSymbol;
 | 
						|
 | 
						|
    return(VIRTUAL::CreateSingle(sSymbol2, dBalance, StartTime, bNetting));
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef __TYPETOBYTES__
 | 
						|
  template <typename T>
 | 
						|
  static int Create( const T &Array[] )
 | 
						|
  {
 | 
						|
    const int Pos = ::ArrayResize(VIRTUAL::Orders, VIRTUAL::Total() + 1) - 1;
 | 
						|
 | 
						|
    const bool FlagRes = ((VIRTUAL::Orders[Pos] = new ORDERS(VIRTUAL::CountHandles)) != NULL) &&
 | 
						|
                         VIRTUAL::Orders[Pos].Load(Array);
 | 
						|
 | 
						|
    if (!FlagRes)
 | 
						|
    {
 | 
						|
      if (VIRTUAL::Orders[Pos] != NULL)
 | 
						|
        delete VIRTUAL::Orders[Pos];
 | 
						|
 | 
						|
      ::ArrayResize(VIRTUAL::Orders, Pos);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      VIRTUAL::CountHandles++;
 | 
						|
 | 
						|
    return(FlagRes ? VIRTUAL::Orders[Pos].Handle : -1);
 | 
						|
  }
 | 
						|
#endif // #ifdef __TYPETOBYTES__
 | 
						|
 | 
						|
  static bool CopyTo( const int Handle )
 | 
						|
  {
 | 
						|
    bool Res = false;
 | 
						|
    ORDERS* const PrevOrders = VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders, VIRTUAL::SelectOrders.MyPointer);
 | 
						|
 | 
						|
    if ((PrevOrders != NULL) && !(Res = (Handle == PrevOrders.Handle)) && VIRTUAL::SelectByHandle(Handle))
 | 
						|
    {
 | 
						|
      Res = VIRTUAL::SelectOrders.CopyFrom(PrevOrders);
 | 
						|
 | 
						|
      VIRTUAL::SelectOrders = PrevOrders;
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool AddTo( const int Handle )
 | 
						|
  {
 | 
						|
    ORDERS* const PrevOrders = VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders, (VIRTUAL::SelectOrders.Handle == Handle)
 | 
						|
                                                                                    ? &VIRTUAL::SelectOrders
 | 
						|
                                                                                    : VIRTUAL::SelectOrders.MyPointer);
 | 
						|
    const bool Res = (PrevOrders != NULL) && Handle && VIRTUAL::SelectByHandle(Handle); // https://www.mql5.com/ru/forum/438066/page27#comment_45059555
 | 
						|
 | 
						|
    if (Res)
 | 
						|
    {
 | 
						|
      VIRTUAL::SelectOrders += PrevOrders;
 | 
						|
 | 
						|
      VIRTUAL::SelectOrders = PrevOrders;
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static int Summary( const string ID = NULL )
 | 
						|
  {
 | 
						|
    const int Size = VIRTUAL::Total();
 | 
						|
    const int Handle = Size ? VIRTUAL::Create() : -1;
 | 
						|
 | 
						|
    if ((Handle != -1) && VIRTUAL::Orders[Size].CopyFrom(VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::Orders[0], VIRTUAL::GetMyPointer(VIRTUAL::Orders[0]))) && (Size > 1))
 | 
						|
    {
 | 
						|
      for (int i = 1; i < Size; i++)
 | 
						|
        VIRTUAL::Orders[Size] += VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::Orders[i], VIRTUAL::GetMyPointer(VIRTUAL::Orders[i]));
 | 
						|
 | 
						|
      VIRTUAL::Orders[Size].SetID(ID);
 | 
						|
    }
 | 
						|
 | 
						|
    return(Handle);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool Delete( void )
 | 
						|
  {
 | 
						|
    bool Res = (VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle));
 | 
						|
 | 
						|
    if (Res)
 | 
						|
    {
 | 
						|
      const int Size = VIRTUAL::Total();
 | 
						|
 | 
						|
      for (int i = 0; i < Size; i++)
 | 
						|
        if (Res = (VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::Orders[i] == VIRTUAL::SelectOrders,
 | 
						|
                                               VIRTUAL::Orders[i].Handle == VIRTUAL::SelectOrders.Handle)))
 | 
						|
        {
 | 
						|
          delete VIRTUAL::Orders[i];
 | 
						|
 | 
						|
          for (int j = i; j < Size - 1; j++)
 | 
						|
            VIRTUAL::Orders[j] = VIRTUAL::Orders[j + 1]; // ArrayCopy, ArrayRemove?
 | 
						|
 | 
						|
          ::ArrayResize(VIRTUAL::Orders, Size - 1);
 | 
						|
 | 
						|
          VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders = NULL, VIRTUAL::SelectOrders.ToNull());
 | 
						|
 | 
						|
          break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static void DeleteAll( void )
 | 
						|
  {
 | 
						|
    for (int i = VIRTUAL::Total() - 1; i >= 0; i--)
 | 
						|
      delete VIRTUAL::Orders[i];
 | 
						|
 | 
						|
    ::ArrayFree(VIRTUAL::Orders);
 | 
						|
    VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders = NULL, VIRTUAL::SelectOrders.ToNull());
 | 
						|
 | 
						|
    VIRTUAL::CountHandles = 1;
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  // По какой-то причине нельзя вызывать эту функцию на глобальном уровне (вне On-функций) - не срабатывает.
 | 
						|
  // Symb = "" - все символы.
 | 
						|
  static ulong Snapshot( const uint RefreshTime = VIRTUAL_SNAPSHOT_REFRESHTIME, const MAGIC_TYPE Magic = -1,
 | 
						|
                         const bool HistoryInit = false, const string Symb = NULL, const bool CloseBy = true )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::SnapshotPtr == NULL)
 | 
						|
    {
 | 
						|
      if (VIRTUAL::SnapshotPtrBackup == NULL)
 | 
						|
        VIRTUAL::SnapshotPtrBackup = VIRTUAL::SnapshotPtr = new SNAPSHOT;
 | 
						|
      else
 | 
						|
        VIRTUAL::SnapshotPtr = VIRTUAL::SnapshotPtrBackup;
 | 
						|
    }
 | 
						|
 | 
						|
    return(VIRTUAL::SnapshotPtr.Snapshot(RefreshTime, Magic, HistoryInit, Symb, CloseBy));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool SnapshotIsActive( void )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::SnapshotPtr != NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  static ulong SnapshotLifeTime( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.SnapshotLifeTime() : ULONG_MAX);
 | 
						|
  }
 | 
						|
 | 
						|
  static void SnapshotDelete( const bool Full = true )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::SnapshotPtr != NULL)
 | 
						|
    {
 | 
						|
      if (Full)
 | 
						|
      {
 | 
						|
        delete VIRTUAL::SnapshotPtr;
 | 
						|
 | 
						|
        VIRTUAL::SnapshotPtrBackup = NULL;
 | 
						|
      }
 | 
						|
 | 
						|
      VIRTUAL::SnapshotPtr = NULL;
 | 
						|
    }
 | 
						|
    else if (Full && (VIRTUAL::SnapshotPtrBackup != NULL))
 | 
						|
    {
 | 
						|
      delete VIRTUAL::SnapshotPtrBackup;
 | 
						|
 | 
						|
      VIRTUAL::SnapshotPtrBackup = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static bool SnapshotHistory( const MAGIC_TYPE Magic = -1,
 | 
						|
                               const bool HistoryInit = false, const string Symb = NULL,
 | 
						|
                               const bool CloseBy = true, const datetime From = 0 )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SnapshotPtr != NULL) && VIRTUAL::SnapshotPtr.SnapshotHistory(Magic, HistoryInit, Symb, CloseBy, From));
 | 
						|
  }
 | 
						|
#else // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  static ulong Snapshot( const uint RefreshTime = 0, const MAGIC_TYPE Magic = -1,
 | 
						|
                         const bool HistoryInit = false, const string Symb = NULL, const bool CloseBy = true )
 | 
						|
  {
 | 
						|
    return(1); // 1 - для использования в bool-выражении.
 | 
						|
  }
 | 
						|
 | 
						|
  static bool SnapshotIsActive( void )
 | 
						|
  {
 | 
						|
    return(false);
 | 
						|
  }
 | 
						|
 | 
						|
  static ulong SnapshotLifeTime( void )
 | 
						|
  {
 | 
						|
    return(ULONG_MAX);
 | 
						|
  }
 | 
						|
 | 
						|
  static void SnapshotDelete( const bool Full = true )
 | 
						|
  {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static bool SnapshotHistory( const MAGIC_TYPE Magic = -1,
 | 
						|
                               const bool HistoryInit = false, const string Symb = NULL,
 | 
						|
                               const bool CloseBy = true, const datetime From = 0 )
 | 
						|
  {
 | 
						|
    return(false);
 | 
						|
  }
 | 
						|
#endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME #else
 | 
						|
 | 
						|
  static void NewTick( const MqlTick &Tick, const STRATEGY Strategy )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
    {
 | 
						|
      VIRTUAL::SelectOrders.NewTick(Tick);
 | 
						|
 | 
						|
      if (Strategy != NULL)
 | 
						|
        Strategy();
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTick( const MqlTick &Tick)
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
      VIRTUAL::SelectOrders.NewTick(Tick);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTick( const MqlTick &Ticks[], const STRATEGY Strategy = NULL )
 | 
						|
  {
 | 
						|
    // https://www.mql5.com/ru/forum/462835/page24#comment_52770433
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
    {
 | 
						|
/*
 | 
						|
      const int Size = ::ArraySize(Ticks);
 | 
						|
 | 
						|
      if (Strategy != NULL)
 | 
						|
        for (int i = 0; (i < Size)  && (!::IsStopped()); i++)
 | 
						|
        {
 | 
						|
          VIRTUAL::SelectOrders.NewTick(Ticks[i]);
 | 
						|
 | 
						|
          Strategy();
 | 
						|
        }
 | 
						|
      else
 | 
						|
        for (int i = 0; i < Size; i++)
 | 
						|
          VIRTUAL::SelectOrders.NewTick(Ticks[i]);
 | 
						|
*/
 | 
						|
      //
 | 
						|
 | 
						|
      VIRTUAL::SelectOrders.NewTick(Ticks, Strategy);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTick_NoCheck( void )
 | 
						|
  {
 | 
						|
    VIRTUAL::SelectOrders.MultiTick();
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTick_NoCheck( const MqlTick &Tick )
 | 
						|
  {
 | 
						|
    VIRTUAL::SelectOrders.NewTick(Tick);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTick( const STRATEGY Strategy = NULL )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    static MqlTick Tick = {};
 | 
						|
 | 
						|
    if ((VIRTUAL::IsVirtual()) && ::SymbolInfoTick(_Symbol, Tick))
 | 
						|
      VIRTUAL::NewTick(Tick, Strategy);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void MultiTick( const MqlTick &Ticks[] )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
      VIRTUAL::SelectOrders.MultiTick(Ticks);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void MultiTick( void )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
      VIRTUAL::SelectOrders.MultiTick();
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void MultiTick( const uint &Index, const MqlTick &Tick )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
      VIRTUAL::SelectOrders.MultiTick(Index, Tick);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void MultiTick( const uint &Index )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
      VIRTUAL::SelectOrders.MultiTick(Index);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void MultiTick_NoCheck( const uint &Index )
 | 
						|
  {
 | 
						|
    VIRTUAL::SelectOrders.MultiTick(Index);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTickMulti( const MqlTick &Ticks[], const STRATEGY_MULTI StrategyMulti = NULL )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
      VIRTUAL::SelectOrders.NewTickMulti(Ticks, StrategyMulti);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTickMulti( const TICKS_ARRAY &Ticks, const STRATEGY_MULTI StrategyMulti = NULL )
 | 
						|
  {
 | 
						|
    VIRTUAL::NewTickMulti(Ticks.Ticks, StrategyMulti);
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static void NewTickMulti( const TICKS_ARRAY &TicksArray[], const STRATEGY_MULTI StrategyMulti = NULL )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::IsVirtual())
 | 
						|
    {
 | 
						|
      if (!VIRTUAL::SelectOrders.IsSingle())
 | 
						|
      {
 | 
						|
        string Symbols[];
 | 
						|
        const int Amount = ::MathMin(::ArraySize(TicksArray), VIRTUAL::SelectOrders.GetSymbols(Symbols));
 | 
						|
 | 
						|
        int Count = 0;
 | 
						|
 | 
						|
        int Size[];
 | 
						|
        bool Res[];
 | 
						|
        int Pos[];
 | 
						|
 | 
						|
        ::ArrayResize(Pos, Amount);
 | 
						|
        ::ArrayInitialize(Pos, 0);
 | 
						|
 | 
						|
        for (uint i = ::ArrayResize(Res, ::ArrayResize(Size, Amount)); (bool)i--;)
 | 
						|
        {
 | 
						|
          Size[i] = ::ArraySize(TicksArray[i].Ticks);
 | 
						|
 | 
						|
          if (Res[i] = Size[i])
 | 
						|
            Count++;
 | 
						|
        }
 | 
						|
 | 
						|
        if (Count == 1)
 | 
						|
        {
 | 
						|
          const uint Index = ::ArrayMaximum(Size);
 | 
						|
          const int SizeSingle = Size[Index];
 | 
						|
 | 
						|
          if (StrategyMulti != NULL)
 | 
						|
          {
 | 
						|
            const string Symb = Symbols[Index];
 | 
						|
 | 
						|
            for (int i = 0; i < SizeSingle; i++)
 | 
						|
            {
 | 
						|
              VIRTUAL::SelectOrders.MultiTick(Index, TicksArray[Index].Ticks[i]);
 | 
						|
 | 
						|
              StrategyMulti(Symb, Index);
 | 
						|
            }
 | 
						|
          }
 | 
						|
          else
 | 
						|
            for (int i = 0; i < SizeSingle; i++)
 | 
						|
              VIRTUAL::SelectOrders.MultiTick(Index, TicksArray[Index].Ticks[i]);
 | 
						|
        }
 | 
						|
        else if (StrategyMulti != NULL)
 | 
						|
          while (Count)
 | 
						|
          {
 | 
						|
            MqlTick MinTick = {0, 0, 0, 0, 0, LONG_MAX};
 | 
						|
            uint Index = -1;
 | 
						|
 | 
						|
            // https://www.mql5.com/ru/forum/170952/page247#comment_52774236
 | 
						|
            for (uint i = Amount; (bool)i--;)
 | 
						|
              if (Res[i])
 | 
						|
              {
 | 
						|
                // Количество вызовов в ~(1+Amount)/2 раз больше общего числа элементов.
 | 
						|
                const MqlTick Tick = TicksArray[i].Ticks[Pos[i]];
 | 
						|
 | 
						|
                if (Tick.time_msc < MinTick.time_msc)
 | 
						|
                {
 | 
						|
                  MinTick = Tick;
 | 
						|
 | 
						|
                  Index = i;
 | 
						|
                }
 | 
						|
              }
 | 
						|
 | 
						|
            if (!(Res[Index] = (++Pos[Index] != Size[Index])))
 | 
						|
              Count--;
 | 
						|
 | 
						|
            VIRTUAL::SelectOrders.MultiTick(Index, MinTick);
 | 
						|
            StrategyMulti(Symbols[Index], Index);
 | 
						|
          }
 | 
						|
        else
 | 
						|
          while (Count)
 | 
						|
          {
 | 
						|
            MqlTick MinTick = {0, 0, 0, 0, 0, LONG_MAX};
 | 
						|
            uint Index = -1;
 | 
						|
 | 
						|
            // https://www.mql5.com/ru/forum/170952/page247#comment_52774236
 | 
						|
            for (uint i = Amount; (bool)i--;)
 | 
						|
              if (Res[i])
 | 
						|
              {
 | 
						|
                // Количество вызовов в ~(1+Amount)/2 раз больше общего числа элементов.
 | 
						|
                const MqlTick Tick = TicksArray[i].Ticks[Pos[i]];
 | 
						|
 | 
						|
                if (Tick.time_msc < MinTick.time_msc)
 | 
						|
                {
 | 
						|
                  MinTick = Tick;
 | 
						|
 | 
						|
                  Index = i;
 | 
						|
                }
 | 
						|
              }
 | 
						|
 | 
						|
            if (!(Res[Index] = (++Pos[Index] != Size[Index])))
 | 
						|
              Count--;
 | 
						|
 | 
						|
            VIRTUAL::SelectOrders.MultiTick(Index, MinTick);
 | 
						|
          }
 | 
						|
      }
 | 
						|
      else if (::ArraySize(TicksArray))
 | 
						|
        VIRTUAL::SelectOrders.NewTickMulti(TicksArray[0].Ticks, StrategyMulti);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  static int GetAmountSymbols( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.GetAmountSymbols() : 1);
 | 
						|
  }
 | 
						|
 | 
						|
  static int GetSymbols( string &Symbols[] )
 | 
						|
  {
 | 
						|
    int Res;
 | 
						|
 | 
						|
    if (VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle))
 | 
						|
      Res = VIRTUAL::SelectOrders.GetSymbols(Symbols);
 | 
						|
    else
 | 
						|
    {
 | 
						|
      Res = ::ArrayResize(Symbols, 1);
 | 
						|
 | 
						|
      Symbols[0] = _Symbol;
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static string GetSymbolByIndex( const int Index )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.GetSymbolByIndex(Index)
 | 
						|
                                           : (!Index ? _Symbol : NULL));
 | 
						|
  }
 | 
						|
 | 
						|
  static int Total( void )
 | 
						|
  {
 | 
						|
    return(::ArraySize(VIRTUAL::Orders));
 | 
						|
  }
 | 
						|
 | 
						|
  static int GetHandle( void )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL_SELECTORDERS_MACROS((VIRTUAL::SelectOrders != NULL) ? VIRTUAL::SelectOrders.Handle : 0,
 | 
						|
                                       VIRTUAL::SelectOrders.Handle));
 | 
						|
  }
 | 
						|
 | 
						|
  static int GetHandleByIndex( const int Index )
 | 
						|
  {
 | 
						|
    return((Index >= 0) && (Index <= VIRTUAL::Total()) ? (Index ? VIRTUAL::Orders[Index - 1].Handle : 0) : -1);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool IsExist( const int Handle )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::GetNumber(Handle) > 0);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool GetCurrentTick( MqlTick &Tick )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.SymbolInfoTick(_Symbol, Tick) : ::SymbolInfoTick(_Symbol, Tick));
 | 
						|
  }
 | 
						|
 | 
						|
  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_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.IsNetting() : RealNetting);
 | 
						|
  }
 | 
						|
 | 
						|
  static string ToString( const int LastHistoryOrders = 0, const bool Pending = true )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.ToString(LastHistoryOrders, Pending) : NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  // Вывод статистики.
 | 
						|
  static string StatToString( const int Amount = 1 )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.StatToString(Amount) : NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  static int GetNumber( const int Handle )
 | 
						|
  {
 | 
						|
    int Res = Handle ? -1 : 0;
 | 
						|
 | 
						|
    if (Handle)
 | 
						|
      for (int i = VIRTUAL::Total() - 1; i >= 0; i--)
 | 
						|
        if (VIRTUAL::Orders[i].Handle == Handle)
 | 
						|
        {
 | 
						|
          Res = i + 1;
 | 
						|
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  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 SelectByIndex( int &Index, const int Handle )
 | 
						|
  {
 | 
						|
    bool Res = (VIRTUAL::GetHandleByIndex(Index) == Handle) && VIRTUAL::SelectByIndex(Index);
 | 
						|
 | 
						|
    if (!Res)
 | 
						|
      Index = (Res = VIRTUAL::SelectByHandle(Handle)) ? VIRTUAL::GetNumber(Handle) : -1;
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool SelectByHandle( const int Handle = 0 )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    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 bool Stop( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.Stop());
 | 
						|
  }
 | 
						|
 | 
						|
  static bool IsHistoryChanged( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.IsHistoryChanged());
 | 
						|
  }
 | 
						|
 | 
						|
  // https://www.mql5.com/ru/forum/282062/page72#comment_56065971
 | 
						|
  static bool IsChanged( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(== NULL, .Handle == 0)) || VIRTUAL::SelectOrders.GetFlagChange());
 | 
						|
  }
 | 
						|
 | 
						|
  // С какого времени считать TesterStatistics.
 | 
						|
  static bool InitStat( const long StartTime )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.InitStat(StartTime) : false);
 | 
						|
  }
 | 
						|
 | 
						|
  static double VirtualTesterStatistics( const ENUM_STATISTICS StatID )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.TesterStatistics(StatID) : ::TesterStatistics(StatID));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool VIRTUAL::InitStat( const datetime StartTime )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::InitStat((long)StartTime * 1000));
 | 
						|
  }
 | 
						|
 | 
						|
  static datetime VirtualTimeCurrent( void )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.TimeCurrent() : ::TimeCurrent());
 | 
						|
  }
 | 
						|
 | 
						|
  static datetime VirtualTimeCurrent( MqlDateTime &StructTime )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.TimeCurrent(StructTime) : ::TimeCurrent(StructTime));
 | 
						|
  }
 | 
						|
 | 
						|
  static datetime VirtualTimeTradeServer( void )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
 | 
						|
  #ifdef __MQL5__
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.TimeCurrent() : ::TimeTradeServer());
 | 
						|
  #else // #ifdef __MQL5__
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.TimeCurrent() : ::TimeCurrent());
 | 
						|
  #endif // #ifdef __MQL5__ #else
 | 
						|
  }
 | 
						|
 | 
						|
  static datetime VirtualTimeTradeServer( MqlDateTime &StructTime )
 | 
						|
  {
 | 
						|
  #ifdef __MQL5__
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.TimeTradeServer(StructTime) : ::TimeTradeServer(StructTime));
 | 
						|
  #else // #ifdef __MQL5__
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.TimeTradeServer(StructTime) : ::TimeCurrent(StructTime));
 | 
						|
  #endif // #ifdef __MQL5__ #else
 | 
						|
  }
 | 
						|
 | 
						|
  static bool VirtualSymbolInfoTick( const string Symb, MqlTick &Tick )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.SymbolInfoTick(Symb, Tick) : ::SymbolInfoTick(Symb, Tick));
 | 
						|
  }
 | 
						|
 | 
						|
  static double VirtualSymbolInfoDouble( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.SymbolInfoDouble(Symb, Property) : ::SymbolInfoDouble(Symb, Property));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool VirtualSymbolInfoDouble( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property, double &Value )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.SymbolInfoDouble(Symb, Property, Value) : ::SymbolInfoDouble(Symb, Property, Value));
 | 
						|
  }
 | 
						|
 | 
						|
  static long VirtualSymbolInfoInteger( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.SymbolInfoInteger(Symb, Property) : ::SymbolInfoInteger(Symb, Property));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool VirtualSymbolInfoInteger( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property, long &Value )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.SymbolInfoInteger(Symb, Property, Value) : ::SymbolInfoInteger(Symb, Property, Value));
 | 
						|
  }
 | 
						|
 | 
						|
  static long VirtualAccountInfoInteger( const ENUM_ACCOUNT_INFO_INTEGER Property )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
      // Отказ от такого варианта из-за возможного вызова в OnInit и
 | 
						|
      // возможности не вызывать на каждом тике.
 | 
						|
//    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.AccountInfoInteger(Property) : ::AccountInfoInteger(Property));
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.AccountInfoInteger(Property) : ::AccountInfoInteger(Property));
 | 
						|
  }
 | 
						|
 | 
						|
  static double VirtualAccountInfoDouble( const ENUM_ACCOUNT_INFO_DOUBLE Property )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.AccountInfoDouble(Property) : ::AccountInfoDouble(Property));
 | 
						|
  }
 | 
						|
 | 
						|
  static double VirtualAccountBalance( void )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.AccountBalance() : ::AccountInfoDouble(ACCOUNT_BALANCE));
 | 
						|
  }
 | 
						|
 | 
						|
  static double VirtualAccountEquity( void )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.AccountEquity() : ::AccountInfoDouble(ACCOUNT_EQUITY));
 | 
						|
  }
 | 
						|
 | 
						|
  static double VirtualAccountProfit( void )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.AccountProfit() : ::AccountInfoDouble(ACCOUNT_PROFIT));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool VirtualTesterDeposit( const double Deposit )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.TesterDeposit(Deposit) :
 | 
						|
           #ifdef __MQL5__
 | 
						|
            ::TesterDeposit(Deposit)
 | 
						|
           #else // __MQL5__
 | 
						|
             false
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  static bool VirtualTesterWithdrawal( const double Withdraw )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.TesterWithdrawal(Withdraw) :
 | 
						|
           #ifdef __MQL5__
 | 
						|
            ::TesterWithdrawal(Withdraw)
 | 
						|
           #else // __MQL5__
 | 
						|
             false
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  // Можно сохранить выбранный ордер в static ORDER_BASE VIRTUAL::SelectOrder,
 | 
						|
  // а потом избежать оверхеда работы с указателем VIRTUAL::SelectOrders,
 | 
						|
  // забирая Order*()-значения из сохраненной структуры. Но это решение еще медленнее по замерам.
 | 
						|
  static bool VirtualOrderSelect( const TICKET_TYPE Index, const int Select, const int Pool )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.OrderSelect(Index, Select, Pool) :
 | 
						|
           #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
             (VIRTUAL::SnapshotPtr != NULL) ?
 | 
						|
             #ifdef __MQL5__ // Выбор по тикету в MT5 - разнообразный набор вариантов.
 | 
						|
               (Select == SELECT_BY_TICKET) ? ::OrderSelect(Index, Select, Pool) && VIRTUAL::SnapshotPtr.CopyOrder() // Будет выбран не из снепшота!
 | 
						|
                                            :
 | 
						|
             #endif // #ifdef __MQL5__
 | 
						|
                                              ((((Index == INT_MIN) || (Index == INT_MAX)) && (Pool == MODE_TRADES) &&
 | 
						|
                                               ::OrderSelect(Index, Select, Pool) &&
 | 
						|
                                             #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
 | 
						|
                                               VIRTUAL::SnapshotPtr.CopyOrder(true))
 | 
						|
                                             #else // #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
 | 
						|
                                               VIRTUAL::SnapshotPtr.CopyOrder())
 | 
						|
                                             #endif // #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY #else
 | 
						|
                                               || VIRTUAL::SnapshotPtr.OrderSelect(Index, Select, Pool))
 | 
						|
                                  :
 | 
						|
           #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           #ifdef __MQL5__
 | 
						|
             #ifdef __MT4ORDERS__
 | 
						|
               ::OrderSelect(Index, Select, Pool)
 | 
						|
             #else // __MT4ORDERS__
 | 
						|
               false
 | 
						|
             #endif // __MT4ORDERS__
 | 
						|
           #else // __MQL5__
 | 
						|
             ::OrderSelect(Index, Select, Pool)
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  static bool VirtualOrderSelect( const TICKET_TYPE Index, const int Select )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.OrderSelect(Index, Select) :
 | 
						|
           #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
             (VIRTUAL::SnapshotPtr != NULL) ?
 | 
						|
             #ifdef __MQL5__ // Выбор по тикету в MT5 - разнообразный набор вариантов.
 | 
						|
               (Select == SELECT_BY_TICKET) ? ::OrderSelect(Index, Select) && VIRTUAL::SnapshotPtr.CopyOrder() // Будет выбран не из снепшота!
 | 
						|
                                            :
 | 
						|
             #endif // #ifdef __MQL5__
 | 
						|
                                              ((((Index == INT_MIN) || (Index == INT_MAX)) &&
 | 
						|
                                               ::OrderSelect(Index, Select) &&
 | 
						|
                                             #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
 | 
						|
                                               VIRTUAL::SnapshotPtr.CopyOrder(true))
 | 
						|
                                             #else // #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
 | 
						|
                                               VIRTUAL::SnapshotPtr.CopyOrder())
 | 
						|
                                             #endif // #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY #else
 | 
						|
                                               || VIRTUAL::SnapshotPtr.OrderSelect(Index, Select))
 | 
						|
                                  :
 | 
						|
           #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           #ifdef __MQL5__
 | 
						|
             #ifdef __MT4ORDERS__
 | 
						|
               ::OrderSelect(Index, Select)
 | 
						|
             #else // __MT4ORDERS__
 | 
						|
               false
 | 
						|
             #endif // __MT4ORDERS__
 | 
						|
           #else // __MQL5__
 | 
						|
             ::OrderSelect(Index, Select)
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef __MQL5__
 | 
						|
  // Такая "перегрузка" позволяет использоваться совместно и MT5-вариант OrderSelect
 | 
						|
  static bool VirtualOrderSelect( const ulong Ticket )
 | 
						|
  {
 | 
						|
    return(::OrderSelect(Ticket));
 | 
						|
  }
 | 
						|
#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::IsVirtual() ? 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 )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? 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::IsVirtual() ? 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 )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? 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 )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? 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__
 | 
						|
               -1
 | 
						|
             #endif // __MT4ORDERS__
 | 
						|
           #else // __MQL5__
 | 
						|
             ::OrderSend(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration, arrow_color)
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef __MQL5__
 | 
						|
  static int VirtualOrdersTotal( const bool )
 | 
						|
  {
 | 
						|
  #ifdef __MT4ORDERS__
 | 
						|
    return(::OrdersTotal(true)); // См. static int MT4OrdersTotal( const bool ) в MT4Orders.mqh
 | 
						|
  #else // __MT4ORDERS__
 | 
						|
    return(::OrdersTotal());
 | 
						|
  #endif // __MT4ORDERS__
 | 
						|
  }
 | 
						|
#endif // __MQL5__
 | 
						|
 | 
						|
  static int VirtualOrdersTotal( void )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.OrdersTotal2() :
 | 
						|
           #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
             (VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.OrdersTotal2() :
 | 
						|
           #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           #ifdef __MQL5__
 | 
						|
             #ifdef __MT4ORDERS__
 | 
						|
               ::OrdersTotal()
 | 
						|
             #else // __MT4ORDERS__
 | 
						|
               false
 | 
						|
             #endif // __MT4ORDERS__
 | 
						|
           #else // __MQL5__
 | 
						|
             ::OrdersTotal()
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  static void VirtualOrderPrint( void )
 | 
						|
  {
 | 
						|
    if (VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle))
 | 
						|
      VIRTUAL::SelectOrders.OrderPrint();
 | 
						|
    else
 | 
						|
    #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
      if (VIRTUAL::SnapshotPtr != NULL)
 | 
						|
        VIRTUAL::SnapshotPtr.OrderPrint();
 | 
						|
      else
 | 
						|
    #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
      #ifdef __MQL5__
 | 
						|
        #ifdef __MT4ORDERS__
 | 
						|
          ::OrderPrint();
 | 
						|
        #else // __MT4ORDERS__
 | 
						|
          ::Print("");
 | 
						|
        #endif // __MT4ORDERS__
 | 
						|
      #else // __MQL5__
 | 
						|
        ::OrderPrint();
 | 
						|
      #endif // __MQL5__
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  #define ORDERFUNCTION(NAME,T)                                                          \
 | 
						|
    static T VirtualOrder##NAME( void )                                                  \
 | 
						|
    {                                                                                    \
 | 
						|
      _VC return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle))   \
 | 
						|
                 ? VIRTUAL::SelectOrders.Order##NAME() :                                 \
 | 
						|
                 (VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.Order##NAME() :
 | 
						|
 | 
						|
#else // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  #define ORDERFUNCTION(NAME,T)                                                          \
 | 
						|
    static T VirtualOrder##NAME( void )                                                  \
 | 
						|
    {                                                                                    \
 | 
						|
      _VC return(VIRTUAL::IsVirtual() ? VIRTUAL::SelectOrders.Order##NAME() :
 | 
						|
#endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME #else
 | 
						|
 | 
						|
  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(SymbolID, int)
 | 
						|
      0
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  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__
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  ORDERFUNCTION(TicketID, TICKET_TYPE)
 | 
						|
    #ifdef __MQL5__
 | 
						|
      #ifdef __MT4ORDERS__
 | 
						|
        ::OrderTicketID()
 | 
						|
      #else // __MT4ORDERS__
 | 
						|
        0
 | 
						|
      #endif // __MT4ORDERS__
 | 
						|
    #else // __MQL5__
 | 
						|
      ::OrderTicket()
 | 
						|
    #endif // __MQL5__
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  ORDERFUNCTION(DealsAmount, int)
 | 
						|
    #ifdef __MQL5__
 | 
						|
      #ifdef __MT4ORDERS__
 | 
						|
        ::OrderDealsAmount()
 | 
						|
      #else // __MT4ORDERS__
 | 
						|
        0
 | 
						|
      #endif // __MT4ORDERS__
 | 
						|
    #else // __MQL5__
 | 
						|
      0
 | 
						|
    #endif // __MQL5__
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
   ORDERFUNCTION(LotsOpen, double)
 | 
						|
    #ifdef __MQL5__
 | 
						|
      #ifdef __MT4ORDERS__
 | 
						|
        ::OrderLotsOpen()
 | 
						|
      #else // __MT4ORDERS__
 | 
						|
        0
 | 
						|
      #endif // __MT4ORDERS__
 | 
						|
    #else // __MQL5__
 | 
						|
      ::OrderLots()
 | 
						|
    #endif // __MQL5__
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  ORDERFUNCTION(TicketOpen, TICKET_TYPE)
 | 
						|
    #ifdef __MQL5__
 | 
						|
      #ifdef __MT4ORDERS__
 | 
						|
        ::OrderTicketOpen()
 | 
						|
      #else // __MT4ORDERS__
 | 
						|
        0
 | 
						|
      #endif // __MT4ORDERS__
 | 
						|
    #else // __MQL5__
 | 
						|
      ::OrderTicket()
 | 
						|
    #endif // __MQL5__
 | 
						|
    );
 | 
						|
  }
 | 
						|
#undef ORDERFUNCTION
 | 
						|
 | 
						|
  static bool VirtualOrderComment( const string NewComment )
 | 
						|
  {
 | 
						|
    _VC
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.OrderComment(NewComment));
 | 
						|
  }
 | 
						|
 | 
						|
  // DBL_MIN - тип Неттинга и размер баланса берутся с текущего счета.
 | 
						|
  static int Tester( const MqlTick &Ticks[], const STRATEGY Strategy, const double Balance = DBL_MIN, 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);
 | 
						|
  }
 | 
						|
 | 
						|
// ----TesterSingle-section: begin.
 | 
						|
  static int TesterSingle( const SYMBOL_BASE &sSymbol, const MqlTick &Ticks[], const STRATEGY Strategy,
 | 
						|
                           const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    const int Handle = VIRTUAL::GetHandle();
 | 
						|
    const bool Res = ::ArraySize(Ticks) &&
 | 
						|
                     VIRTUAL::SelectByHandle(VIRTUAL::CreateSingle(sSymbol, Balance,
 | 
						|
                                                                   Ticks[0].time - Ticks[0].time % (24 * 3600), bNetting));
 | 
						|
 | 
						|
    if (Res)
 | 
						|
    {
 | 
						|
      VIRTUAL::NewTick(Ticks, Strategy);
 | 
						|
 | 
						|
      if (Stop)
 | 
						|
        VIRTUAL::Stop();
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res ? Handle : -1);
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterSingle( const SYMBOL_BASE &sSymbol, const TICKS_ARRAY &Ticks, const STRATEGY Strategy,
 | 
						|
                           const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::TesterSingle(sSymbol, Ticks.Ticks, Strategy, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterSingle( const string sSymbol, const MqlTick &Ticks[], const STRATEGY Strategy,
 | 
						|
                           const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    // const SYMBOL_BASE sSymbol2 = sSymbol; // https://www.mql5.com/ru/forum/492248/page3#comment_57718727
 | 
						|
    SYMBOL_BASE sSymbol2; sSymbol2 = sSymbol;
 | 
						|
 | 
						|
    return(VIRTUAL::TesterSingle(sSymbol2, Ticks, Strategy, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterSingle( const string sSymbol, const TICKS_ARRAY &Ticks, const STRATEGY Strategy,
 | 
						|
                           const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::TesterSingle(sSymbol, Ticks.Ticks, Strategy, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
// ----TesterSingle-section: end.
 | 
						|
 | 
						|
// ----TesterMulti-section1: begin.
 | 
						|
  static int TesterMulti( const SYMBOL_BASE &sSymbol, const MqlTick &Ticks[], const STRATEGY_MULTI StrategyMulti,
 | 
						|
                          const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    const int Handle = VIRTUAL::GetHandle();
 | 
						|
    const bool Res = ::ArraySize(Ticks) &&
 | 
						|
                     VIRTUAL::SelectByHandle(VIRTUAL::CreateSingle(sSymbol, Balance,
 | 
						|
                                                                   Ticks[0].time - Ticks[0].time % (24 * 3600), bNetting));
 | 
						|
 | 
						|
    if (Res)
 | 
						|
    {
 | 
						|
      VIRTUAL::NewTickMulti(Ticks, StrategyMulti);
 | 
						|
 | 
						|
      if (Stop)
 | 
						|
        VIRTUAL::Stop();
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res ? Handle : -1);
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterMulti( const SYMBOL_BASE &sSymbol, const TICKS_ARRAY &Ticks, const STRATEGY_MULTI StrategyMulti,
 | 
						|
                          const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::TesterMulti(sSymbol, Ticks.Ticks, StrategyMulti, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterMulti( const string sSymbol, const MqlTick &Ticks[], const STRATEGY_MULTI StrategyMulti,
 | 
						|
                          const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    // const SYMBOL_BASE sSymbol2 = sSymbol; // https://www.mql5.com/ru/forum/492248/page3#comment_57718727
 | 
						|
    SYMBOL_BASE sSymbol2; sSymbol2 = sSymbol;
 | 
						|
 | 
						|
    return(VIRTUAL::TesterMulti(sSymbol2, Ticks, StrategyMulti, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterMulti( const string sSymbol, const TICKS_ARRAY &Ticks, const STRATEGY_MULTI StrategyMulti,
 | 
						|
                          const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::TesterMulti(sSymbol, Ticks.Ticks, StrategyMulti, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
// ----TesterMulti-section1: end.
 | 
						|
 | 
						|
// ----TesterMulti-section2: begin.
 | 
						|
  static int TesterMulti( const SYMBOL_BASE &sSymbols[], const TICKS_ARRAY &TicksArray[], const STRATEGY_MULTI StrategyMulti,
 | 
						|
                           const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    datetime MinTime = INT_MAX;
 | 
						|
 | 
						|
    for (uint i = ::MathMin(::ArraySize(sSymbols), ::ArraySize(TicksArray)); (bool)i--;)
 | 
						|
      MinTime = ::MathMin(MinTime, ::ArraySize(TicksArray[i].Ticks) ? TicksArray[i].Ticks[0].time : INT_MAX);
 | 
						|
 | 
						|
    const int Handle = VIRTUAL::GetHandle();
 | 
						|
    const bool Res = ::ArraySize(TicksArray) && (MinTime != INT_MAX) &&
 | 
						|
                     VIRTUAL::SelectByHandle(VIRTUAL::CreateMulti(sSymbols, Balance, MinTime - MinTime % (24 * 3600), bNetting));
 | 
						|
 | 
						|
    if (Res)
 | 
						|
    {
 | 
						|
      VIRTUAL::NewTickMulti(TicksArray, StrategyMulti);
 | 
						|
 | 
						|
      if (Stop)
 | 
						|
        VIRTUAL::Stop();
 | 
						|
    }
 | 
						|
 | 
						|
    return(Res ? Handle : -1);
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterMulti( const string &sSymbols[], const TICKS_ARRAY &TicksArray[], const STRATEGY_MULTI StrategyMulti,
 | 
						|
                           const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    SYMBOL_BASE sSymbols2[];
 | 
						|
 | 
						|
    for (uint i = ::ArrayResize(sSymbols2, ::ArraySize(sSymbols)); (bool)i--;)
 | 
						|
      sSymbols2[i] = sSymbols[i];
 | 
						|
 | 
						|
    return(VIRTUAL::TesterMulti(sSymbols2, TicksArray, StrategyMulti, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
// ----TesterMulti-section2: end.
 | 
						|
 | 
						|
// ----TesterMultiApart-section: begin.
 | 
						|
  static int TesterMultiApart( const SYMBOL_BASE &sSymbols[], const TICKS_ARRAY &TicksArray[], const STRATEGY_MULTI StrategyMulti,
 | 
						|
                           const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    const int Handle = VIRTUAL::GetHandle();
 | 
						|
 | 
						|
    ORDERS* PrevOrders = NULL;
 | 
						|
 | 
						|
    for (uint i = ::MathMin(::ArraySize(sSymbols), ::ArraySize(TicksArray)); (bool)i--;)
 | 
						|
      if (VIRTUAL::TesterMulti(sSymbols[i], TicksArray[i], StrategyMulti, Balance, Stop, bNetting) != -1)
 | 
						|
      {
 | 
						|
        if (PrevOrders != NULL)
 | 
						|
        {
 | 
						|
          PrevOrders += VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders, &VIRTUAL::SelectOrders);
 | 
						|
 | 
						|
          VIRTUAL::Delete();
 | 
						|
        }
 | 
						|
        else
 | 
						|
          PrevOrders = VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders, VIRTUAL::SelectOrders.MyPointer);
 | 
						|
      }
 | 
						|
 | 
						|
    if (PrevOrders != NULL)
 | 
						|
      VIRTUAL::SelectOrders = PrevOrders;
 | 
						|
 | 
						|
    return((PrevOrders != NULL) ? Handle : -1);
 | 
						|
  }
 | 
						|
 | 
						|
  static int TesterMultiApart( const string &sSymbols[], const TICKS_ARRAY &TicksArray[], const STRATEGY_MULTI StrategyMulti,
 | 
						|
                               const double Balance = DBL_MIN, const bool Stop = true, const bool bNetting = false )
 | 
						|
  {
 | 
						|
    SYMBOL_BASE sSymbols2[];
 | 
						|
 | 
						|
    for (uint i = ::ArrayResize(sSymbols2, ::ArraySize(sSymbols)); (bool)i--;)
 | 
						|
      sSymbols2[i] = sSymbols[i];
 | 
						|
 | 
						|
    return(VIRTUAL::TesterMultiApart(sSymbols2, TicksArray, StrategyMulti, Balance, Stop, bNetting));
 | 
						|
  }
 | 
						|
// ----TesterMultiApart-section: end.
 | 
						|
 | 
						|
  // Сброс номеров тикетов Истории торгов.
 | 
						|
  static bool ResetTickets( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.ResetTickets());
 | 
						|
  }
 | 
						|
 | 
						|
  static int GetMemoryUsed( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.GetMemoryUsed() : 0);
 | 
						|
  }
 | 
						|
 | 
						|
  static int GetMemoryUsedFull( void )
 | 
						|
  {
 | 
						|
    int Memory = sizeof(VIRTUAL::SelectOrders) +
 | 
						|
                 ::ArraySize(VIRTUAL::Orders) * sizeof(ORDERS*) +
 | 
						|
                 sizeof(VIRTUAL::CountHandles) +
 | 
						|
                 sizeof(VIRTUAL::VirtualDelete);
 | 
						|
 | 
						|
    for (int i = VIRTUAL::Total() - 1; i >= 0; i--)
 | 
						|
      Memory += VIRTUAL::Orders[i].GetMemoryUsed() + VIRTUAL_SELECTORDERS_MACROS(0, VIRTUAL::SelectOrders.GetMemoryUsed());
 | 
						|
 | 
						|
  #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
    Memory += sizeof(VIRTUAL::SnapshotPtr) + ((VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.GetMemoryUsed() : 0);
 | 
						|
  #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
 | 
						|
    return(Memory);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool ToStack( void )
 | 
						|
  {
 | 
						|
    VIRTUAL::StackOrders[VIRTUAL::StackPos++] = VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders, VIRTUAL::SelectOrders.MyPointer);
 | 
						|
 | 
						|
    return(true);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool SelectFromStack( void )
 | 
						|
  {
 | 
						|
    const bool Res = VIRTUAL::StackPos;
 | 
						|
 | 
						|
    if (Res)
 | 
						|
      VIRTUAL::SelectOrders = VIRTUAL::StackOrders[--VIRTUAL::StackPos];
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static const ORDER_BASE GetOrder( void )
 | 
						|
  {
 | 
						|
    ORDER_BASE Order;
 | 
						|
 | 
						|
    if (VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle))
 | 
						|
      Order = VIRTUAL::SelectOrders.GetOrder();
 | 
						|
    else
 | 
						|
    {
 | 
						|
    #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
      if (VIRTUAL::SnapshotPtr != NULL)
 | 
						|
        Order = VIRTUAL::SnapshotPtr.GetOrder();
 | 
						|
      else
 | 
						|
    #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
      Order.Copy();
 | 
						|
    }
 | 
						|
 | 
						|
    return(Order);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool AddOrder( const ORDER_BASE &Order )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.AddOrder(Order));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool AddOrder( const ORDER_BASE &NewOrders[] )
 | 
						|
  {
 | 
						|
    const int Size = ::ArraySize(NewOrders);
 | 
						|
    bool Res = (VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && Size;
 | 
						|
 | 
						|
    if (Res)
 | 
						|
      for (int i = 0; i < Size; i++)
 | 
						|
        Res &= VIRTUAL::SelectOrders.AddOrder(NewOrders[i]);
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool CalcSwaps( const datetime RolloverTime = 0 )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::CalcSwaps(_Symbol, RolloverTime));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool CalcSwaps( const string Symb, const datetime RolloverTime = 0 )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::CalcSwaps(::SymbolInfoDouble(Symb, SYMBOL_SWAP_SHORT), ::SymbolInfoDouble(Symb, SYMBOL_SWAP_LONG),
 | 
						|
                              RolloverTime,(int)::SymbolInfoInteger(Symb, SYMBOL_SWAP_ROLLOVER3DAYS)));
 | 
						|
  }
 | 
						|
 | 
						|
  static bool CalcSwaps( const double SwapShort, const double SwapLong,
 | 
						|
                         datetime RolloverTime = 0, const int Rollover3Days = WEDNESDAY )
 | 
						|
  {
 | 
						|
  #define DAY  (24 * 3600)
 | 
						|
    RolloverTime = RolloverTime % DAY;
 | 
						|
  #undef DAY
 | 
						|
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.CalcSwaps(SwapShort, SwapLong, RolloverTime, Rollover3Days));
 | 
						|
  }
 | 
						|
 | 
						|
  static uint Save( const string FileName, const bool FileCommon = false )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.Save(FileName, FileCommon) :
 | 
						|
         #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           ((VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.Save(FileName, FileCommon) : 0)
 | 
						|
         #else // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           0
 | 
						|
         #endif // // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME #else
 | 
						|
          );
 | 
						|
  }
 | 
						|
 | 
						|
  static bool Load( const string FileName, const bool FileCommon = false )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.Load(FileName, FileCommon));
 | 
						|
  }
 | 
						|
 | 
						|
  static uint Save( const int FileHandle )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.Save(FileHandle) :
 | 
						|
         #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           ((VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.Save(FileHandle) : 0)
 | 
						|
         #else // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           0
 | 
						|
         #endif // // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME #else
 | 
						|
          );
 | 
						|
  }
 | 
						|
 | 
						|
  static bool Load( const int FileHandle )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.Load(FileHandle));
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef __TYPETOBYTES__
 | 
						|
  template <typename T>
 | 
						|
  static uint Save( T &Array[], const int LastHistoryOrders = INT_MAX )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders != NULL) ? VIRTUAL::SelectOrders.Save(Array, LastHistoryOrders) :
 | 
						|
         #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           ((VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.Save(Array, LastHistoryOrders) : 0)
 | 
						|
         #else // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           0
 | 
						|
         #endif // // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME #else
 | 
						|
          );
 | 
						|
  }
 | 
						|
 | 
						|
  template <typename T>
 | 
						|
  static bool Load( const T &Array[] )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders != NULL) && VIRTUAL::SelectOrders.Load(Array));
 | 
						|
  }
 | 
						|
#endif // #ifdef __TYPETOBYTES__
 | 
						|
 | 
						|
  // NULL-строка превратится в ""-строку. См. String.mqh.
 | 
						|
  static bool SetID( const string NewID )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.SetID(NewID) :
 | 
						|
         #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           ((VIRTUAL::SnapshotPtr != NULL) && VIRTUAL::SnapshotPtr.SetID(NewID))
 | 
						|
         #else // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           false
 | 
						|
         #endif // // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME #else
 | 
						|
          );
 | 
						|
  }
 | 
						|
 | 
						|
  // NULL-строка может возвращаться только для реального окружения. См. VIRTUAL::SetID.
 | 
						|
  static string GetID( void )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.GetID() :
 | 
						|
         #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           ((VIRTUAL::SnapshotPtr != NULL) ? VIRTUAL::SnapshotPtr.GetID() : NULL)
 | 
						|
         #else // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
           NULL
 | 
						|
         #endif // // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME #else
 | 
						|
          );
 | 
						|
  }
 | 
						|
 | 
						|
  static bool ReduceHistory( const int LastHistoryOrders, const bool ChangeHistory = false )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) && VIRTUAL::SelectOrders.ReduceHistory(LastHistoryOrders, ChangeHistory));
 | 
						|
  }
 | 
						|
 | 
						|
  static string GetMode( void )
 | 
						|
  {
 | 
						|
  #define MACROS_TOSTRING(A) #A
 | 
						|
  #define MACROS_TOSTRING2(A) MACROS_TOSTRING(A)
 | 
						|
 | 
						|
    static const string Str = NULL
 | 
						|
 | 
						|
                            #ifdef __MT4ORDERS__
 | 
						|
                              + "__MT4ORDERS__ " + MACROS_TOSTRING2(__MT4ORDERS__) + "\n"
 | 
						|
                            #endif // #ifdef __MT4ORDERS__
 | 
						|
 | 
						|
                            #ifdef MAX_ORDERS
 | 
						|
                              + "MAX_ORDERS " + MACROS_TOSTRING2(MAX_ORDERS) + "\n"
 | 
						|
                            #endif // #ifdef MAX_ORDERS
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_TESTER
 | 
						|
                              + "VIRTUAL_TESTER\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_TESTER
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_TESTER_MULTI
 | 
						|
                              + "VIRTUAL_TESTER_MULTI\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_TESTER_MULTI
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_LIMITS_TP_SLIPPAGE
 | 
						|
                              + "VIRTUAL_LIMITS_TP_SLIPPAGE\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_LIMITS_TP_SLIPPAGE
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_CLOSEALL_BYEND
 | 
						|
                              + "VIRTUAL_CLOSEALL_BYEND\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_CLOSEALL_BYEND
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_ONTESTER_FORMULA
 | 
						|
                              + "VIRTUAL_ONTESTER_FORMULA " + MACROS_TOSTRING2(VIRTUAL_ONTESTER_FORMULA) + "\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_ONTESTER_FORMULA
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
                              + "VIRTUAL_SNAPSHOT_REFRESHTIME " + MACROS_TOSTRING2(VIRTUAL_SNAPSHOT_REFRESHTIME) + "\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
 | 
						|
                              + "VIRTUAL_SNAPSHOT_WITHOUT_HISTORY\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_SNAPSHOT_WITHOUT_HISTORY
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_TESTER_FAST
 | 
						|
                              + "VIRTUAL_TESTER_FAST\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_TESTER_FAST
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_COUNTER
 | 
						|
                              + "VIRTUAL_COUNTER\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_COUNTER
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_NOCHECK_NULL
 | 
						|
                              + "VIRTUAL_NOCHECK_NULL\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_NOCHECK_NULL
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_ALTERNATIVE
 | 
						|
                              + "VIRTUAL_ALTERNATIVE\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_ALTERNATIVE
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
                              + "VIRTUAL_SELECTORDERS_OBJECT\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_SELECTORDERS_OBJECT
 | 
						|
 | 
						|
                            #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY
 | 
						|
                              + "VIRTUAL_ORDERSELECT_WITHOUT_COPY\n"
 | 
						|
                            #endif // #ifdef VIRTUAL_ORDERSELECT_WITHOUT_COPY
 | 
						|
 | 
						|
                            #ifdef TICKS_CORRECT_TIME
 | 
						|
                              + "TICKS_CORRECT_TIME\n"
 | 
						|
                            #endif // #ifdef TICKS_CORRECT_TIME
 | 
						|
 | 
						|
                            #ifdef TICKS_FORCE_NORMALIZE
 | 
						|
                              + "TICKS_FORCE_NORMALIZE\n"
 | 
						|
                            #endif // #ifdef TICKS_FORCE_NORMALIZE
 | 
						|
                              ;
 | 
						|
  #undef MACROS_TOSTRING2
 | 
						|
  #undef MACROS_TOSTRING
 | 
						|
 | 
						|
    return(Str);
 | 
						|
  }
 | 
						|
 | 
						|
  static uint VirtualOrderCloseAsync( const TICKET_TYPE Ticket, const double dLots, const double Price, const int SlipPage, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.OrderClose(Ticket, dLots, Price) :
 | 
						|
           #ifdef __MQL5__
 | 
						|
             #ifdef __MT4ORDERS__
 | 
						|
               ::OrderCloseAsync(Ticket, dLots, Price, SlipPage, Arrow_Color)
 | 
						|
             #else // __MT4ORDERS__
 | 
						|
               false
 | 
						|
             #endif // __MT4ORDERS__
 | 
						|
           #else // __MQL5__
 | 
						|
             ::OrderClose(Ticket, dLots, Price, SlipPage, Arrow_Color)
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  static uint VirtualOrderModifyAsync( 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_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.OrderModify(Ticket, Price, SL, TP, Expiration) :
 | 
						|
           #ifdef __MQL5__
 | 
						|
             #ifdef __MT4ORDERS__
 | 
						|
               ::OrderModifyAsync(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 uint VirtualOrderDeleteAsync( const TICKET_TYPE Ticket, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return((VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.OrderDelete(Ticket) :
 | 
						|
           #ifdef __MQL5__
 | 
						|
             #ifdef __MT4ORDERS__
 | 
						|
               ::OrderDeleteAsync(Ticket, Arrow_Color)
 | 
						|
             #else // __MT4ORDERS__
 | 
						|
               false
 | 
						|
             #endif // __MT4ORDERS__
 | 
						|
           #else // __MQL5__
 | 
						|
             ::OrderDelete(Ticket, Arrow_Color)
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  static TICKET_TYPE VirtualOrderSendAsync( 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_MACROS(!= NULL, .Handle)) ? VIRTUAL::SelectOrders.OrderSend(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration) :
 | 
						|
           #ifdef __MQL5__
 | 
						|
             #ifdef __MT4ORDERS__
 | 
						|
               ::OrderSendAsync(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration, arrow_color)
 | 
						|
             #else // __MT4ORDERS__
 | 
						|
               -1
 | 
						|
             #endif // __MT4ORDERS__
 | 
						|
           #else // __MQL5__
 | 
						|
             ::OrderSend(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration, arrow_color)
 | 
						|
           #endif // __MQL5__
 | 
						|
           );
 | 
						|
  }
 | 
						|
 | 
						|
  // _VI2, _VSI2
 | 
						|
  struct HANDLE_INDEX
 | 
						|
  {
 | 
						|
    int Handle;
 | 
						|
    int Index;
 | 
						|
 | 
						|
    HANDLE_INDEX( const int NewHandle = -1) : Handle(NewHandle), Index(-1)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    void operator =( const int NewHandle )
 | 
						|
    {
 | 
						|
      this.Handle = NewHandle;
 | 
						|
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    bool operator !=( const int AnotherHandle ) const
 | 
						|
    {
 | 
						|
      return(this.Handle != AnotherHandle);
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  // https://www.mql5.com/ru/forum/170952/page228#comment_44576693
 | 
						|
  struct POINTER
 | 
						|
  {
 | 
						|
  private:
 | 
						|
    ORDERS* Pointer;
 | 
						|
    int Handle;
 | 
						|
 | 
						|
  public:
 | 
						|
    POINTER( void ) : Pointer(NULL), Handle(-1)
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    POINTER( const int iHandle )
 | 
						|
    {
 | 
						|
      this = iHandle;
 | 
						|
    }
 | 
						|
 | 
						|
    void operator =( const int iHandle )
 | 
						|
    {
 | 
						|
      if (iHandle == VIRTUAL::GetHandle())
 | 
						|
      {
 | 
						|
        this.Pointer = VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders, VIRTUAL::SelectOrders.MyPointer);
 | 
						|
        this.Handle = iHandle;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        const int Index = VIRTUAL::GetNumber(iHandle);
 | 
						|
 | 
						|
        if (Index >= 0)
 | 
						|
        {
 | 
						|
          this.Pointer = Index ? VIRTUAL::Orders[Index - 1] : NULL;
 | 
						|
          this.Handle = iHandle;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          this.Pointer = NULL;
 | 
						|
          this.Handle = -1;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    bool operator +=( const VIRTUAL_POINTER &pPointer ) const
 | 
						|
    {
 | 
						|
      const bool Res = (this.Pointer != NULL) && (pPointer.Pointer != NULL) && !this.IsNull() && !pPointer.IsNull();
 | 
						|
 | 
						|
      if (Res)
 | 
						|
        VIRTUAL_SELECTORDERS_MACROS(this.Pointer, VIRTUAL::GetMyPointer(this.Pointer)) +=
 | 
						|
        VIRTUAL_SELECTORDERS_MACROS(pPointer.Pointer, VIRTUAL::GetMyPointer(pPointer.Pointer));
 | 
						|
 | 
						|
      return(Res);
 | 
						|
    }
 | 
						|
 | 
						|
    bool Init( void )
 | 
						|
    {
 | 
						|
      this.Pointer = VIRTUAL_SELECTORDERS_MACROS(VIRTUAL::SelectOrders, VIRTUAL::SelectOrders.MyPointer);
 | 
						|
      this.Handle = VIRTUAL::GetHandle();
 | 
						|
 | 
						|
      return(true);
 | 
						|
    }
 | 
						|
 | 
						|
    void Delete( void )
 | 
						|
    {
 | 
						|
      this.Handle = -1;
 | 
						|
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    bool Select( void ) const
 | 
						|
    {
 | 
						|
      const bool Res = !this.IsNull();
 | 
						|
 | 
						|
      if (Res)
 | 
						|
        VIRTUAL::SelectOrders = this.Pointer;
 | 
						|
 | 
						|
      return(Res);
 | 
						|
    }
 | 
						|
 | 
						|
    int GetHandle( void ) const
 | 
						|
    {
 | 
						|
      return(this.Handle);
 | 
						|
    }
 | 
						|
 | 
						|
    bool IsNull() const
 | 
						|
    {
 | 
						|
      return(this.Handle == -1);
 | 
						|
    }
 | 
						|
 | 
						|
    bool operator != ( const VIRTUAL_POINTER &pPointer ) const
 | 
						|
    {
 | 
						|
      return(this.Handle != pPointer.Handle);
 | 
						|
    }
 | 
						|
 | 
						|
    bool operator != ( const int iHandle ) const
 | 
						|
    {
 | 
						|
      return(this.Handle != iHandle);
 | 
						|
    }
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
static ORDERS* VIRTUAL::Orders[];
 | 
						|
 | 
						|
static ORDERS VIRTUAL_SELECTORDERS_MACROS(*VIRTUAL::SelectOrders = NULL, VIRTUAL::SelectOrders(0));
 | 
						|
 | 
						|
static int VIRTUAL::CountHandles = 1;
 | 
						|
 | 
						|
static ORDERS* VIRTUAL::StackOrders[100];
 | 
						|
static int VIRTUAL::StackPos = 0;
 | 
						|
 | 
						|
#ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
  static SNAPSHOT* VIRTUAL::SnapshotPtr = NULL;
 | 
						|
  static SNAPSHOT* VIRTUAL::SnapshotPtrBackup = NULL;
 | 
						|
#endif // #ifdef VIRTUAL_SNAPSHOT_REFRESHTIME
 | 
						|
 | 
						|
static const VIRTUAL_DELETE VIRTUAL::VirtualDelete;
 | 
						|
 | 
						|
#undef VIRTUAL_SELECTORDERS_MACROS
 | 
						|
 | 
						|
#define AccountBalance VIRTUAL::VirtualAccountBalance
 | 
						|
#define AccountEquity  VIRTUAL::VirtualAccountEquity
 | 
						|
#define AccountProfit  VIRTUAL::VirtualAccountProfit
 | 
						|
 | 
						|
#ifdef OrdersTotal
 | 
						|
  #undef OrdersTotal
 | 
						|
#endif // OrdersTotal
 | 
						|
 | 
						|
#ifdef __MQL5__
 | 
						|
  #ifndef __MT4ORDERS__
 | 
						|
    #define VIRTUAL_FUNCTIONS
 | 
						|
  #endif // __MT4ORDERS__
 | 
						|
#endif // __MQL5__
 | 
						|
 | 
						|
#ifdef VIRTUAL_FUNCTIONS
 | 
						|
  bool OrderSelect( const TICKET_TYPE Index, const int Select, const int Pool )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderSelect(Index, Select, Pool));
 | 
						|
  }
 | 
						|
 | 
						|
  bool OrderSelect( const TICKET_TYPE Index, const int Select)
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderSelect(Index, Select));
 | 
						|
  }
 | 
						|
 | 
						|
  bool OrderClose( const TICKET_TYPE Ticket, const double dLots, const double Price, const int SlipPage, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderClose(Ticket, dLots, Price, SlipPage, Arrow_Color));
 | 
						|
  }
 | 
						|
 | 
						|
  bool OrderModify( const TICKET_TYPE Ticket, const double Price, const double SL, const double TP, const datetime Expiration, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderModify(Ticket, Price, SL, TP, Expiration, Arrow_Color));
 | 
						|
  }
 | 
						|
 | 
						|
  bool OrderCloseBy( const TICKET_TYPE Ticket, const TICKET_TYPE Opposite, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderCloseBy(Ticket, Opposite, Arrow_Color));
 | 
						|
  }
 | 
						|
 | 
						|
  bool OrderDelete( const TICKET_TYPE Ticket, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderDelete(Ticket, Arrow_Color));
 | 
						|
  }
 | 
						|
 | 
						|
  TICKET_TYPE OrderSend( 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::VirtualOrderSend(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration, arrow_color));
 | 
						|
  }
 | 
						|
 | 
						|
  void OrderPrint( void )
 | 
						|
  {
 | 
						|
    VIRTUAL::VirtualOrderPrint();
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  #define OrdersTotal            VIRTUAL::VirtualOrdersTotal
 | 
						|
 | 
						|
  #define ORDERFUNCTION(NAME, T)        \
 | 
						|
    T NAME( void )                      \
 | 
						|
    {                                   \
 | 
						|
      return(VIRTUAL::Virtual##NAME()); \
 | 
						|
    }
 | 
						|
 | 
						|
  ORDERFUNCTION(OrdersHistoryTotal, int);
 | 
						|
  ORDERFUNCTION(OrderTicket, TICKET_TYPE);
 | 
						|
  ORDERFUNCTION(OrderType, int);
 | 
						|
  ORDERFUNCTION(OrderLots, double);
 | 
						|
  ORDERFUNCTION(OrderOpenPrice, double);
 | 
						|
  ORDERFUNCTION(OrderOpenTime, datetime);
 | 
						|
  ORDERFUNCTION(OrderStopLoss, double);
 | 
						|
  ORDERFUNCTION(OrderTakeProfit, double);
 | 
						|
  ORDERFUNCTION(OrderClosePrice, double);
 | 
						|
  ORDERFUNCTION(OrderCloseTime, datetime);
 | 
						|
  ORDERFUNCTION(OrderExpiration, datetime);
 | 
						|
  ORDERFUNCTION(OrderMagicNumber, MAGIC_TYPE);
 | 
						|
  ORDERFUNCTION(OrderProfit, double);
 | 
						|
  ORDERFUNCTION(OrderCommission, double);
 | 
						|
  ORDERFUNCTION(OrderSwap, double);
 | 
						|
  ORDERFUNCTION(OrderSymbol, string);
 | 
						|
  ORDERFUNCTION(OrderComment, string);
 | 
						|
  ORDERFUNCTION(OrderOpenTimeMsc, long);
 | 
						|
  ORDERFUNCTION(OrderCloseTimeMsc, long);
 | 
						|
  ORDERFUNCTION(OrderOpenPriceRequest, double);
 | 
						|
  ORDERFUNCTION(OrderClosePriceRequest, double);
 | 
						|
  ORDERFUNCTION(OrderOpenReason, ENUM_DEAL_REASON);
 | 
						|
  ORDERFUNCTION(OrderCloseReason, ENUM_DEAL_REASON);
 | 
						|
  ORDERFUNCTION(OrderTicketID, TICKET_TYPE);
 | 
						|
  ORDERFUNCTION(OrderDealsAmount, int);
 | 
						|
  ORDERFUNCTION(OrderTicketOpen, TICKET_TYPE);
 | 
						|
  ORDERFUNCTION(OrderLotsOpen, double);
 | 
						|
  ORDERFUNCTION(OrderSymbolID, int);
 | 
						|
 | 
						|
  #undef ORDERFUNCTION
 | 
						|
  #undef VIRTUAL_FUNCTIONS
 | 
						|
 | 
						|
  uint OrderCloseAsync( const TICKET_TYPE Ticket, const double dLots, const double Price, const int SlipPage, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderClose(Ticket, dLots, Price, SlipPage, Arrow_Color));
 | 
						|
  }
 | 
						|
 | 
						|
  uint OrderModifyAsync( const TICKET_TYPE Ticket, const double Price, const double SL, const double TP, const datetime Expiration, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderModify(Ticket, Price, SL, TP, Expiration, Arrow_Color));
 | 
						|
  }
 | 
						|
 | 
						|
  uint OrderDeleteAsync( const TICKET_TYPE Ticket, const color Arrow_Color = clrNONE )
 | 
						|
  {
 | 
						|
    return(VIRTUAL::VirtualOrderDelete(Ticket, Arrow_Color));
 | 
						|
  }
 | 
						|
 | 
						|
  TICKET_TYPE OrderSendAsync( 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::VirtualOrderSendAsync(Symb, Type, dVolume, Price, SlipPage, SL, TP, comment, magic, dExpiration, arrow_color));
 | 
						|
  }
 | 
						|
 | 
						|
#else // #ifdef VIRTUAL_FUNCTIONS
 | 
						|
  #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 OrderSymbolID          VIRTUAL::VirtualOrderSymbolID
 | 
						|
  #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 OrderOpenReason        VIRTUAL::VirtualOrderOpenReason
 | 
						|
  #define OrderCloseReason       VIRTUAL::VirtualOrderCloseReason
 | 
						|
  #define OrderTicketID          VIRTUAL::VirtualOrderTicketID
 | 
						|
  #define OrderDealsAmount       VIRTUAL::VirtualOrderDealsAmount
 | 
						|
  #define OrderTicketOpen        VIRTUAL::VirtualOrderTicketOpen
 | 
						|
  #define OrderLotsOpen          VIRTUAL::VirtualOrderLotsOpen
 | 
						|
 | 
						|
  #define OrderCloseAsync        VIRTUAL::VirtualOrderCloseAsync
 | 
						|
  #define OrderModifyAsync       VIRTUAL::VirtualOrderModifyAsync
 | 
						|
  #define OrderDeleteAsync       VIRTUAL::VirtualOrderDeleteAsync
 | 
						|
  #define OrderSendAsync         VIRTUAL::VirtualOrderSendAsync
 | 
						|
#endif // #ifdef VIRTUAL_FUNCTIONS #else
 | 
						|
 | 
						|
#define TesterDeposit      VIRTUAL::VirtualTesterDeposit
 | 
						|
#define TesterWithdrawal   VIRTUAL::VirtualTesterWithdrawal
 | 
						|
#define TesterStatistics   VIRTUAL::VirtualTesterStatistics
 | 
						|
 | 
						|
#define TimeCurrent        VIRTUAL::VirtualTimeCurrent
 | 
						|
#define TimeTradeServer    VIRTUAL::VirtualTimeTradeServer
 | 
						|
 | 
						|
#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());
 | 
						|
#endif // VIRTUAL_ONTESTER_FORMULA
 | 
						|
}
 | 
						|
 | 
						|
#define OnTester OldOnTester2
 | 
						|
 | 
						|
#endif // BESTINTERVAL_ONTESTER
 | 
						|
 | 
						|
#define OnTick OldOnTick2 // TesterBenchmark.mqh ?
 | 
						|
 | 
						|
#else // #ifdef VIRTUAL_TESTER
 | 
						|
 | 
						|
#ifdef VIRTUAL_TESTER_FAST
 | 
						|
 | 
						|
#include "Sync.mqh"
 | 
						|
 | 
						|
struct HISTORY_UNIT
 | 
						|
{
 | 
						|
  long Ticket;
 | 
						|
  int Type;
 | 
						|
  double Lots;
 | 
						|
 | 
						|
  HISTORY_UNIT( void ) : Ticket(::OrderTicket()), Type(::OrderType()), Lots(::OrderLots())
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  bool operator !=( const HISTORY_UNIT &Unit ) const
 | 
						|
  {
 | 
						|
    return((this.Ticket != Unit.Ticket) || (this.Type != Unit.Type) || (this.Lots != Unit.Lots));
 | 
						|
  }
 | 
						|
 | 
						|
  bool IsChange( void )
 | 
						|
  {
 | 
						|
    const HISTORY_UNIT Tmp;
 | 
						|
    const bool Res = (this != Tmp);
 | 
						|
 | 
						|
    if (Res)
 | 
						|
      this = Tmp;
 | 
						|
 | 
						|
    return(Res);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// Возвращает true только в случае, если с последнего вызова произошли торговые изменения
 | 
						|
bool IsChange( void )
 | 
						|
{
 | 
						|
  static HISTORY_UNIT History[];
 | 
						|
 | 
						|
  const int Total = OrdersTotal();
 | 
						|
  bool Res = (ArraySize(History) != Total);
 | 
						|
 | 
						|
  for (int i = 0, j = Res ? ArrayResize(History, 0, Total) : 0; i < Total; i++)
 | 
						|
    if (OrderSelect(i, SELECT_BY_POS))
 | 
						|
    {
 | 
						|
      if (Res || (Res = History[j].IsChange()))
 | 
						|
        ArrayResize(History, j + 1, Total);
 | 
						|
 | 
						|
      j++;
 | 
						|
    }
 | 
						|
 | 
						|
  return(Res);
 | 
						|
}
 | 
						|
 | 
						|
void OnTick()
 | 
						|
{
 | 
						|
  static const bool Init = VIRTUAL::SelectByHandle(VIRTUAL::Create());
 | 
						|
 | 
						|
  // https://www.mql5.com/ru/forum/282062/page31#comment_19616482
 | 
						|
//  if (VIRTUAL::SelectByIndex(1))
 | 
						|
  {
 | 
						|
    VIRTUAL::NewTick(::OldOnTick2);
 | 
						|
/*
 | 
						|
    if (IsChange()) // https://www.mql5.com/ru/forum/215783/page12#comment_5924356
 | 
						|
      SYNC::Positions<ISTIME>();
 | 
						|
*/
 | 
						|
//    VIRTUAL::SelectByIndex();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
#define OnTick OldOnTick2 // TesterBenchmark.mqh ?
 | 
						|
 | 
						|
#endif // #ifdef VIRTUAL_TESTER_FAST
 | 
						|
 | 
						|
#endif // #ifdef VIRTUAL_TESTER #else
 | 
						|
 | 
						|
#ifndef __MQL5__
 | 
						|
  // VIRTUAL::POINTER
 | 
						|
  #undef private
 | 
						|
  #undef protected
 | 
						|
#endif // #ifndef __MQL5__
 | 
						|
 | 
						|
#undef VIRTUAL_SELECTORDERS_MACROS
 | 
						|
 | 
						|
#ifdef DELETE_MACRO_MAX_ORDERS
 | 
						|
  #undef MAX_ORDERS
 | 
						|
  #undef DELETE_MACRO_MAX_ORDERS
 | 
						|
#endif // #ifdef DELETE_MACRO_MAX_ORDERS |