MQL5: Примеры. - страница 4

 

Советник торгующий по индикатору RSI, как правило, имеет два параметра - два уровня значений: "Level UP" и "Level DOWN":

rsi levels

Шаг первый:

заносим во входные параметры эксперта, параметры индикатора. А также объявляем переменную, в которой будет храниться хендл индикатора:

//+------------------------------------------------------------------+
//|                                          iRSI simple advisor.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//--- input parameters
input int                  Inp_RSI_ma_period       = 14;          // RSI: averaging period 
input ENUM_APPLIED_PRICE   Inp_RSI_applied_price   = PRICE_CLOSE; // RSI: type of price
//---
int   handle_iRSI;               // variable for storing the handle of the iRSI indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()


Шаг второй:

добавляем два параметра ('Level UP" и "Level DOWN") - значение уровней индикатора RSI для принятия решения о торговле

//+------------------------------------------------------------------+
//|                                          iRSI simple advisor.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.001"
//--- input parameters
input int                  Inp_RSI_ma_period       = 14;          // RSI: averaging period 
input ENUM_APPLIED_PRICE   Inp_RSI_applied_price   = PRICE_CLOSE; // RSI: type of price
input double               Inp_RSI_Level_UP        = 70;          // RSI Level UP
input double               Inp_RSI_Level_DOWN      = 30;          // RSI Level DOWN
//---
int   handle_iRSI;               // variable for storing the handle of the iRSI indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()


Шаг третий:

создаём хендл индикатора в OnInit()

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iRSI
   handle_iRSI=iRSI(Symbol(),Period(),Inp_RSI_ma_period,Inp_RSI_applied_price);
//--- if the handle is not created 
   if(handle_iRSI==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |


Шаг четвёртый:

Добавляем функцию, в которой получаем значение индикатора iRSI на нужном баре

  }
//+------------------------------------------------------------------+
//| Get value of buffers for the iRSI                                |
//+------------------------------------------------------------------+
double iRSIGet(const int index)
  {
   double RSI[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iRSI array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iRSI,0,index,1,RSI)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iRSI indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(0.0);
     }
   return(RSI[0]);
  }
//+------------------------------------------------------------------+


Шаг пятый:

анализируем значение индикатора и открываем позиции. Для отсылки торговых приказов подключаем торговый класс CTade и объявляем объект m_trade. Работает советник только в момент рождения нового бара. В OnTick() получаем значение индикатора RSI на баре номер 1 и сравниваем его с уровнями "Level UP" и "Level DOWN". При получении сигнала открываем позицию. В данном советнике не реализованы Take Profit, Stop Loss, Trailing и закрытие позиций при противоположном сигнале.

//+------------------------------------------------------------------+
//|                                          iRSI simple advisor.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.004"
//---
#include <Trade\Trade.mqh>
CTrade         m_trade;                      // trading object
//--- input parameters
input int                  Inp_RSI_ma_period       = 14;          // RSI: averaging period 
input ENUM_APPLIED_PRICE   Inp_RSI_applied_price   = PRICE_CLOSE; // RSI: type of price
input double               Inp_RSI_Level_UP        = 70;          // RSI Level UP
input double               Inp_RSI_Level_DOWN      = 30;          // RSI Level DOWN
//---
int   handle_iRSI;               // variable for storing the handle of the iRSI indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iRSI
   handle_iRSI=iRSI(Symbol(),Period(),Inp_RSI_ma_period,Inp_RSI_applied_price);
//--- if the handle is not created 
   if(handle_iRSI==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code 
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early 
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   static datetime PrevBars=0;
   datetime time_0=iTime(Symbol(),Period(),0);
   if(time_0==PrevBars)
      return;
   PrevBars=time_0;
//---
   double rsi_1=iRSIGet(1);
   if(rsi_1==EMPTY_VALUE)
      return;
//---
   if(rsi_1>Inp_RSI_Level_UP)
      m_trade.Sell(1.0);
   else if(rsi_1<Inp_RSI_Level_DOWN)
      m_trade.Buy(1.0);
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---

  }
//+------------------------------------------------------------------+
//| Get value of buffers for the iRSI                                |
//+------------------------------------------------------------------+
double iRSIGet(const int index)
  {
   double RSI[1];
//--- reset error code 
   ResetLastError();
//--- fill a part of the iRSI array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(handle_iRSI,0,index,1,RSI)<0)
     {
      //--- if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iRSI indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated 
      return(EMPTY_VALUE);
     }
   return(RSI[0]);
  }
