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

 
fxsaber #:

Результат запуска Primitive2.ex5 на ICMarkets.


А цена тика в спецификации какая?
 
Aleksei Kuznetsov #:
А цена тика в спецификации какая?

Я привел неправильный скрин - был включен режим по пипсам.


Спецификации RannForex.


 
Aleksei Kuznetsov #:

сравнить прибыль по золоту в тестере MQ и в виртуальном.

Совпадает без изменения Virtual-библиотеки. С учетом, конечно, постоянного TickValue.
Библиотеки: EAToMath
Библиотеки: EAToMath
  • 2026.03.24
  • www.mql5.com
Статьи и техническая библиотека по автоматическому трейдингу: Библиотеки: EAToMath
 

В мат режиме решил добавить лот в %, а не статичный. В Virtual используется штатный OrderCalcMargin() в Order_Base.mqh

  double GetMargin(void) const
  {
  #ifdef __MQL5__
    double result;

    if (::OrderCalcMargin(this.Type, this.GetSymbol(), this.Lots, this.OpenPrice, result))
      return result;
  #endif // __MQL5__
    return 0;
  }

В мат. режиме он вернет 0. И вызов AccountInfoDouble(ACCOUNT_MARGIN) из \Orders.mqh

    case ACCOUNT_MARGIN:
      Res = this.GetMargin();
тоже вернет 0.

Дополнительно и AccountInfoDouble(ACCOUNT_MARGIN_FREE)

    case ACCOUNT_MARGIN_FREE:
      Res = this.AccountEquity() - this.GetMargin();

вернет просто эквити.

Себе сделал так в MathTicker

   sinput int MathLeverage = 100; //Leverage
   bool OrderCalcMargin(ENUM_ORDER_TYPE type, string &symb, double vol, double price, double &margin){
      if(this.isMath){
         margin =  (price * vol) / (MathLeverage * this.Point_); // или /this.TickSize_
         return true;
      }else{return ::OrderCalcMargin(type, symb, vol, price, margin);}
   }

Насколько это правильно - не знаю. Подобрал формулу под золото и EURUSD другие инструменты не проверял.

Может быть это лучше|тоже в Virtual добавить? Чтобы не перехватывать AccountInfoDouble(ACCOUNT_MARGIN_FREE) и AccountInfoDouble(ACCOUNT_MARGIN) из Virtual-а, который перехватил их из тестера))

 

Хотя видимо придется все равно перехватывать, т.к. нужно еще и 

      stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
      minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
      maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
получать из файла для мат режима. Ну это для простоты применения только нужно. Сейчас использую прямые вызовы MathTick.FreeMargin() и MathTick.OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin) вместо перехвата.

Так что возможно Виртуал и нет смысла править, он же не для мат. режима изначально.

 
Aleksei Kuznetsov #:

В мат режиме решил добавить лот в %, а не статичный. В Virtual используется штатный OrderCalcMargin() в Order_Base.mqh

В мат. режиме он вернет 0. И вызов AccountInfoDouble(ACCOUNT_MARGIN) из \Orders.mqh тоже вернет 0.

В ME через CTRL+SHIFT+F поискал упоминание этого. Нашел только в одном месте - для реала. Больше нигде.

Не понимаю, зачем использовать Margin вообще для реализации % лота на бэктестах, т.к. лот прямо-пропорционален Equity/Balance.

Тем более, когда идет запуск через Virtual.


В мат. режиме полно свойств Account/Symbol должно возвращать нули. Чтобы этого не происходило - нужно тянуть в мат. режим весь этот скарб из Symbol.json и Account.json (еще и создавать нужно).

Все же мат. режим (обе публичные реализации) - это решение для осознающих ограничения авторов.


Просьба показать функцию расчета лота, чтобы понять, что на самом деле нужно.

 

Вот есть две истории торговли: постоянным лотом и процентом. Они должны однозначно преобразовываться одна в другую в обе стороны.

Если это не так, тогда вопрос.

От чего не должен зависеть алгоритм торгового сигнала.
От чего не должен зависеть алгоритм торгового сигнала.
  • 2026.03.05
  • www.mql5.com
