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

 
fxsaber:

Метрику можно любую написать для OnTester. Библиотека позволяет.

Неоднозначное утверждение. Подгонку определяю просто - беру ОДИН лучший результат BestInterval и гоню его (одиночный) на интервале в два раза больше. Если расширение интервала не поменяло характер прямой баланса - не подгонка. На втором рисунке выше > 1000 сделок. Если увеличиваю в два раза интервал, прямая остается. Т.е. не подгонка 100%.

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

В целом, Вы занимаетесь чисто машинным обучением, но почему-то игнорируете ту тему :)

да, если встроить какие-то метрики и именно по ним отсеивать модели, то просто рутина перебора уменьшится, вот я к чему. В идеале, если на автомате будет отбираться лучшая, которая с бОльшей вероятностью на ООС тоже что-то покажет

 
Maxim Dmitrievsky:

В целом, Вы занимаетесь чисто машинным обучением, но почему-то игнорируете ту тему :)

Не потяну.

да, если встроить какие-то метрики и именно по ним отсеивать модели, то просто рутина перебора уменьшится, вот я к чему. В идеале, если на автомате будет отбираться лучшая, которая с бОльшей вероятностью на ООС тоже что-то покажет

Ну если бы вычислительных ресурсов было бы на порядки больше, то никакой BestInterval не понадобился бы. Т.е. здесь нет никакого даже намека на МО. Просто фильтр, который удобно и быстро применять, не более.


Что же касается вероятности ООС, то она определяется именно так, как сказал выше. Т.е. исключается какой-либо фактор подбора/оптимизации. Либо все здорово, либо мусор.


Гораздо сложнее вопрос, это когда рабочая ТС есть и нужно выбрать значения оптимальных входных параметров для реала.

 

Для меня стало открытием, что ГА+BestInterval - отвратительная связка. Т.е. происходит сходимость к какому-то локальному экстремуму и на проверку он оказывается абсолютной подгонкой.

При этом Buteforce+BestInterval - отличная связка, как оказалось. Очень много, где ГА заставил поверить в мусорность ТС, Bruteforce показал перспективность.


Ну а для быстроты Bruteforce нужно малое количество тиков, и быстрая логика ТС. Поэтому все механизмы ускорения дают не только количественный, но и качественный результат.

 
От ГА самого по себе глобального оптимума как от быка молока ) Это же вроде считается разведочной оптимизацией, которая вообще ничего не обязана в плане достоверности результатов.
 
Maxim Dmitrievsky:
От ГА самого по себе глобального оптимума как от быка молока ) Это же вроде считается разведочной оптимизацией, которая вообще ничего не обязана в плане достоверности результатов.

Подружиться с ГА не получается.

 
// Вывод на чарт графика баланса BestInterval

#property strict
#property script_show_inputs

input int inAmountIntervals = 3; // Сколько наихудших интервалов торговли выбросить

#include <Graphics\Graphic.mqh> // https://www.mql5.com/ru/articles/2866

void ToChart( const double &Y[] )
{
   CGraphic graphic;
   graphic.Create(0, __FUNCTION__, 0, 30, 30, 780, 380);
   graphic.CurveAdd(Y, CURVE_LINES);
   graphic.CurvePlotAll();
   graphic.Update();   
}

#include <MT4Orders.mqh> // Не требуется, если MT4.
#include <fxsaber\BestInterval\BestInterval.mqh> // Вычисление лучшего интервала торговли

void OnStart()
{
  BESTINTERVAL BestInterval; // Создали объект для вычисления лучшего интервала торговли
  
  BestInterval.Set(); // Поместили историю торгов
          
  for (int i = 0; i < inAmountIntervals; i++)
    if (BestInterval.DeleteWorseInterval()) // Если что-то выбросили
      Print(BestInterval.ToString());       // Распечатаем полученные данные торговли
    else
      break;                                // Иначе - выйдем
      
  double Profits[];
  double Balance[];
  
  const int Size = ArrayResize(Balance, BestInterval.GetProfits(Profits) + 1); // Получили профиты BestInterval-сделок
  Balance[0] = 0;  
  
  // Вычислили кривую баланса
  for (int i = 1; i < Size; i++)
    Balance[i] = Balance[i - 1] + Profits[i - 1];
    
  ToChart(Balance); // Визуализировали
}
 
Если в конце любого советника из штатной поставки вставить это
// Передаем котировки каждого прохода Оптимизатора в Терминал. Применяем к ним BestInterval и визуализируем.

#include <MT4Orders.mqh>                         // https://www.mql5.com/ru/code/16006
#include <fxsaber\BestInterval\BestInterval.mqh> // https://www.mql5.com/ru/code/22710
#include <TypeToBytes.mqh>                       // https://www.mql5.com/ru/code/16280
#include <Graphics\Graphic.mqh>                  // https://www.mql5.com/ru/articles/2866

input int inAmountIntervals = 1; // Сколько наихудших интервалов торговли выбросить

// Выводит график
void ToChart( const double &Y[] )
{
   CGraphic graphic;
   graphic.Create(0, __FUNCTION__, 0, 30, 30, 780, 380);
   graphic.CurveAdd(Y, CURVE_LINES);
   graphic.CurvePlotAll();
   graphic.Update();   
}

// Собирает историю торговли
int GetDeals( DEAL_BASE &Deals[] )
{  
  const int Total = ArrayResize(Deals, OrdersHistoryTotal());
  int Amount = 0; 
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      Deals[Amount].OpenTime = OrderOpenTime();
      Deals[Amount++].Profit = OrderProfit() + OrderCommission() + OrderSwap();
    }
      
  return(ArrayResize(Deals, Amount));    
}

