Библиотеки: BestInterval - страница 23

 
traveller00:
При active=true в BestInterval.mqh есть void OnTickvoid ), внутри неё SYNC::Positions<BEST_TIME>();, которая приведёт в Sync.mqh в static void Positions( const int Handle = 0const bool Reverse = false ). Внутри пересчитываются лоты и если попадают в нужный интервал переносятся из виртуальной среды в реал через SYNC::NewOrderSend(_Symbol, Type, ::MathAbs(AddLots), Price, 10000);.  Тут немного странновато, что цена берётся не из позиций, а считывается на месте, но это ладно. Как видно, передаются нулевые StopLoss и TakeProfit. Возможно, Вы пользуетесь опцией BESTINTERVAL_LIMITSYNC_NETTING, там TakeProfit учитывается.

Да, использую этот режим. true-режим больше делался для демонстрации. На универсальное решение даже не думал тратить время, т.к. все было бы убито в пустую.

Если немного поколдовать, то можно BestInterval-true применять для одиночных проходов советников с закрытым исходным кодом (Маркет и т.д.).

Но все же основная фишка BestInterval - это работа в режиме Оптимизации. true - хорошая, но не обязательная фича.

 
  int FromFile( const string FileName = __FILE__, const int CommonFlag = 0 )
  {
    const bool Res = (::FileLoad(FileName, this.Intervals, CommonFlag) > 0) && (this.IsCalculated = true);

    if (Res)
    {
      this.AmountDeleteIntervals = ::ArraySize(this.Intervals) - (this.Intervals[0].OpenTime ? 0 : 1);

      this.FullInterval.Calculate(this.Intervals);
    }
    else
      ::Print("ERROR: Can not load the File " + FileName + "!");

    return(Res);
  }
Незначительное косметическое исправление, int => bool. Или, если я могу предложить вернуть AmountDeleteIntervals вместо этого.
 
Enrique Dangeroux:
Незначительное косметическое исправление, int => bool. Или, если я могу предложить вернуть AmountDeleteIntervals вместо этого.

Спасибо, надо будет поправить.

 

Пожалуйста, рассмотрите AverageHolding  как дополнение к библиотеке

Interval.mqh

  datetime AverageHolding;

  void CalculateFinal( void )
  {
    this.ProfitMinus = this.Profit - this.ProfitPlus;

    this.ProfitFactor = this.ProfitMinus ? -this.ProfitPlus / this.ProfitMinus : DBL_MAX;
    this.Mean = this.Total ? this.Profit / this.Total : 0;

    this.TotalMinus = this.Total - this.TotalPlus;
    
    this.AverageHolding = this.Total ? this.AverageHolding / this.Total : 0;

    return;
  }

  void Calculate( const DEAL &Deals[], const int Left, const int Right )
  {
    this.Init();

    for (int i = Left; i < Right; i++)
      if (!Deals[i].IsNull())
      {
        if (Deals[i].Profit > 0)
        {
          this.ProfitPlus += Deals[i].Profit;

          this.TotalPlus++;
        }
        
        this.AverageHolding += Deals[i+1].OpenTime - Deals[i].OpenTime;
        this.Profit += Deals[i].Profit;
        this.Total++;
      }

    this.CalculateFinal();

    this.OpenTime = Deals[Left-1].OpenTime + 1;
    this.CloseTime = Deals[Right].OpenTime - 1;

    
    return;
  }



BestInterval.mqh

#define MACROS_GET(A, B)         \
  B Get##A( void ) const         \
  {                              \
    return(this.FullInterval.A); \
  }

  MACROS_GET(Profit, double)
  MACROS_GET(ProfitPlus, double)
  MACROS_GET(ProfitMinus, double)

  MACROS_GET(Total, int)
  MACROS_GET(TotalPlus, int)
  MACROS_GET(TotalMinus, int)

  MACROS_GET(ProfitFactor, double)
  MACROS_GET(Mean, double)

  MACROS_GET(MaxDrawDown, double)
  MACROS_GET(RecoveryFactor, double)
  
  MACROS_GET(AverageHolding, datetime)
#undef MACROS_GET
 
Enrique Dangeroux:

Пожалуйста, рассмотрите AverageHolding  как дополнение к библиотеке

Среднее время жизни закрытой позиции - для чего оно нужно?

Вычислять его нужно не так. Нужно знать время закрытия.

 
fxsaber:

