Ставь лайки и следи за новостями
Поставь на него ссылку - пусть другие тоже оценят
Оцени его работу в терминале MetaTrader 5
CCI Dual - индикатор для MetaTrader 5
- Просмотров:
- 2268
- Рейтинг:
- Опубликован:
- 2020.07.30 09:30
- Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу
Идея индикатора
Отобразить в одном подокне два индикатора 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)
Close All Positions TypeСоветник-утилита: закрывает выбранный тип позиции и выбранный тип прибыли
Советник ведет отложенный ордер на расстоянии от трендовой линии.
ATR Histogram PercentagesПроцентное изменение индикатора iATR (Average True Range, ATR) на текущем баре относительно значения iATR на предыдущем баре