Ставь лайки и следи за новостями
Поставь на него ссылку - пусть другие тоже оценят
Оцени его работу в терминале MetaTrader 5
- Просмотров:
- 2407
- Рейтинг:
- Опубликован:
-
Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу
Идея индикатора
Отобразить в одном подокне два индикатора iCCI (Commodity Channel Index, CCI) с разными периодами усреднения. На примере этого индикатора я покажу, как использовать MQL Wizard и как использовать готовые решения из справки iCCI.
Итак, по шагам:
Рис. 1. Шаг первый
- Даём имя индикатору
- Добавляем входной параметр (потом его заменим)
- Жмём кнопку 'Next'
Рис. 2. Шаг второй
- Выбираем полную версию OnCalculate
- Жмём кнопку 'Next'
Рис. 3. Финиш
- Отмечаем, что индикатор будет отображать данные в отдельном окне
- Добавляем два стиля рисования (стиль рисования будет 'DRAW_LINE')
- Жмём кнопку 'Finish'
На данном этапе получаем заготовку.
//+------------------------------------------------------------------+ //| CCI Dual.mq5 | //| Copyright 2020, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot CCIFast #property indicator_label1 "CCIFast" #property indicator_type1 DRAW_LINE #property indicator_color1 clrDodgerBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot CCISlow #property indicator_label2 "CCISlow" #property indicator_type2 DRAW_LINE #property indicator_color2 clrPaleVioletRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- input parameters input int Input1=9; //--- indicator buffers double CCIFastBuffer[]; double CCISlowBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,CCIFastBuffer,INDICATOR_DATA); SetIndexBuffer(1,CCISlowBuffer,INDICATOR_DATA); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
Теперь работает со справкой iCCI (в основном используем копипаст).
Добавляем входные параметры:
#property indicator_width2 1 //--- input parameters input group "CCI" input int Inp_CCI_Fast_ma_period = 14; // CCI Fast: averaging period input ENUM_APPLIED_PRICE Inp_CCI_Fast_applied_price = PRICE_TYPICAL; // CCI Fast: type of price input int Inp_CCI_Slow_ma_period = 50; // CCI Slow: averaging period input ENUM_APPLIED_PRICE Inp_CCI_Slow_applied_price = PRICE_TYPICAL; // CCI Slow: type of price //--- indicator buffers
Добавляем две переменные (в них будут храниться хендлы индикаторов) и две служебные переменные:
input ENUM_APPLIED_PRICE Inp_CCI_Fast_applied_price = PRICE_TYPICAL; // CCI Fast: type of price //--- indicator buffers double CCIFastBuffer[]; double CCISlowBuffer[]; //--- int handle_iCCI_Fast; // variable for storing the handle of the iCCI indicator int handle_iCCI_Slow; // variable for storing the handle of the iCCI indicator int bars_calculated=0; // we will keep the number of values in the Commodity Channel Index indicator int m_start=0; //+------------------------------------------------------------------+ //| Custom indicator initialization function |
Инициализируем служебную переменную (она отвечает за начало отсчёта)
int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,CCIFastBuffer,INDICATOR_DATA); SetIndexBuffer(1,CCISlowBuffer,INDICATOR_DATA); m_start=(m_start<Inp_CCI_Fast_ma_period)?Inp_CCI_Fast_ma_period:m_start; m_start=(m_start<Inp_CCI_Fast_ma_period)?Inp_CCI_Fast_ma_period:m_start; m_start=m_start+3; //--- return(INIT_SUCCEEDED); }
Теперь в OnInit нужно создать два индикатора:
m_start=m_start+3; //--- create handle of the indicator iCCI handle_iCCI_Fast=iCCI(Symbol(),Period(),Inp_CCI_Fast_ma_period,Inp_CCI_Fast_applied_price); //--- if the handle is not created if(handle_iCCI_Fast==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iCCI indicator (\"Fast\") for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } //--- create handle of the indicator iCCI handle_iCCI_Slow=iCCI(Symbol(),Period(),Inp_CCI_Slow_ma_period,Inp_CCI_Slow_applied_price); //--- if the handle is not created if(handle_iCCI_Slow==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iCCI indicator (\"Slow\") for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); }
Переходим в OnCalculate (используем копипаст из справки и немного вносим правки - адаптируем код для двух индикаторов).
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- int values_to_copy; //--- determine the number of values calculated in the indicator int calculated_fast=BarsCalculated(handle_iCCI_Fast); if(calculated_fast<=0) { PrintFormat("BarsCalculated(\"Fast\") returned %d, error code %d",calculated_fast,GetLastError()); return(0); } int calculated_slow=BarsCalculated(handle_iCCI_Slow); if(calculated_slow<=0) { PrintFormat("BarsCalculated(\"Slow\") returned %d, error code %d",calculated_slow,GetLastError()); return(0); } if(calculated_fast!=calculated_slow) { PrintFormat("BarsCalculated(\"Fast\") %d not equal BarsCalculated(\"Slow\") %d",calculated_fast,calculated_slow); return(0); } int calculated=calculated_fast; //--- if it is the first start of calculation of the indicator or if the number of values in the iCCI indicator changed //---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history) if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) { //--- if the iCCIBuffer array is greater than the number of values in the iCCI indicator for symbol/period, then we don't copy everything //--- otherwise, we copy less than the size of indicator buffers if(calculated>rates_total) values_to_copy=rates_total; else values_to_copy=calculated; } else { //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate() //--- for calculation not more than one bar is added values_to_copy=(rates_total-prev_calculated)+1; } //--- fill the iCCIBuffer array with values of the Commodity Channel Index indicator //--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation if(!FillArrayFromBuffer(CCIFastBuffer,handle_iCCI_Fast,values_to_copy)) return(0); if(!FillArrayFromBuffer(CCISlowBuffer,handle_iCCI_Slow,values_to_copy)) return(0); //--- memorize the number of values in the Commodity Channel Index indicator bars_calculated=calculated; //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Filling indicator buffers from the iCCI indicator | //+------------------------------------------------------------------+ bool FillArrayFromBuffer(double &values[], // indicator buffer of Commodity Channel Index values int ind_handle, // handle of the iCCI indicator int amount // number of copied values ) { //--- reset error code ResetLastError(); //--- fill a part of the iCCIBuffer array with values from the indicator buffer that has 0 index if(CopyBuffer(ind_handle,0,0,amount,values)<0) { //--- if the copying fails, tell the error code PrintFormat("Failed to copy data from the iCCI indicator, error code %d",GetLastError()); //--- quit with zero result - it means that the indicator is considered as not calculated return(false); } //--- everything is fine return(true); } //+------------------------------------------------------------------+ //| Indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(handle_iCCI_Fast!=INVALID_HANDLE) IndicatorRelease(handle_iCCI_Fast); if(handle_iCCI_Slow!=INVALID_HANDLE) IndicatorRelease(handle_iCCI_Slow); }
Наш индикатор готов!
Рис. 4. Индикатор 'CCI Dual'
Переменная 'm_start' в OnCalculalte не использовалась - она зарезервирована для последующих изменений.

Сигналы от двух индикаторов iRSI (Relative Strength Index, RSI)

Советник-утилита: закрывает выбранный тип позиции и выбранный тип прибыли

Советник ведет отложенный ордер на расстоянии от трендовой линии.

Процентное изменение индикатора iATR (Average True Range, ATR) на текущем баре относительно значения iATR на предыдущем баре