Недавно мне задали такой вопрос: как получить данные из индикатора iBearsPower?
Прежде чем показать код, начну с основных моментов работы с индикаторами в экспертах MQL5:
Шаг 1: на глобальном уровне программы объявляем переменную - в ней будет храниться хэндл индикатора iBearsPower.
Шаг 2: в OnInit () создаем индикатор iBearsPower и записываем хэндл в переменную. Примечание: индикатор создается ОДИН раз в OnInit ().
Шаг 3: в OnTick () мы получаем данные из индикатора.
Пример находится в CodeBase в коде MySystem.
Шаг 1:
double ExtStopLoss=0.0; double ExtTakeProfit=0.0; int handle_iBullsPower; // variable for storing the handle of the iBullsPower indicator int handle_iBearsPower; // variable for storing the handle of the iBearsPower indicator double m_adjusted_point; // point value adjusted for 3 or 5 points //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit()
Шаг 2:
} //--- create handle of the indicator iBearsPower handle_iBearsPower=iBearsPower(m_symbol.Name(),Period(),Inp_ma_period); //--- if the handle is not created if(handle_iBearsPower==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iBearsPower indicator for the symbol %s/%s, error code %d", m_symbol.Name(), EnumToString(Period()), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason)
Шаг 3:
double bulls[]; ArraySetAsSeries(bulls,true); double bears[]; ArraySetAsSeries(bears,true); if(!iBullsPowerGetArray(InpBarCurrent,2,bulls) || !iBearsPowerGetArray(InpBarCurrent,2,bears)) { PrevBars=0; return; }
Функция iBearsPowerGetArray: используется CopyBuffer
//+------------------------------------------------------------------+ //| Get value of buffers for the iBearsPower in the array | //+------------------------------------------------------------------+ bool iBearsPowerGetArray(const int start_pos,const int count,double &arr_buffer[]) { //--- bool result=true; if(!ArrayIsDynamic(arr_buffer)) { Print("This a no dynamic array!"); return(false); } ArrayFree(arr_buffer); int buffer_num=0; // indicator buffer number //--- reset error code ResetLastError(); //--- fill a part of the iBearsPower array with values from the indicator buffer that has 0 index int copied=CopyBuffer(handle_iBearsPower,buffer_num,start_pos,count,arr_buffer); if(copied!=count) { //--- if the copying fails, tell the error code PrintFormat("Failed to copy data from the iBearsPower indicator, error code %d",GetLastError()); //--- quit with zero result - it means that the indicator is considered as not calculated return(false); } return(result); }
Как получать данные от индикаторов из нескольких символов.
Все очень просто! Сначала нужно указать названия символов во входных параметрах. Осталось создать хэндлы индикаторов на этих символах.
Итак, советник получает данные с текущего символа и еще с одного (" Символ 1 "), период усреднения задается в параметре Bulls Power:
//--- input parameters input string InpSybmol_1 = "USDJPY" ; // Symbol 1 (non-existent symbol -> parameter is disabled) input int Inp_BullsPower_ma_period = 5 ; // Bulls Power : averaging period
В поле глобальных переменных программы создаем две переменные - в них будут храниться хэндлы индикаторов Bulls Power:
//--- int handle_iBullsPower_current ; // variable for storing the handle of the iBullsPower indicator int handle_iBullsPower_symbol_1 ; // variable for storing the handle of the iBullsPower indicator int m_digits_symbol_1;
m_digits_symbol_1 - вспомогательная переменная, в ней хранится количество знаков после запятой для символа 1.
Создание хендлов совмещено с проверкой символа: если символ существует, то мы создаем хендл:
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit () { //--- handle_iBullsPower_symbol_1= INVALID_HANDLE ; m_digits_symbol_1= 0 ; if (m_symbol.Name(InpSybmol_1)) // sets symbol name { m_digits_symbol_1=m_symbol. Digits (); CreateBullsPower(handle_iBullsPower_symbol_1,m_symbol.Name(), Period (),Inp_BullsPower_ma_period); } handle_iBullsPower_current= INVALID_HANDLE ; if (m_symbol.Name( Symbol ())) // sets symbol name CreateBullsPower(handle_iBullsPower_current,m_symbol.Name(), Period (),Inp_BullsPower_ma_period); //--- return ( INIT_SUCCEEDED ); }
Хендлы создаются в функции CreateBullsPower:
//+------------------------------------------------------------------+ //| Create Bulls Power | //+------------------------------------------------------------------+ bool CreateBullsPower( int &handle, // handle of the indicator const string symbol, // symbol name ENUM_TIMEFRAMES timeframe, // timeframe int ma_period // averaging period ) { handle= INVALID_HANDLE ; //--- create handle of the indicator iBullsPower handle= iBullsPower (symbol,timeframe,ma_period); //--- if the handle is not created if (handle== INVALID_HANDLE ) { //--- tell about the failure and output the error code PrintFormat ( "Failed to create handle of the iBullsPower indicator for the symbol %s/%s, error code %d" , symbol, EnumToString (timeframe), GetLastError ()); //--- the indicator is stopped early return ( false ); } //--- return ( true ); }
Осталось получить данные от индикатора в OnTick () (получаем данные с помощью функции iGetArray)
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick () { //--- string text= "" ; double value[]; ArraySetAsSeries (value, true ); int buffer= 0 ,start_pos= 0 ,count= 2 ; if (handle_iBullsPower_current!= INVALID_HANDLE ) if (iGetArray(handle_iBullsPower_current,buffer,start_pos,count,value)) { text=text+ "\n" +m_symbol.Name(); for ( int i= 0 ;i<count;i++) { text=text+ " #" + IntegerToString (i)+ "+: " + DoubleToString (value[i],m_symbol. Digits ()+ 1 )+ "; " ; } } if (handle_iBullsPower_symbol_1!= INVALID_HANDLE ) if (iGetArray(handle_iBullsPower_symbol_1,buffer,start_pos,count,value)) { text=text+ "\n" +InpSybmol_1; for ( int i= 0 ;i<count;i++) { text=text+ " #" + IntegerToString (i)+ "+: " + DoubleToString (value[i],m_digits_symbol_1+ 1 )+ "; " ; } } Comment (text); }
Итого:
Возможно ли перенести часть хэндла из секции OnInit() в секцию OnTick()?
Хендл ДОЛЖЕН быть создан ТОЛЬКО ОДИН раз. Наиболее удобным местом для создания хэндла является OnInit ().
Пример работы с индикатором ZigZag
Код: ZigZag Example.mq5
Обратите внимание на алгоритм поиска экстремума: если значение в буфере индикатора не равно "0.0" и не равно "PLOT_EMPTY_VALUE" - это значит, что мы обнаружили экстремум.
Поиск экстремума происходит в барах " ZigZag: сколько свечей проверять назад ".
Алгоритм работы стандартный: ОДИН раз в OnInit () мы создаем индикатор.
//--- int handle_iCustom; // variable for storing the handle of the iCustom indicator //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- create handle of the indicator iCustom handle_iCustom=iCustom(Symbol(),Period(),"Examples\\ZigZag",InpDepth,InpDeviation,InptBackstep); //--- if the handle is not created if(handle_iCustom==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iCustom indicator for the symbol %s/%s, error code %d", Symbol(), EnumToString(Period()), GetLastError()); //--- the indicator is stopped early return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); }
Далее в OnTick () мы делаем копию данных индикатора, используя при этом хэндл индикатора.
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { static long counter=0; counter++; if(counter>=15) counter=0; else return; //--- double ZigzagBuffer[]; ArraySetAsSeries(ZigzagBuffer,true); int start_pos=0,count=InpCandlesCheck+1; if(!iGetArray(handle_iCustom,0,start_pos,count,ZigzagBuffer)) return; string text=""; for(int i=0;i<count;i++) { if(ZigzagBuffer[i]!=PLOT_EMPTY_VALUE && ZigzagBuffer[i]!=0.0) text=text+"\n"+IntegerToString(i)+": "+DoubleToString(ZigzagBuffer[i],Digits()); } Comment(text); }
Функция, с помощью которой копируются данные индикатора:
//+------------------------------------------------------------------+ //| Get value of buffers | //+------------------------------------------------------------------+ double iGetArray(const int handle,const int buffer,const int start_pos,const int count,double &arr_buffer[]) { bool result=true; if(!ArrayIsDynamic(arr_buffer)) { Print("This a no dynamic array!"); return(false); } ArrayFree(arr_buffer); //--- reset error code ResetLastError(); //--- fill a part of the iBands array with values from the indicator buffer int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer); if(copied!=count) { //--- if the copying fails, tell the error code PrintFormat("Failed to copy data from the indicator, error code %d",GetLastError()); //--- quit with zero result - it means that the indicator is considered as not calculated return(false); } return(result); }
Результат работы:
Пример работы с графическим объектом OBJ_HLINE.
Советник OBJ_HLINE, следующий за ценой, имеет два параметра: Отступ вверх - отступ вверх от текущей цены и Отступ вниз - отступ вниз от верхней строки:
Анимация работы советника:
спасибо.
void OnTick() { scanTicks(); } bool NewBar(void) { bool iNewBar=false; static double currPeriodProgress=0; double lastPeriodProgress=MathMod(TimeCurrent(),PeriodSeconds()); if(lastPeriodProgress<currPeriodProgress) iNewBar=true; currPeriodProgress=lastPeriodProgress; return(iNewBar); } void scanTicks() { NewBar(); double waktuSekarang; if(NewBar()==true) { waktuSekarang=MathMod(TimeCurrent(),PeriodSeconds()); } MqlTick tick_array[]; int copied=CopyTicks(_Symbol,tick_array,COPY_TICKS_ALL,0,1); // Latest loop for(int i=copied-1; i>=0;i--) { MqlTick tick = tick_array[i]; //debug Print("Bid : ", tick.bid, " Ask : ", tick.ask, " Array ", i); } }
Пример:
//+------------------------------------------------------------------+ //| Temp.mq5 | //| Copyright © 2019, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2019, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.00" //+------------------------------------------------------------------+ //| Enum Copy Ticks Flags | //+------------------------------------------------------------------+ enum ENUM_COPY_TICKS_FLAGS { info=0, // COPY_TICKS_INFO trade=1, // COPY_TICKS_TRADE all=2, // COPY_TICKS_ALL }; //--- input parameters input ENUM_COPY_TICKS_FLAGS InpFlags = trade; // The Copy Ticks Flags: input uint InpCount = 10; // The number of ticks that you want to receive //--- datetime ExtPrevBars=0; // "0" -> D'1970.01.01 00:00'; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- //--- 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 datetime time_0=iTime(Symbol(),Period(),0); if(time_0==ExtPrevBars) return; ExtPrevBars=time_0; //--- MqlTick tick_array[]; // Tick receiving array //--- Measuring start time before receiving the ticks uint start=GetTickCount(); //--- Requesting the tick history since 1970.01.01 00:00.001 (parameter from=1 ms) int received=CopyTicks(Symbol(),tick_array,InpFlags,(ulong)(TimeCurrent()+60),InpCount); if(received!=-1) { //--- Showing information about the number of ticks and spent time PrintFormat("%s: received %d ticks in %d ms",Symbol(),received,GetTickCount()-start); //--- If the tick history is synchronized, the error code is equal to zero if(GetLastError()==0) { int limit=(received>10)?10:received; for(int i=0;i<limit;i++) Print("Bid : ",tick_array[i].bid," Ask : ",tick_array[i].ask," Array ",i); } else PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d", _Symbol,received,GetTickCount()-start,_LastError); } } //+------------------------------------------------------------------+
Результат:
2019.08.18 09:29:02.686 2019.03.11 02:00:00 EURUSD: received 9 ticks in 0 ms 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.12343 Ask : 1.1236 Array 0 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.12344 Ask : 1.12361 Array 1 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.12342 Ask : 1.12359 Array 2 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.12343 Ask : 1.1236 Array 3 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.12341 Ask : 1.12358 Array 4 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.12342 Ask : 1.12359 Array 5 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.1234 Ask : 1.12357 Array 6 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.12341 Ask : 1.12358 Array 7 2019.08.18 09:29:02.686 2019.03.11 02:00:00 Bid : 1.1234 Ask : 1.12357 Array 8
Не публикуйте двойные сообщения!
Я удалил ваше дублирующее сообщение.
Не делайте двойных сообщений!
Я удалил ваше дублирующее сообщение.
Никто не делал двойного сообщения. Я сделал перенос сообщения из одной темы в другую:
Форум о трейдинге, автоматических торговых системах и тестировании торговых стратегий
Владимир Карпутов, 2019.08.18 07:56
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
В этой теме обсуждаются примеры кода на языке MQL5. Будут примеры получения данных из индикаторов, программирования советников... в общем, любые вопросы от новичков по языку MQL5.
Если вы только начинаете знакомиться с терминалом MetaTrader 5, то могу порекомендовать следующие темы:
Как начать работать с Metatrader 5
С чего начать?
Воспользуйтесь советами в сервисе Freelance!