Библиотеки: Virtual - страница 81

 
fxsaber #:
Библиотека обновлена, чтобы лучше работать в мат. режиме MT5-тестера.


В частности, были такие проблемы.

Снова столкнулся с несовпадением порядка для мат и виртуал режима для BTC.
Проблема решилась таким образом:

  void SetSymbol( string sSymb = NULL )
  {
    if (sSymb == NULL)
      sSymb = _Symbol;

    this.SymbolID = 0;
    this.Symbol = sSymb;

    this.Point = _Point;//::SymbolInfoDouble(sSymb, SYMBOL_POINT);
    this.Digits = _Digits;//(int)::SymbolInfoInteger(sSymb, SYMBOL_DIGITS);

    if (false) // Режим прибыли в валюте.
    {
      this.TickSize = ::SymbolInfoDouble(sSymb, SYMBOL_TRADE_TICK_SIZE);
      this.TickValue = ::SymbolInfoDouble(sSymb, SYMBOL_TRADE_TICK_VALUE);
    }
    else // Режим прибыли в пипсах.
    {
      this.TickSize = this.Point;
      this.TickValue = 1;
    }

    // https://www.mql5.com/ru/forum/282062/page80#comment_57515249
    if (!this.TickSize || !this.TickValue) {this.TickSize = _TickSize;this.TickValue=_TickValue;} 
    if (!this.TickSize) {this.TickSize = 1;}

    this.TickValue /= this.TickSize;
/*
    this.SwapLong = ::SymbolInfoDouble(sSymb, SYMBOL_SWAP_LONG);
    this.SwapShort = ::SymbolInfoDouble(sSymb, SYMBOL_SWAP_SHORT);

    this.CommissionKoef = 0;
*/
    return;
  }

Предложения:

    this.Point = _Point;//::SymbolInfoDouble(sSymb, SYMBOL_POINT);
    this.Digits = _Digits;//(int)::SymbolInfoInteger(sSymb, SYMBOL_DIGITS);

1) В математическом режиме в SymbolInfo...() нули (либо остается что-то от предыдущего запуска в обычном режиме). Вы заполняете _Point и_Digits из файла с тиками - надо брать оттуда. В обычном режиме они тоже будут правильными.

 2)
this.TickSize = ::SymbolInfoDouble(sSymb, SYMBOL_TRADE_TICK_SIZE);
this.TickValue = ::SymbolInfoDouble(sSymb, SYMBOL_TRADE_TICK_VALUE);

Сохранил их в файле с тиками. В мат режиме заполняю глобальные переменные _TickSize и _TickValue. И в коде выше делал вот так

    if (!this.TickSize || !this.TickValue) {this.TickSize = _TickSize;this.TickValue=_TickValue;}//read from glogal in Math mode
    if (!this.TickSize) {this.TickSize = 1;}
И в начало файла добавил
#ifndef _TickSize
   #define _TickSize 1
   #define _TickValue 1
#endif

чтобы при работе без тикового тестера Virtual имел эти переменные.

После этих изменений с моим тиковым тестером стало правильно рассчитывать прибыль во всех режимах при вычислении в валюте. По пипсам по прежнему - отличия.

Так же предлагаю сделать переключатель режима прибыли через переменную или дефайн, чтобы не лезть в код библиотеки.

 
Forester #:

В математическом режиме в SymbolInfo...() нули (либо остается что-то от предыдущего запуска в обычном режиме).

Вы можете заполнить любыми данными SYMBOL_BASE-структуру и с ней вызвать VIRTUAL::CreateSingle.


Ровно так делается в EAToMath.mqh.

        const int VirtualHandle = VIRTUAL::CreateSingle(this.Data_Tester, this.Data_Tester.Deposit, this.Data_Tester.From);

 

Обновление - добавлен VIRTUAL::GetSymbolBase().

Orders.mqh
Virtual.mqh
Библиотеки: EAToMath
Библиотеки: EAToMath
  • 2025.11.04
  • www.mql5.com
Статьи и техническая библиотека по автоматическому трейдингу: Библиотеки: EAToMath
 
fxsaber #:
CreateSingle

Спасибо.
Сделал так.

         SYMBOL_BASE sb; sb.Point=_Point; sb.Digits=_Digits;  sb.TickSize=_TickSize; sb.Symbol=_Symbol; sb.SymbolID=0; sb.TickValue=_TickValue / _TickSize;//this.TickValue_ /= this.TickSize_; //as in SetSymbol() in \fxsaber\Virtual\Symbol_Base.mqh
         Print("Symbol=",_Symbol," Point=",_Point," Digits=",_Digits, " TickSize=",_TickSize," TickValue=",_TickValue);
         static const int handle1 = VIRTUAL::CreateSingle( sb, AccountBalance(),OrderSelect(0, SELECT_BY_POS, MODE_HISTORY) ? OrderOpenTime() : 0);
         static const int handle2 = VIRTUAL::CreateSingle( sb, AccountBalance(),OrderSelect(0, SELECT_BY_POS, MODE_HISTORY) ? OrderOpenTime() : 0);