Среднее время жизни закрытой позиции - для чего оно нужно?

Я имею в виду среднее время жизни позиции (OrderCloseTime - OrderOpentime). Это может быть полезно в качестве пользовательских критериев GA. Например, привести GA к увеличению частоты транзакций в сочетании с минимальным порогом прибыли на сделку.


fxsaber:

Вычислять его нужно не так. Нужно знать время закрытия.

Для счета неттинга DEAL IN / OUT достаточно времени открытия для расчета, для правильной реализации необходимо использовать время закрытия, которое в настоящее время не учитывается в библиотеке.

Существует проблема, которая останется. Тестер форсирует закрытие последней позиции. Точность атомных часов может понадобиться не для всех стратегий, она останется проблемой. Также GA можно привести к большей частоте торговли, просто вернув 0, когда BestInterval.GetTotal () <xxx, например, как вы написали в каком-то посте.

Таким образом, это выглядит не стоит, пока неприятности преследуют.

 
Enrique Dangeroux:

Я имею в виду среднее время жизни позиции (OrderCloseTime - OrderOpentime). Это может быть полезно в качестве пользовательских критериев GA. Например, привести GA к увеличению частоты транзакций в сочетании с минимальным порогом прибыли на сделку.

Приведите критерий оптимизации в виде схематичного исходного кода OnTester-функции.

 

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

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

fxsaber, 2019.12.05 13:48

Сказать, что я доволен - явно преуменьшить... BestInterval теперь крут. А изменения минимальны. Как всегда, пример.


Вот круглосуточный проход.


Применяем классический BestInterval.

Profit = 8018.00 = 8018.00 + 0.00 (0.00%) - Amount of Delete Intervals = 0 (2019.09.14 - 2019.12.04)
00:00:00 - 23:59:59 : Profit = 8018.00 (100.00%), Total = 739 (73.34%), PF = 1.44, Mean = 10.85, DD = 1317.00, RF = 6.09
SUMMARY: 00:00:00 - 23:59:59 : Profit = 8018.00 (100.00%), Total = 739 (73.34%), PF = 1.44, Mean = 10.85, DD = 1317.00, RF = 6.09

Profit = 10721.00 = 8018.00 + 2703.00 (33.71%) - Amount of Delete Intervals = 1 (2019.09.14 - 2019.12.04), 13:00 - 08:00, CountHours = 18
00:00:00 - 08:03:48 : Profit = 3278.00 (30.58%), Total = 161 (79.50%), PF = 2.21, Mean = 20.36, DD = 518.00, RF = 6.33
13:07:59 - 23:59:59 : Profit = 7443.00 (69.42%), Total = 389 (74.55%), PF = 2.14, Mean = 19.13, DD = 417.00, RF = 17.85
SUMMARY: 00:00:00 - 23:59:59 : Profit = 10721.00 (100.00%), Total = 550 (76.00%), PF = 2.16, Mean = 19.49, DD = 536.00, RF = 20.00

Видим, что на треть увеличился профит, ну и другие показатели стали лучше.


Но хотелось гибкости. И вот она.

Profit = 8018.00 = 8018.00 + 0.00 (0.00%) - Amount of Delete Intervals = 0 (2019.09.14 - 2019.12.04)
00:00:00 - 23:59:59 : Profit = 8018.00 (100.00%), Total = 739 (73.34%), PF = 1.44, Mean = 10.85, DD = 1317.00, RF = 6.09
SUMMARY: 00:00:00 - 23:59:59 : Profit = 8018.00 (100.00%), Total = 739 (73.34%), PF = 1.44, Mean = 10.85, DD = 1317.00, RF = 6.09

Profit = 4868.00 = 8018.00 + -3150.00 (-39.29%) - Amount of Delete Intervals = 1 (2019.09.14 - 2019.12.04), 20:00 - 01:00, CountHours = 4
00:00:00 - 01:31:54 : Profit = 1067.00 (21.92%), Total = 32 (87.50%), PF = 4.63, Mean = 33.34, DD = 177.00, RF = 6.03
19:29:54 - 23:59:59 : Profit = 3801.00 (78.08%), Total = 118 (83.90%), PF = 5.53, Mean = 32.21, DD = 249.00, RF = 15.27
SUMMARY: 00:00:00 - 23:59:59 : Profit = 4868.00 (100.00%), Total = 150 (84.67%), PF = 5.29, Mean = 32.45, DD = 310.00, RF = 15.70


