Смотри, как бесплатно скачать роботов
Ищи нас в Telegram!
Ставь лайки и следи за новостями
Интересный скрипт?
Поставь на него ссылку - пусть другие тоже оценят
Понравился скрипт?
Оцени его работу в терминале MetaTrader 5
Библиотеки

OnTesterCustom - библиотека для MetaTrader 5

Просмотров:
2404
Рейтинг:
(11)
Опубликован:
2020.01.23 23:49
Обновлен:
2020.02.02 22:07
\MQL5\Experts\ \MQL5\Include\fxsaber\OnTesterCustom\
Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу

Библиотека стала некоторым причесыванием этой идеи.

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

    Обсуждение статьи "Выцарапываем профит до последнего пипса"

    fxsaber, 2019.10.07 03:03

    При настройке ТС есть два подхода

    1. Торговля постоянным лотом.
    2. ММ, как часть от свободных средств (или баланса).

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

    Например, в пипсах результат может быть одинаков у двух проходов. Но проход с бОльшим количеством сделок может стать предпочтительнее при реинвестировании.


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

    Взял такой: какая относительная прибыльность достигается при жестко заданной максимальной относительной просадке.


    При таком расчете можно не думать о ММ совсем в своей ТС для тестера. Все будет работать, будто ММ есть.


    Пример1.


    В поставке идет такой код OnTester для советника.

    #include <fxsaber\OnTesterCustom\OnTesterCustom.mqh> // Дополнительные торговые стат. показатели.
    
    #define D(A) DoubleToString(A, 2)
    
    double OnTester()
    {
      const ONTESTERCUSTOM OnTesterCustom(_Symbol);
      
      const double Commission = 20; // Комиссия - единиц на миллион за сторону
    
      const double Risk = 0.1; // Фиксированный риск.
    
      const double Gain = OnTesterCustom.TesterStatistics(ONTESTERCUSTOM_GAIN, Risk, Commission);
      const double MaxDD = OnTesterCustom.TesterStatistics(ONTESTERCUSTOM_MAXDD, Risk, Commission);    
      const double RF = OnTesterCustom.TesterStatistics(ONTESTERCUSTOM_RECOVERYFACTOR, Risk, Commission);    
          
      Print("\nПри риске " + D(Risk) +
            "\nувеличение было бы в " + D(Gain) + " раза" +
            "\nс максимальной относительной просадкой по балансу " + D(MaxDD) + 
            "\nфактор восстановления = " + D(RF) +
            "\nкомиссия = " + D(Commission) + " на миллион (на сторону).");                                      
            
      const double MaxDDFix = 0.3; // Фиксированная максимальная просадка.
      
      const double GainFix = OnTesterCustom.TesterStatistics(ONTESTERCUSTOM_GAIN_FIXDD, MaxDDFix, Commission);
      const double RFFix = OnTesterCustom.TesterStatistics(ONTESTERCUSTOM_RECOVERYFACTOR_FIXDD, MaxDDFix, Commission);    
      const double RiskFix = OnTesterCustom.TesterStatistics(ONTESTERCUSTOM_RISK_FIXDD, MaxDDFix, Commission);    
    
      Print("\nПри риске " + D(RiskFix) +
            "\nувеличение было бы в " + D(GainFix) + " раза" +
            "\nс максимальной относительной просадкой по балансу " + D(MaxDDFix) + 
            "\nфактор восстановления = " + D(RFFix) +
            "\nкомиссия = " + D(Commission) + " на миллион (на сторону).");                                          
        
      return(Gain);
    }


    Результат в Тестере будет таким.

    При риске 0.10
    увеличение было бы в 5.59 раза
    с максимальной относительной просадкой по балансу 0.07
    фактор восстановления = 2.16
    комиссия = 20.00 на миллион (на сторону).
    
    При риске 0.47
    увеличение было бы в 2517.23 раза
    с максимальной относительной просадкой по балансу 0.30
    фактор восстановления = 33.06
    комиссия = 20.00 на миллион (на сторону).

    Верхнее - расчет показателей, если закладываться на 10% от имеющейся суммы. Видно, что увеличение в ~5.5 раз.

    Нижнее - решение задачи получения максимальной просадки в 30%. Показано, что для этого можно закладываться на 47% от имеющейся суммы. И увеличение тогда будет в ~2500 раз.


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


    Пример2.


    Представим такую задачу, что имеется Маркет-советник и нужно понять, как на его потенциальную производительность влияют различные характеристики?

    Библиотека позволяет легко играться с различными показателями. От истории торгов используются только цены открытия/закрытия. Другие показатели не важны, т.к. их можно задавать, как входные параметры для вычислений. В частности, можно, например, варьировать размер комиссии и посмотреть ее влияние на результат ТС.


    Возьмем Маркет-советник и прогоним его в Тестере. После чего в Терминале запустим такой скрипт.

    #include <fxsaber\SingleTesterCache\SingleTesterCache.mqh> // https://www.mql5.com/ru/code/27611
    #include <fxsaber\MultiTester\MTTester.mqh> // https://www.mql5.com/ru/code/26132
    
    #include <fxsaber\OnTesterCustom\OnTesterCustom.mqh> // Дополнительные торговые стат. показатели.
    
    #include <Graphics\Graphic.mqh>
    
    #define MIN_WIDTH 10
    string GraphPlot( const double &Y[], int Width = 0, int Height = 0,
                      const ENUM_CURVE_TYPE Type = CURVE_NONE,
                      const string CurveName = NULL, string ObjName = NULL )
    {
      Width = Width ? Width : (int)::ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
      Height = Height ? Height : (int)::ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
      ObjName = (ObjName == NULL) ? __FUNCTION__ : ObjName;
    
      CGraphic Graphic;
    
      const bool Res = (::ObjectFind(0, ObjName) >= 0) ? Graphic.Attach(0, ObjName) : Graphic.Create(0, ObjName, 0, 0, 0, Width, Height);
    
      if (Res)
      {
        const int Size = ::ArraySize(Y);
    
        Graphic.CurveAdd(Y, ((Type == CURVE_NONE) && Size) ? ((Width / Size < MIN_WIDTH) ? CURVE_LINES : CURVE_POINTS_AND_LINES) : Type, CurveName);
    
        Graphic.CurvePlotAll();
        Graphic.Update();
      }
    
      return (Res ? Graphic.ChartObjectName() : NULL);
    }
    
    void OnStart()
    {
      uchar Bytes[];
      
      if (MTTESTER::GetLastTstCache(Bytes) != -1) // Если получилось прочитать последнюю кеш-запись одиночного прогона
      {
        const SINGLETESTERCACHE SingleTesterCache(Bytes); // Загоняем ее в соответствующий объект.
        const ONTESTERCUSTOM OnTesterCustom(SingleTesterCache);
    
        const double Risk = 0.5; // Фиксированный риск.
        
        double Gains[];
        const int Size = ArrayResize(Gains, 50);
    
        // Вычисляем прибыльность ТС для разных значений комиссии
        for (int i = 0; i < Size; i++)
          Gains[i] = OnTesterCustom.TesterStatistics(ONTESTERCUSTOM_GAIN, Risk, i);
          
        GraphPlot(Gains, 1200, 500, CURVE_NONE, "Gains(Commission)"); // Построили график зависимости прибыльности от комисиии.
      }
    }


    В результате получим график такой зависимости.

    Зависимость производительности ТС от размера торговой комиссии.

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

    Аналогично можно визуализировать и другие стат. характеристики. При этом исходный код анализируемых советников не нужен.


    Особенности.


    Поскольку библиотека несет исследовательскую составляющую, то накладываются некоторые логические ограничения на ТС.

    // Вычисляет профитность на истории не пересекающихся закрытых позиций.

    Библиотека игнорирует встроенные в советники техники ММ. Ее интересует только качество входов/выходов. Поэтому через нее возможно исследовать вопросы реинвестирования в быстром режиме Оптимизации по пипсам. Это позволит ускорить работу с советниками иногда в разы.

    Исходник кроссплатформенный. Возможен подобный анализ и реальноый торговли, т.к. есть механиз управления символами и мэджиками

    Percentage of Balance Percentage of Balance

    Советник закрывает все позиции и удаляет все отложенные ордера при достижении прибыли или просадки (задаются в процентах от Баланса торгового счёта)

    iBands Breakdown iBands Breakdown

    Торговая стратегия на неудавшихся пробоях индикатора iBands (Bollinger Bands, BB)

    Tick Counter Indicator Tick Counter Indicator

    Подсчёт тиков через вызов CopyTicksRange

    Assistant EA Assistant EA

    Помощник в торговле. Выставляет SL, открывает вторую позиция, локирует ...