Мы не будем давать сложное емкое определение торгового сигнала. А дадим более понятное обывательское грубое представление. Если сделать бэктест торгового робота, то точки сделок - это торговые
 
fxsaber #:

Все же мат. режим (обе публичные реализации) - это решение для осознающих ограничения авторов.

Возможно, узко вижу. Вроде, мат. режим нужен только для ускорения поиска рыночных закономерностей. А плюшки - это уже другая история.

Primitive2.mq4 ровно так написан - отсутствие лишних/повторных расчетов.

Препарируем торговый советник - 2.
Препарируем торговый советник - 2.
  • 2026.03.16
  • www.mql5.com
На этот раз для исследования возьмем советник второго по продаваемости (в этом месяце)  автора в Маркете. В режиме по реальным тикам он выглядит так. TesterReport показывает сильное влияние
 
fxsaber #:

Не понимаю, зачем использовать Margin вообще для реализации % лота на бэктестах, т.к. лот прямо-пропорционален Equity/Balance.

Кстати, да. 
Тоже не очень понимаю, хотел даже где-нибудь на форуме спросить/обсудить преимущества перед просто Эквити. Может можно и тут обсудить, раз тема поднята. Или перенести в отдельную ветку с помощью модераторов.

  1. Понимаю, что будут меньше новые лоты при наличии сделок. Но после оптимизации это видимо уже будет не важно, так как в топ уйдут одни варианты, при расчете по эквити другие.
  2. Ну и чтобы в какой то момент не запросить сделку, на которую не будет хватать свободных средств/маржи.

Видимо это основные аргументы за такой алгоритм.
Ну вообще мне не принципиально - могу и просто % от эквити брать. От баланса наверное не стоит.

fxsaber #:

Просьба показать функцию расчета лота, чтобы понять, что на самом деле нужно.

Взял из примеров Moving Average

double TradeSizeOptimized(void)
  {
   double price=0.0;
   double margin=0.0;
//--- select lot size
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);

   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//--- normalize and check limits
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);

   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;

   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- return trading volume
   return(lot);
  }

Выкинул из нее блок 

//--- calculate number of losses orders without a break
   if(DecreaseFactor>0)...

Который только усложняет код, а преимущества не ясны.

Для мат вычислений сделал так

double TradeSizeOptimized(MqlTick& Tick){
  if(MaximumRisk==0){return inLots;}
   double price=Tick.ask, margin=0.0,lot=0,stepvol=0.01,minvol=0.01,maxvol=100;
//--- select lot size

   #ifdef _MathTick_
      if(MathTick.isMath){
         if(!MathTick.OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin)){return(0.0);}//Margin = (Price symbol x Volume) / Leverage / point; FreeMargin=Equity - Margin;
         if(margin<=0.0){return(0.0);}
         lot=NormalizeDouble(MathTick.FreeMargin()*MaximumRisk/margin,2);
         //lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);//ACCOUNT_MARGIN_FREE - возьмет в Virtual, есть малые отличия, наверное из за того, что свопы в эквити в конце добавляются, а не каждый день, поэтому эквити другое => др. своб маржа => др лот для лота в %
         stepvol=MathTick.stepvol;
         minvol=MathTick.minvol;
         maxvol=MathTick.maxvol;
      }
   #endif 
   if(margin==0){// не было расчета в мат режиме
      if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin)){return(0.0);}//Margin = (Price symbol x Volume) / Leverage; FreeMargin=Equity - Margin;
      if(margin<=0.0){return(0.0);}
      lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
      stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
      minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
      maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   }


//--- normalize and check limits
   lot=stepvol*NormalizeDouble(lot/stepvol,0);
   if(lot<minvol){lot=minvol;}
   if(lot>maxvol){lot=maxvol;}
//--- return trading volume
   return(lot);
  }
 
fxsaber #:

Возможно, узко вижу. Вроде, мат. режим нужен только для ускорения поиска рыночных закономерностей. А плюшки - это уже другая история.

Ну можно и совместить)) 
Тем более, что я обычно в валюте делаю тестирование с комиссиями и текущими свопами. 
При этом могу сразу проверить в тестере MQ. Отличие в результатах - обычно центы или единицы долларов. Наверное из за округлений и из за свопов которые в конце рассчитываются, а не каждый день.