Профит не увеличился, а уменьшился! Но посмотрите на другие показатели. Вместо того, чтобы найти интервал с самым большими профитом и вероятностью подгонки, был найден гораздо более узкий интервал, но куда вкуснее, чем классика.


Новшество добавляется так

#define BESTINTERVAL_SLIPPAGE // Создание искусственного фильтра для вычисления BestInterval.


Теперь очень сильно повысилось качество исследования рыночных закономерностей. Существенные последствия для мультитестерных работ.


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


И еще такое замечание. BestInterval, например, игнорит сделки, открытые с полуночи до часа. Это вовсе на значит, что если в два часа придет сигнал на открытие, то BestInterval даст ее открыть. Библа даст открыть только в том случае, если проигноренная позиция с полуночи будет "закрыта". Поэтому можно видеть часто, что оптимизация ТС с жестко заданным интервалом дает более плохие результаты, чем показывает BestInterval.


Самый наглядный пример - это контртрендовая ТС на тренде. Допусти, ТС дает сигнал SELL, а тренд прет вверх. BestInterval будет игнорить эти сигналы.

 

Заметил такую особенность, которая основывается на своем опыте.


Если критерий Оптимизации никак не связан с гладкостью кривой профита. И лучший результат все же дает гладкую кривую, то это не подгонка.

Например, критерий - максимальная прибыль. И в результате лучший проход - прямая вверх. Это не подгонка.

А вот если критерий - минимальный R^2. И в результате лучший проход - прямая вверх. То это, скорее всего, подгоночка.


У меня дилемма, BestInterval - независимый критерий Оптимизации или нет? Особенно, с его фишкой задания Slippage.

 
Конкретный пример вышесказанного. Взял круглосуточную ТС и оптимизировал на EURUSD, с применением BestInterval и SlipPage ~ -12 пипсов. Такая картина.
Profit = 490.00 = 490.00 + 0.00 (0.00%) - Amount of Delete Intervals = 0 (2020.07.01 - 2020.08.14)
00:00:00 - 23:59:59 : Profit = 490.00 (100.00%), Total = 183 (69.95%), PF = 1.03, Mean = 2.68, DD = 2441.00, RF = 0.20
SUMMARY: 00:00:00 - 23:59:59 : Profit = 490.00 (100.00%), Total = 183 (69.95%), PF = 1.03, Mean = 2.68, DD = 2441.00, RF = 0.20

Profit = 4858.00 = 490.00 + 4368.00 (891.43%) - Amount of Delete Intervals = 1 (2020.07.01 - 2020.08.14), 18:00 - 12:00, CountHours = 17
00:00:00 - 11:42:21 : Profit = 2925.00 (60.21%), Total = 68 (75.00%), PF = 1.89, Mean = 43.01, DD = 847.00, RF = 3.45
17:53:40 - 23:59:59 : Profit = 1933.00 (39.79%), Total = 36 (77.78%), PF = 2.06, Mean = 53.69, DD = 859.00, RF = 2.25
SUMMARY: 00:00:00 - 23:59:59 : Profit = 4858.00 (100.00%), Total = 104 (75.96%), PF = 1.95, Mean = 46.71, DD = 916.00, RF = 5.30

Т.е. он говорит, что если игнорить все сделки, не попадающие в интервал 18:00-12:00, то на истории будет все красиво.


Зашиваю в ТС этот интервал, делая ТС уже не круглосуточной, и оптимизирую по максимальному профиту.

Profit = 1924.00 = 1924.00 + 0.00 (0.00%) - Amount of Delete Intervals = 0 (2020.07.01 - 2020.08.14)
00:00:00 - 23:59:59 : Profit = 1924.00 (100.00%), Total = 163 (69.94%), PF = 1.20, Mean = 11.80, DD = 2075.00, RF = 0.93
SUMMARY: 00:00:00 - 23:59:59 : Profit = 1924.00 (100.00%), Total = 163 (69.94%), PF = 1.20, Mean = 11.80, DD = 2075.00, RF = 0.93

Лучший проход генетики, мягко говоря, мусор.


ЗЫ Это еще слабый пример. Встречается, когда BestInterval имеет PF > 3, а Оптимизатор выдает PF < 1.