//+------------------------------------------------------------------+
Файлы:
 
  • 2.3.1 Так всё-таки - индикатор Fractals перерисовывается или нет?

Чтобы ответить точно, сначала следует сказать какие фракталы можно использовать в советнике:

  1. создать хендл индикатора iFractals - замечу, что код этого индикатора закрыт;
  2. создать хендл пользовательского индикатора (iCustom), который находится в папке \MQL5\Indicators\Examples\Fractals.mq5 - код этого индикатора открыт.

Способ #1 сравнения показаний индикаторов

В одном советнике контролировать наличие фракталов в обоих индикаторах (проводить постоянный поиск последнего фрактала). Также можно

Способ #2 сравнения показаний индикаторов

На чистый график (на котором нет ни графических объектов, ни индикаторов, ни советников) добавить два индикатора: один через меню "Вставка" - "Индикаторы" - Билла Вильямса" - "Fractalc":


а второй индикатор сначала нужно чуточку изменить:

в индикатор \MQL5\Indicators\Examples\Fractals.mq5 внести небольшую правку - изменить сдвижку по вертикале:

было "-10", а мы поставим "-20":

//--- 10 pixels upper from high price
int    ExtArrowShift=-20;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()

Конечно после этого нужно скомпилировать индикатор.

Теперь через окно "Навигатор" - правый клик на индикаторе и "Присоединить к графику":



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

GBPUSDH1

- теперь этот график нужно сохранить как шаблон для тестера стратегий: правый клик на графике и "Шаблоны" - "Сохранить шаблоны ..." и указать имя шаблона "tester.tpl".

Остаётся запустить визуальное тестирование ЛЮБОГО ДРУГОГО индикатора и в тестере можно наблюдать совпадения (или расхождения) от двух индикаторов фракталы. Я специально подыскал такое место, где видно, что стандартный индикатор Fractals (у которого код закрыт) перерисовывается: символ GBPUSD,H1, начало тестирования 2018.04.13. Видео снято начиная с 2018.04.13 11:58:


...

 
  • 7.1. ChartIndicatorsTotal, ChartIndicatorName

Индикаторы могут быть размещены не только в главном окне, но в подокне. Причём подокон может быть несколько:


Для обхода всех индикаторов нужно организовать два цикла:

  • верхний цикл по всем окнам графика - общее количество окон получим при помощи CHART_WINDOWS_TOTAL
  • и внутри каждого окна цикл по всем индикаторам - реализуем при помощи ChartIndicatorName.

Итоговый скрипт:

//+------------------------------------------------------------------+
//|                                         ChartIndicatorsTotal.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int windows_total=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
   for(int i=windows_total-1;i>=0;i--)
     {
      int indicators_total=ChartIndicatorsTotal(0,i);
      for(int j=indicators_total-1;j>=0;j--)
        {
         Print("windows #",i,", indicator #",j,", ",ChartIndicatorName(0,i,j));
        }
     }
  }


Для рисунка выше скрипт даёт такую информацию:

2018.05.15 09:16:30.602 ChartIndicatorsTotal (GBPUSD,D1)        windows #2, indicator #0, MACD(12,26,9)
2018.05.15 09:16:30.603 ChartIndicatorsTotal (GBPUSD,D1)        windows #1, indicator #0, Stoch(5,3,3)
2018.05.15 09:16:30.603 ChartIndicatorsTotal (GBPUSD,D1)        windows #0, indicator #0, Alligator(13,8,5)


Файлы:
 
Монолог ни о чём ....
 
  • 8.5.2. Свойства ордеров 

Иногда полезно знать какое значение имеют элементы внутри перечисления. Пример распечатывающий значения элементов перечисления ENUM_ORDER_TYPE. Для небольшой автоматизации применяется параметрическая форма #define