Работает.

Но хотелось бы иметьфункцию для обновления SYMBOL_BASE существующего символа.
Дело в том, что в мат. режиме виртуалки создаются в OnTester(), но для контроля работы без мат. режима нужно создавать виртуалки при первом тике в OnTick(). И при работе без подключенного модуля работы с тиками.
В общем получается создание виртуалок в 3х местах через условные операторы. Хорошо бы 1 раз создать и потом обновить символ при необходимости. Наподобие GetSymbolBase.

 
Forester #:

Спасибо.
Сделал так.

Работает.

Но хотелось бы иметьфункцию для обновления SYMBOL_BASE существующего символа.
Дело в том, что в мат. режиме виртуалки создаются в OnTester(), но для контроля работы без мат. режима нужно создавать виртуалки при первом тике в OnTick(). И при работе без подключенного модуля работы с тиками.
В общем получается создание виртуалок в 3х местах через условные операторы. Хорошо бы 1 раз создать и потом обновить символ при необходимости. Наподобие GetSymbolBase.

Почему бы не создавать виртуальное окружение в OnInit? Это будет работать в любом режиме.
 
hini #:
Почему бы не создавать виртуальное окружение в OnInit? Это будет работать в любом режиме.

Все равно будет минимум 2 разных вызова
VIRTUAL::Create

и

VIRTUAL::CreateSingle(...)


Создал требуемую функцию по аналогии с Get:

в Virtual.mqh

  static void SetSymbolBase( SYMBOL_BASE &sb )
  {
    if (VIRTUAL::SelectOrders VIRTUAL_SELECTORDERS_MACROS(!= NULL, .Handle))
      VIRTUAL::SelectOrders.SetSymbolBase(sb);

  }

в Orders.mqh

  void SetSymbolBase( const SYMBOL_BASE &sb )
  {
    //this.SymbolBase.Digits = sb.Digits;this.SymbolBase.Point = sb.Point;this.SymbolBase.TickSize = sb.TickSize;this.SymbolBase.TickValue = sb.TickValue;
    this.SymbolBase = sb;
  }

Работает правильно. Для этого в OnInit() создаю виртуалки

      static const int handle1 = VIRTUAL::Create(AccountBalance()); // Создали хэндл виртуального торгового окружения 1. 0 - реальное торговое окружение
      static const int handle2 = VIRTUAL::Create(AccountBalance()); // Создали хэндл виртуального торгового окружения 2. 0 - реальное торговое окружение


Потом перед подачей тиков из файла использую эту новую функцию:

         SYMBOL_BASE sb; sb.Point=_Point; sb.Digits=_Digits;  sb.TickSize=_TickSize; sb.Symbol=_Symbol; sb.SymbolID=0; sb.TickValue=_TickValue / _TickSize;//this.TickValue_ /= this.TickSize_; //as in SetSymbol() in \fxsaber\Virtual\Symbol_Base.mqh
         VIRTUAL::SelectByIndex(1);VIRTUAL::SetSymbolBase(sb);VIRTUAL::SelectByIndex(2);VIRTUAL::SetSymbolBase(sb);

Добавьте пожалуйста в основную версию Virtual.

ПС: Есть еще одна проблема в мат режиме. Поисследую и позже напишу.

 
Forester #:

Но хотелось бы иметь функцию для обновления SYMBOL_BASE существующего символа.

Наверное, это полезно даже во время прогона, когда нужно пересчитать, например, TickValue.

Дело в том, что в мат. режиме виртуалки создаются в OnTester(), но для контроля работы без мат. режима нужно создавать виртуалки при первом тике в OnTick(). И при работе без подключенного модуля работы с тиками.

В EAToMath это решено. В частности, можно вызывать OnTick из OnTester... Но я понял, что там свой "велосипед".

В общем получается создание виртуалок в 3х местах через условные операторы. Хорошо бы 1 раз создать и потом обновить символ при необходимости. Наподобие GetSymbolBase.

Надо будет сделать.

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотеки: Virtual

Forester, 2025.11.07 10:08

Все равно будет минимум 2 разных вызова
VIRTUAL::Create

и

VIRTUAL::CreateSingle(...)

Вы можете отказаться полностью от Create в пользу CreateSingle.
 
Обновление - добавлен VIRTUAL::SetSymbolBase.
Orders.mqh
Virtual.mqh

 
Forester #:

ПС: Есть еще одна проблема в мат режиме. Поисследую и позже напишу.

Это интересно еще в контексте EAToMath, т.к. там пока не сталкивался с косяками.