// Отсюда (Агент) будем отправлять данные на Терминал
double OnTester()
{
  DEAL_BASE Deals[];
  
  if (MQLInfoInteger(MQL_OPTIMIZATION) && GetDeals(Deals)) // Если Оптимизация, собрали историю торговли
  {    
    CONTAINER<uchar> Container; // https://www.mql5.com/ru/forum/95447/page4#comment_5464205
    
    Container[0] = Deals; // Поместили историю торгов в контейнер
  
    FrameAdd(NULL, 0, 0, Container.Data); // Отправили данные из Агента на Терминал
  }
  
  return(0);
}

// Здесь (Терминал) принимаем данные от Агентов
void OnTesterPass()
{    
  ulong Pass;
  string Name;
  long ID;
  double Value;

  CONTAINER<uchar> Container; // https://www.mql5.com/ru/forum/95447/page4#comment_5464205

  while (FrameNext(Pass, Name, ID, Value, Container.Data))
  {
    Print("Pass = " + (string)Pass); // Номер прохода
    
    DEAL_BASE Deals[];
   
    // Получили данные от Агента
    Container[0].Get(Deals);
          
    BESTINTERVAL BestInterval; // Создали объект для вычисления лучшего интервала торговли
    
    BestInterval.Set(Deals);   // Поместили переданную историю торгов

    Print(BestInterval.ToString() + "\n");           // Распечатаем полученные данные торговли
            
    for (int i = 0; i < inAmountIntervals; i++)
      if (BestInterval.DeleteWorseInterval())        // Если что-то выбросили
        Print(BestInterval.ToString() + "\n");       // Распечатаем полученные данные торговли
      else
        break;                                       // Иначе - выйдем
        
    double Profits[];
    double Balance[];
    
    const int Size = ArrayResize(Balance, BestInterval.GetProfits(Profits) + 1); // Получили профиты BestInterval-сделок
    Balance[0] = 0;  
    
    // Вычислили кривую баланса
    for (int i = 1; i < Size; i++)
      Balance[i] = Balance[i - 1] + Profits[i - 1];
      
    ToChart(Balance); // Визуализировали    
  }
}


то в логе Терминала будет нечто подобное (на примере штатного Moving Averages)

Pass = 0
Amount of Delete Intervals = 0 (2018.10.01 - 2019.02.05)
00:00:00 - 23:59:59 : Profit = -8498.94 (100.00%), Total = 6394 (26.07%), PF = 0.52, Mean = -1.33, DD = 8660.23, RF = -0.98
SUMMARY: 00:00:00 - 23:59:59 : Profit = -8498.94 (100.00%), Total = 6394 (26.07%), PF = 0.52, Mean = -1.33, DD = 8660.23, RF = -0.98

Amount of Delete Intervals = 1 (2018.10.01 - 2019.02.05), 18:00 - 18:00, CountHours = -1
17:40:01 - 17:42:59 : Profit = 364.25 (100.00%), Total = 9 (100.00%), PF = Max, Mean = 40.47, DD = 4.63, RF = 78.67
SUMMARY: 00:00:00 - 23:59:59 : Profit = 364.25 (100.00%), Total = 9 (100.00%), PF = Max, Mean = 40.47, DD = 4.63, RF = 78.67

Pass = 1
Amount of Delete Intervals = 0 (2018.10.01 - 2019.02.05)
00:00:00 - 23:59:59 : Profit = -9757.53 (100.00%), Total = 6394 (24.70%), PF = 0.55, Mean = -1.53, DD = 10076.19, RF = -0.97
SUMMARY: 00:00:00 - 23:59:59 : Profit = -9757.53 (100.00%), Total = 6394 (24.70%), PF = 0.55, Mean = -1.53, DD = 10076.19, RF = -0.97

Amount of Delete Intervals = 1 (2018.10.01 - 2019.02.05), 09:00 - 10:00, CountHours = 0
08:27:01 - 10:14:59 : Profit = 628.59 (100.00%), Total = 472 (39.41%), PF = 1.39, Mean = 1.33, DD = 550.93, RF = 1.14
SUMMARY: 00:00:00 - 23:59:59 : Profit = 628.59 (100.00%), Total = 472 (39.41%), PF = 1.39, Mean = 1.33, DD = 550.93, RF = 1.14


А на чарте график BestInterval-профита соответствующего прохода


 

Мимо проходил. Вчитался.

В описании сказано: "

  • Идея авторская. Возможно, есть аналоги.

"

Нечто более обобщенное я описывал в блоге на английском (часть 1, часть 2). Делать сечения только по интервалам времени - узкоспециализированный подход. По идее сечения по другим параметрам могут быть не менее интересны.

 
Stanislav Korotky:

Мимо проходил. Вчитался.

В описании сказано: "

  • Идея авторская. Возможно, есть аналоги.

"

Нечто более обобщенное я описывал в блоге на английском (часть 1, часть 2). Делать сечения только по интервалам времени - узкоспециализированный подход. По идее сечения по другим параметрам могут быть не менее интересны.

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

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

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

fxsaber, 2018.11.15 11:24

Сообразил, что логично обобщить принцип BestInterval. Ведь на самом деле BestInterval - это классификация сделок по OrderOpenTime. Но никто не мешает классифицировать по другому признаку.

Например, мы знаем, чему была равна МАшка (в OrderComment пропишем) в момент открытия позиции. Соответственно, все позиции в истории торгов можем сопоставить этим значениям МАшки.

А далее применяем BestInterval к этим МАшкам. И на выходе получаем, в каких диапазонах МАшки стоит открывать позиции, а в каких - нет.


Конечно, вместо МАшки можно брать любую числовую функцию. По итогу можно найти классные фильтры, которые превосходят время.

 
fxsaber:

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

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

Причина обращения: