//+------------------------------------------------------------------+ //| testIndicator_09112014.mq5 | //| Tapochun | //| https://login.mql5.com/ru/users/tapochun | //+------------------------------------------------------------------+ #property copyright "Tapochun" #property link "https://login.mql5.com/ru/users/tapochun" #property version "1.00" #property indicator_chart_window #property indicator_plots 0 #define PERIODS 7 //+------------------------------------------------------------------+ //| Глобальные переменные | //+------------------------------------------------------------------+ int globHandles[ PERIODS ]; // Хэндлы индикатора iFractals ENUM_TIMEFRAMES globPeriods[ PERIODS ] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1 }; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { bool answer; // Ответ функции for( int i = 0; i < PERIODS; i++ ) // Цикл по доступным ТФ { answer = InitializeIndicatorHandle( globHandles[ i ], globPeriods[ i ] ); // Получаем хэндл индикатора на i ТФ if( !answer ) return( INIT_FAILED ); // Если некорректный хэндл - выходим } 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[]) { static int savedCalc[ PERIODS ] = { 0 }; // Сохраненное кол-во просчитанных по каждому ТФ static datetime savedTime[ PERIODS ] = { 0 }; // Сохраненное время открытия последней свечи по каждому ТФ int num; if( prev_calculated == 0 ) { num = IsNewBarPlus( savedCalc, savedTime, globHandles, globPeriods ); // Номер максимального ТФ, по которому образовался новый бар Print( __FUNCTION__,": Первый запуск! num = ",num ); } else { num = IsNewBarPlus( savedCalc, savedTime, globHandles, globPeriods ); // Номер максимального ТФ, по которому образовался новый бар if( num < 0 ) return( rates_total ); // Если нет нового бара - выходим } return(rates_total); } //+------------------------------------------------------------------+ //| Инициализируем хэндлы используемых индикаторов | //+------------------------------------------------------------------+ bool InitializeIndicatorHandle( int &handle, // Хэндл индикатора const ENUM_TIMEFRAMES period // Период ) { handle = iFractals( _Symbol, period ); if( handle == INVALID_HANDLE ) { Print( __FUNCTION__,": ОШИБКА! Хэндл индикатора Fractals "+EnumToString( period )+" не получен!" ); return( false ); } return( true ); // Значение при норме } //+------------------------------------------------------------------+ //| Проверка образования нового бара + проверка по индикатору | //+------------------------------------------------------------------+ int IsNewBarPlus( int &savedCalc[], // Сохраненное количество просчитанных баров по индикатору на всех ТФ (out) datetime &savedTime[], // Сохраненное время открытия последнего бара на всех ТФ (out) const int &handles[], // Хэндлы индикатора по всем ТФ const ENUM_TIMEFRAMES &periods[] // Используемые ТФ ) { int calc[ PERIODS ] = { 0 }; // Количество просчитанных свечей по всем ТФ datetime time[ PERIODS ] = { 0 }; // Время открытия текущей свечи по i ТФ int max_time = -1; int max_calc = -1; for( int i = 0; i < PERIODS; i++ ) // Цикл по используемым ТФ { time[ i ] = (datetime)SeriesInfoInteger( _Symbol, globPeriods[ i ], SERIES_LASTBAR_DATE ); if( time[ i ] != savedTime[ i ] ) // Если время не совпадает с сохраненным { max_time = i; // Запоминаем номер максимального ТФ, по которому образовался новый бар Print( __FUNCTION__,": "+EnumToString( periods[ i ] )+". Новый бар! time[ i ] = ",TimeToString( time[ i ] ),", savedTime[ i ] = ",TimeToString( savedTime[ i ] ) ); } calc[ i ] = BarsCalculated( handles[ i ] ); // Кол-во просчитанных по i ТФ if( calc[ i ] == -1 ) // Если данные еще не расчитаны - переходим к след. ТФ { Print( __FUNCTION__,": "+EnumToString( periods[ i ] )+". Данные еще не расчитаны!" ); continue; } if( calc[ i ] != savedCalc[ i ] ) // Если новый просчитанный { max_calc = i; // Запоминаем номер максимального ТФ, по которому просчитан новый бар Print( __FUNCTION__,": "+EnumToString( periods[ i ] )+". Сохр. = ",savedCalc[ i ],", текущее = ",calc[ i ],".Новый бар по индикатору!" ); } } if( max_calc == max_time && max_calc != -1 && max_time != -1 ) // Если номера совпадают и они неотрицательные { for( int i = 0; i <= max_calc; i++ ) // Цикл по всем обновленным ТФ { savedCalc[ i ] = calc[ i ]; // Сохраняем количество просчитанных по индикатору на i ТФ savedTime[ i ] = time[ i ]; // Сохраняем время открытия текущей свечи по i ТФ Print( __FUNCTION__,": "+EnumToString( periods[ i ] )+". Сохраняем параметры. Calc = ",savedCalc[ i ],", time = ",TimeToString( savedTime[ i ] ) ); } return( max_calc ); // Возвращаем номер макс. ТФ, по которому просчитан новый бар индикатора } return( max_calc ); }