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

 
gspencer:
Я ничего не знаю о кодировании или работе с советниками в Meta Editor, но мне очень нравится ваша концепция с BestInterval. Не затруднит ли вас проинструктировать меня, как добавить его в советник, который я хочу протестировать?

Постарайтесь понять обсуждение в этой теме.

Библиотеки: BestInterval
Библиотеки: BestInterval
  • 2018.10.12
  • www.mql5.com
Статьи и техническая библиотека по автоматическому трейдингу: Библиотеки: BestInterval
 
// Вывод на чарт графика баланса 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:

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

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

 
Stanislav Korotky:

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

Барьер всегда был. Иногда шел напролом - чтение исходников.

 
fxsaber:

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

Бог тебе судья. 

 
Памятка
#include <fxsaber\BestInterval\BestInterval.mqh>

void OnStart()
{
  BESTINTERVAL BestInterval;

  // Соответствующие значения для всего BestInterval
  Print(BestInterval.GetTotal());          // Количество закрытых позиций.
  Print(BestInterval.GetTotalPlus());      // Количество прибыльных закрытых позиций.
  Print(BestInterval.GetTotalMinus());     // Количество убыточных закрытых позиций.
  Print(BestInterval.GetMean());           // Мат. ожидание
  Print(BestInterval.GetProfit());         // Прибыль
  Print(BestInterval.GetProfitFactor());   // Профит-фактор
  Print(BestInterval.GetProfitPlus());     // Прибыль положительных сделок
  Print(BestInterval.GetProfitMinus());    // Убыток отрицательных сделок
  Print(BestInterval.GetRecoveryFactor()); // Фактор восстановления
  Print(BestInterval.GetMaxDrawDown());    // Максимальная абсолютная просадка по балансу

  Print(BestInterval.GetAmountDeleteIntervals()); // Количество удаленных плохих интервалов

  INTERVAL Intervals[];

  const int Size = BestInterval.GetIntervals(Intervals); // Получили интервалы, из которых состоит BestInterval

  // Для каждого интервала распечатали его показатели
  for (int i = 0; i < Size; i++)
  {
    Print(Intervals[i].Total);          // Количество закрытых позиций.
    Print(Intervals[i].TotalPlus);      // Количество прибыльных закрытых позиций.
    Print(Intervals[i].TotalMinus);     // Количество убыточных закрытых позиций.
    Print(Intervals[i].Mean);           // Мат. ожидание
    Print(Intervals[i].Profit);         // Прибыль
    Print(Intervals[i].ProfitFactor);   // Профит-фактор
    Print(Intervals[i].ProfitPlus);     // Прибыль положительных сделок
    Print(Intervals[i].ProfitMinus);    // Убыток отрицательных сделок
    Print(Intervals[i].RecoveryFactor); // Фактор восстановления
    Print(Intervals[i].MaxDrawDown);    // Максимальная абсолютная просадка по балансу

    Print(Intervals[i].OpenTime);       // Время открытия интервала.
    Print(Intervals[i].CloseTime);      // Время закрытия интервала.
  }
}
 
Stanislav Korotky:

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

думал, думал, так и не придумал что кроме времени можно так же эффективно фильтровать.

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

стакан? другие датафиды?

и еще вопрос - есть смысл делать гиперкубы? по идее по отдельности оно все тоже должно хорошо фильтроваться.