//+------------------------------------------------------------------+
//|                                              ENUM_ORDER_TYPE.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//--- параметрическая форма #define
#define output(order_type,order_description) PrintFormat("%26s  -> %d %s",EnumToString(order_type),order_type,order_description);
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- ENUM_ORDER_TYPE
   output(ORDER_TYPE_BUY,"Рыночный ордер на покупку");
   output(ORDER_TYPE_SELL,"Рыночный ордер на продажу");
   output(ORDER_TYPE_BUY_LIMIT,"Отложенный ордер Buy Limit");
   output(ORDER_TYPE_SELL_LIMIT,"Отложенный ордер Sell Limit");
   output(ORDER_TYPE_BUY_STOP,"Отложенный ордер Buy Stop");
   output(ORDER_TYPE_SELL_STOP,"Отложенный ордер Sell Stop");
   output(ORDER_TYPE_BUY_STOP_LIMIT,"По достижении цены ордера выставляется отложенный ордер Buy Limit по цене StopLimit");
   output(ORDER_TYPE_SELL_STOP_LIMIT,"По достижении цены ордера выставляется отложенный ордер Sell Limit по цене StopLimit");
   output(ORDER_TYPE_CLOSE_BY,"Ордер на закрытие позиции встречной позицией");
  }
//+------------------------------------------------------------------+


Результат работы скрипта:

            ORDER_TYPE_BUY  -> 0 Рыночный ордер на покупку
           ORDER_TYPE_SELL  -> 1 Рыночный ордер на продажу
      ORDER_TYPE_BUY_LIMIT  -> 2 Отложенный ордер Buy Limit
     ORDER_TYPE_SELL_LIMIT  -> 3 Отложенный ордер Sell Limit
       ORDER_TYPE_BUY_STOP  -> 4 Отложенный ордер Buy Stop
      ORDER_TYPE_SELL_STOP  -> 5 Отложенный ордер Sell Stop
 ORDER_TYPE_BUY_STOP_LIMIT  -> 6 По достижении цены ордера выставляется отложенный ордер Buy Limit по цене StopLimit
ORDER_TYPE_SELL_STOP_LIMIT  -> 7 По достижении цены ордера выставляется отложенный ордер Sell Limit по цене StopLimit
       ORDER_TYPE_CLOSE_BY  -> 8 Ордер на закрытие позиции встречной позицией

...

Файлы:
 
  • 8.5.3. Свойства позиций

Пример распечатывающий значения элементов перечисления ENUM_POSITION_TYPE. Для небольшой автоматизации применяется параметрическая форма #define

//+------------------------------------------------------------------+
//|                                           ENUM_POSITION_TYPE.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//--- параметрическая форма #define
#define output(position_type,position_description) PrintFormat("%26s  -> %d %s",EnumToString(position_type),position_type,position_description);
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- ENUM_POSITION_TYPE
   output(POSITION_TYPE_BUY,"Покупка");
   output(POSITION_TYPE_SELL,"Продажа");
  }
//+------------------------------------------------------------------+


Элементы перечисления ENUM_POSITION_TYPE имеют такие значения:

         POSITION_TYPE_BUY  -> 0 Покупка
        POSITION_TYPE_SELL  -> 1 Продажа


Файлы:
 

Реальная тема для создания примера - работа во 'Фрилансе':

I am trying to create my own trading robot through the wizard in MT5. However l want my trading robot to only open trades in one direction i.e. either BUY or SELL and not both.

Please advise.

Перевод: робот создан исключительно с использованием 'Мастера', (т.е. 100% стандартной библиотеки) Вопрос: как задавать ограничение в направлении торговли (только покупка, только продажа, без ограничений)?
 
Vladimir Karputov:

Остаётся запустить визуальное тестирование ЛЮБОГО ДРУГОГО индикатора и в тестере можно наблюдать совпадения (или расхождения) от двух индикаторов фракталы. Я специально подыскал такое место, где видно, что стандартный индикатор Fractals (у которого код закрыт) перерисовывается: символ GBPUSD,H1, начало тестирования 2018.04.13. Видео снято начиная с 2018.04.13 11:58:


Даже и не знал, что у этих индикаторов разный алгоритм! А остальные проверяли, которые с открытым кодом и встроенные в язык?

 
Aleksey Vyazmikin:

Даже и не знал, что у этих индикаторов разный алгоритм! А остальные проверяли, которые с открытым кодом и встроенные в язык?

Нет, не проверял. А Fractals попал под подозрение из-за того, что было по нему много вопросов.

 
книгу надо по мквл 5 написать . по мквл4 же есть