//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2012, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #property copyright "Scriptong" #property link "http://advancetools.net" #property description "English: Displaying of the divergence based on the testimony of various indicators.\nRussian: Отображение дивергенции на основе показаний различных индикаторов." #property version "1.13" #property strict #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 clrTurquoise #property indicator_level1 0.0 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_YESNO { NO, // No / Нет YES // Yes / Да }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_INDICATOR_TYPE { RSI, // RSI MACD, // MACD MOMENTUM, // Momentum RVI, // RVI STOCHASTIC, // Stochastic StdDev, // Standart deviation DERIVATIVE, // Derivative / производная WILLIAM_BLAU, // William Blau CUSTOM // Custom / Пользовательский }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_EXTREMUM_TYPE { EXTREMUM_TYPE_NONE, EXTREMUM_TYPE_MIN, EXTREMUM_TYPE_MAX }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_MARKET_APPLIED_PRICE { MARKET_APPLIED_PRICE_CLOSE, // Close/Close MARKET_APPLIED_PRICE_HIGHLOW // High/Low }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_PRICE_TYPE { PRICE_TYPE_INDICATOR, PRICE_TYPE_MARKET }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ENUM_CUSTOM_PARAM_CNT { PARAM_CNT_0, // 0 PARAM_CNT_1, // 1 PARAM_CNT_2, // 2 PARAM_CNT_3, // 3 PARAM_CNT_4, // 4 PARAM_CNT_5, // 5 PARAM_CNT_6, // 6 PARAM_CNT_7, // 7 PARAM_CNT_8, // 8 PARAM_CNT_9, // 9 PARAM_CNT_10, // 10 PARAM_CNT_11, // 11 PARAM_CNT_12, // 12 PARAM_CNT_13, // 13 PARAM_CNT_14, // 14 PARAM_CNT_15, // 15 PARAM_CNT_16, // 16 PARAM_CNT_17, // 17 PARAM_CNT_18, // 18 PARAM_CNT_19, // 19 PARAM_CNT_20 // 20 }; //--- Input parameters of indicator input ENUM_INDICATOR_TYPE i_indicatorType = WILLIAM_BLAU; // Base indicator / Базовый индикатор input int i_divergenceDepth = 20; // Depth of 2nd ref. point search / Глубина поиска 2ой оп. точки input string i_string1="The base indicator parameters / Параметры базового индикатора"; // ============================ input int i_barsPeriod1 = 8000; // First calculate period / Первый период расчета input int i_barsPeriod2 = 2; // Second calculate period / Второй период расчета input int i_barsPeriod3 = 1; // Third calculate period / Третий период расчета input ENUM_APPLIED_PRICE i_indAppliedPrice = PRICE_CLOSE; // Applied price of indicator / Цена расчета индикатора input ENUM_MA_METHOD i_indMAMethod = MODE_EMA; // MA calculate method / Метод расчета среднего input string i_string2="Price extremum parameters / Параметры ценового экстремума"; // ============================ input int i_findExtInterval = 10; // Price ext. to indicator ext. / От экст. цены до экст. инд. input ENUM_MARKET_APPLIED_PRICE i_marketAppliedPrice = MARKET_APPLIED_PRICE_CLOSE; // Applied price of market / Используемая рыночная цена input string i_string3="Custom indicator / Пользовательский индикатор"; // ============================ input string i_customName = "Sentiment_Line"; // The name of indicator / Имя индикатора input int i_customBuffer = 0; // Index of data buffer / Индекс буфера для съема данных input ENUM_CUSTOM_PARAM_CNT i_customParamCnt = PARAM_CNT_3; // Amount of ind. parameters / Кол-во параметров индикатора input double i_customParam1 = 13.0; // Value of the 1st parameter / Значение 1-ого параметра input double i_customParam2 = 1.0; // Value of the 2nd parameter / Значение 2-ого параметра input double i_customParam3 = 0.0; // Value of the 3rd parameter / Значение 3-ого параметра input double i_customParam4 = 0.0; // Value of the 4th parameter / Значение 4-ого параметра input double i_customParam5 = 0.0; // Value of the 5th parameter / Значение 5-ого параметра input double i_customParam6 = 0.0; // Value of the 6th parameter / Значение 6-ого параметра input double i_customParam7 = 0.0; // Value of the 7th parameter / Значение 7-ого параметра input double i_customParam8 = 0.0; // Value of the 8th parameter / Значение 8-ого параметра input double i_customParam9 = 0.0; // Value of the 9th parameter / Значение 9-ого параметра input double i_customParam10 = 0.0; // Value of the 10th parameter / Значение 10-ого параметра input double i_customParam11 = 0.0; // Value of the 11th parameter / Значение 11-ого параметра input double i_customParam12 = 0.0; // Value of the 12th parameter / Значение 12-ого параметра input double i_customParam13 = 0.0; // Value of the 13th parameter / Значение 13-ого параметра input double i_customParam14 = 0.0; // Value of the 14th parameter / Значение 14-ого параметра input double i_customParam15 = 0.0; // Value of the 15th parameter / Значение 15-ого параметра input double i_customParam16 = 0.0; // Value of the 16th parameter / Значение 16-ого параметра input double i_customParam17 = 0.0; // Value of the 17th parameter / Значение 17-ого параметра input double i_customParam18 = 0.0; // Value of the 18th parameter / Значение 18-ого параметра input double i_customParam19 = 0.0; // Value of the 19th parameter / Значение 19-ого параметра input double i_customParam20 = 0.0; // Value of the 20th parameter / Значение 20-ого параметра input string i_string4="Parameters of displaying / Параметры отображения"; // ============================ input ENUM_YESNO i_isAlert = YES; // Alert on divergence? / Сигнал при дивергенции? input ENUM_YESNO i_isPush = YES; // Notification on divergence? / Уведомлять при дивергенции? input string i_string4_1 = "Divergence class A / Дивергенции класса А";// ============================ input ENUM_YESNO i_showClassA = YES; // Show / Отображать input color i_bullsDivAColor = clrBlue; // Color of bulls divergence line / Цвет линий бычьей дивергенции input color i_bearsDivAColor = clrRed; // Color of bears divergence line / Цвет линий медв. дивергенции input string i_string4_2 = "Divergence class B / Дивергенции класса B";// ============================ input ENUM_YESNO i_showClassB = NO; // Show / Отображать input color i_bullsDivBColor = clrDodgerBlue; // Color of bulls divergence line / Цвет линий бычьей дивергенции input color i_bearsDivBColor = clrMaroon; // Color of bears divergence line / Цвет линий медв. дивергенции input string i_string4_3 = "Divergence class C / Дивергенции класса C";// ============================ input ENUM_YESNO i_showClassC = NO; // Show / Отображать input color i_bullsDivCColor = clrDeepSkyBlue; // Color of bulls divergence line / Цвет линий бычьей дивергенции input color i_bearsDivCColor = clrPurple; // Color of bears divergence line / Цвет линий медв. дивергенции input string i_string4_4 = "Hidden divergence / Скрытая дивергенция"; // ============================ input ENUM_YESNO i_showHidden = NO; // Show / Отображать input color i_bullsDivHColor = clrYellowGreen; // Color of bulls divergence line / Цвет линий бычьей дивергенции input color i_bearsDivHColor = clrIndigo; // Color of bears divergence line / Цвет линий медв. дивергенции input int i_indBarsCount = 10000; // The number of bars to display / Количество баров отображения //--- The indicator's buffers double g_indValues[]; double g_tempBuffer[]; //--- Other global variables of indicator bool g_activate; // Sign of successful initialization of indicator int g_indSubWindow; // Subwindow index of indicator string g_indName,// The unique name of the indicator for easy location indicator subwindow g_tfName; // Name of current TF #define PREFIX "DIVVIEW_" // Prefix the name of the graphic objects which displayed by indicator #define TITLE_CLASS_A "Class A" #define TITLE_CLASS_B "Class B" #define TITLE_CLASS_C "Class C" #define TITLE_CLASS_H "Hidden divergence" //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Custom indicator initialization function | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ int OnInit() { g_activate=false; if(!IsTuningParametersCorrect()) return INIT_FAILED; if(!BuffersBind()) return (INIT_FAILED); g_tfName=GetCurrentTFName(); g_indSubWindow=-1; g_activate=true; return INIT_SUCCEEDED; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Checking the correctness of input parameters | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ bool IsTuningParametersCorrect() { string name=WindowExpertName(); bool isRussianLang=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian"); if(i_divergenceDepth<1) { Alert(name,(isRussianLang)? ": глубина поиска второй опорной точки должна быть 1 и более баров. Индикатор отключен." : ": depth search for the second reference point should be 1 or more bars. The indicator is turned off."); return false; } if(i_barsPeriod1<1) { Alert(name,(isRussianLang)? ": первое количество баров для расчета показаний индикатора менее 1. Индикатор отключен." : ": the first amount of bars for calculate the indicator values is less then 1. The indicator is turned off."); return false; } if(i_barsPeriod2<1) { Alert(name,(isRussianLang)? ": второе количество баров для расчета показаний индикатора менее 1. Индикатор отключен." : ": the second amount of bars for calculate the indicator values is less then 1. The indicator is turned off."); return false; } if(i_barsPeriod3<1) { Alert(name,(isRussianLang)? ": третье количество баров для расчета показаний индикатора менее 1. Индикатор отключен." : ": the third amount of bars for calculate the indicator values is less then 1. The indicator is turned off."); return false; } if(i_findExtInterval<1) { Alert(name,(isRussianLang)? ": интервал поиска экстремума цены должен быть более нуля баров. Индикатор отключен." : ": the interval of search of price extremum must be greater than zero bars. The indicator is turned off."); return false; } return (true); } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Defining the current TF name | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ string GetCurrentTFName() { switch(_Period) { case PERIOD_M1: return "M1"; case PERIOD_M5: return "M5"; case PERIOD_M15: return "M15"; case PERIOD_M30: return "M30"; case PERIOD_H1: return "H1"; case PERIOD_H4: return "H4"; case PERIOD_D1: return "D1"; case PERIOD_W1: return "W1"; case PERIOD_MN1: return "MN1"; } return "U/D"; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Binding the indicator buffers with arrays | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ bool BuffersBind() { if(i_indicatorType==WILLIAM_BLAU) IndicatorBuffers(2); string name=WindowExpertName(); bool isRussianLang=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian"); if(!SetIndexBuffer(0,g_indValues)) { Alert(name,(isRussianLang)? ": ошибка связывания массивов с буферами индикатора. Ошибка №"+IntegerToString(GetLastError()) : ": error of binding of the arrays and the indicator buffers. Error N"+IntegerToString(GetLastError())); return false; } if(i_indicatorType==WILLIAM_BLAU) if(!SetIndexBuffer(1,g_tempBuffer)) { Alert(name,(isRussianLang)? ": ошибка связывания массивов с буферами индикатора. Ошибка №"+IntegerToString(GetLastError()) : ": error of binding of the arrays and the indicator buffers. Error N"+IntegerToString(GetLastError())); return false; } SetIndexStyle(0,DRAW_LINE); if(i_indicatorType==WILLIAM_BLAU) SetIndexStyle(1,DRAW_NONE); g_indName="DivViewer at "+GetBaseIndicatorName()+IntegerToString(GetTickCount()); IndicatorShortName(g_indName); return true; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Defining the name of the base indicator | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ string GetBaseIndicatorName() { if(i_indicatorType==CUSTOM) return i_customName + " (" + DoubleToString(i_customParam1, 1) + ", " + DoubleToString(i_customParam2, 1) + ", " + DoubleToString(i_customParam3, 1) + ") "; return EnumToString(i_indicatorType) + " (" + IntegerToString(i_barsPeriod1) + ", " + IntegerToString(i_barsPeriod2) + ", " + IntegerToString(i_barsPeriod3) + ") "; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ void OnDeinit(const int reason) { DeleteAllObjects(); } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Deleting of all graphical objects | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ void DeleteAllObjects() { string prefix=PREFIX+IntegerToString(g_indSubWindow); int strLen= StringLen(prefix); for(int i = ObjectsTotal()-1; i>= 0; i--) if(StringSubstr(ObjectName(i),0,strLen)==prefix) ObjectDelete(ObjectName(i)); } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Displaying the trend line | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ void ShowTrendLine(int subWindow,datetime time1,double price1,datetime time2,double price2,string toolTip,color clr) { string name=PREFIX+IntegerToString(g_indSubWindow)+IntegerToString(subWindow)+IntegerToString(time1)+IntegerToString(time2); if(ObjectFind(0,name)<0) { ObjectCreate(0,name,OBJ_TREND,subWindow,time1,price1,time2,price2); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetInteger(0,name,OBJPROP_BACK,false); ObjectSetInteger(0,name,OBJPROP_WIDTH,1); ObjectSetInteger(0,name,OBJPROP_RAY,false); ObjectSetInteger(0,name,OBJPROP_HIDDEN,true); ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false); ObjectSetString(0,name,OBJPROP_TOOLTIP,toolTip); return; } ObjectMove(0,name,0,time1,price1); ObjectMove(0,name,1,time2,price2); ObjectSetInteger(0,name,OBJPROP_COLOR,clr); ObjectSetString(0,name,OBJPROP_TOOLTIP,toolTip); } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Determination of bar index which needed to recalculate | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ int GetRecalcIndex(int &total,const int ratesTotal,const int prevCalculated) { total=ratesTotal-1; if(i_indBarsCount>0 && i_indBarsCount=Bars) return 0.0; if(i_marketAppliedPrice==MARKET_APPLIED_PRICE_CLOSE) return Close[barIndex]; if(extremumType==EXTREMUM_TYPE_MAX) return High[barIndex]; return Low[barIndex]; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Determining of the extremum type at the spesified element of speciefied array | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ENUM_EXTREMUM_TYPE GetBufferExtremum(int barIndex,int total,const double &buffer[]) { if(barIndex+2>=total || barIndex<0) { Print("Possible error! ",__FUNCTION__,", barIndex = ",barIndex,", total bars = ",total); return EXTREMUM_TYPE_NONE; } double valueRight=buffer[barIndex]; double valueCenter=buffer[barIndex+1]; double valueLeft=buffer[barIndex+2]; if(valueCentervalueRight && valueCenter>valueLeft) return EXTREMUM_TYPE_MAX; return EXTREMUM_TYPE_NONE; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Determining whether an extremum of price at a specified bar | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ENUM_EXTREMUM_TYPE GetMarketExtremum(int barIndex,int total,ENUM_EXTREMUM_TYPE desiredExtremum) { if(i_marketAppliedPrice==MARKET_APPLIED_PRICE_HIGHLOW) { if(desiredExtremum!=EXTREMUM_TYPE_MIN && GetBufferExtremum(barIndex,total,High)==EXTREMUM_TYPE_MAX) return EXTREMUM_TYPE_MAX; if(desiredExtremum!=EXTREMUM_TYPE_MAX && GetBufferExtremum(barIndex,total,Low)==EXTREMUM_TYPE_MIN) return EXTREMUM_TYPE_MIN; return EXTREMUM_TYPE_NONE; } return GetBufferExtremum(barIndex, total, Close); } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Calculating the coefficients K and B of the equation straight line through specified points | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ double GetBAndKKoefs(int x1,double y1,int x2,double y2,double &kKoef) { if(x2==x1) return EMPTY_VALUE; kKoef=(y2-y1)/(x2-x1); return y1 - kKoef * x1; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Calculating the price by values of base indicator or by market price | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ double GetIndOrMarketPrice(ENUM_EXTREMUM_TYPE extremumType,ENUM_PRICE_TYPE priceType,int barIndex) { if(priceType==PRICE_TYPE_INDICATOR) return g_indValues[barIndex]; return GetMarketPrice(barIndex, extremumType); } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Is break the divergence line? | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ bool IsDivLineBreak(ENUM_EXTREMUM_TYPE extremumType,ENUM_PRICE_TYPE priceType,int leftBarIndex,int rightBarIndex) { double kKoef; double bKoef=GetBAndKKoefs(rightBarIndex,GetIndOrMarketPrice(extremumType,priceType,rightBarIndex),leftBarIndex,GetIndOrMarketPrice(extremumType,priceType,leftBarIndex),kKoef); if(bKoef==EMPTY_VALUE) return true; for(int i=leftBarIndex-1; i>rightBarIndex; i--) { double lineValue = kKoef * i + bKoef; double basePrice = GetIndOrMarketPrice(extremumType, priceType, i); if(extremumType==EXTREMUM_TYPE_MAX && lineValuebasePrice) return true; } return false; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| The class definition of divergence | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ string GetDivergenceType(double indRightValue,double indLeftValue,double priceRightValue,double priceLeftValue,ENUM_EXTREMUM_TYPE extType) { if(extType==EXTREMUM_TYPE_MIN) { if(indRightValue>indLeftValue && priceRightValueindLeftValue && MathAbs(priceRightValue-priceLeftValue)<_Point/10) return TITLE_CLASS_B; if(MathAbs(indRightValue-indLeftValue)<_Point/100 && priceRightValuepriceLeftValue) return TITLE_CLASS_A; if(indRightValuepriceLeftValue) return TITLE_CLASS_C; return TITLE_CLASS_H; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| The class definition of divergence, the need for its display and color of display | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ bool IsShowDivergence(double indRightValue,double indLeftValue,double priceRightValue,double priceLeftValue,ENUM_EXTREMUM_TYPE extType,string &divClass,color &clr) { divClass=GetDivergenceType(indRightValue,indLeftValue,priceRightValue,priceLeftValue,extType); if((i_showClassA==NO && divClass==TITLE_CLASS_A) || (i_showClassB == NO && divClass == TITLE_CLASS_B) || (i_showClassC == NO && divClass == TITLE_CLASS_C) || (i_showHidden == NO && divClass == TITLE_CLASS_H)) return false; if(divClass==TITLE_CLASS_A) clr=(extType==EXTREMUM_TYPE_MIN) ? i_bullsDivAColor : i_bearsDivAColor; if(divClass==TITLE_CLASS_B) clr=(extType==EXTREMUM_TYPE_MIN) ? i_bullsDivBColor : i_bearsDivBColor; if(divClass==TITLE_CLASS_C) clr=(extType==EXTREMUM_TYPE_MIN) ? i_bullsDivCColor : i_bearsDivCColor; if(divClass==TITLE_CLASS_H) clr=(extType==EXTREMUM_TYPE_MIN) ? i_bullsDivHColor : i_bearsDivHColor; return true; } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Sound and Push-notifications of divergence | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ void SignalOnDivergence(string text) { static datetime lastSignal=0; if(lastSignal>=Time[0]) return; lastSignal=Time[0]; if(i_isAlert) Alert(_Symbol,", ",g_tfName,": ",text); if(i_isPush) SendNotification(_Symbol+", "+g_tfName+": "+text); } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Determining the divergence existence and its showing | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ void DefineAndShowDivergence(ENUM_EXTREMUM_TYPE extremumType,int rightBarIndex,int leftBarIndex,int priceRightBarIndex,int priceLeftBarIndex) { double indRightValue= g_indValues[rightBarIndex]; double indLeftValue = g_indValues[leftBarIndex]; double priceRightValue= GetMarketPrice(priceRightBarIndex,extremumType); double priceLeftValue = GetMarketPrice(priceLeftBarIndex,extremumType); // Checking the divergence existence if((indRightValue>indLeftValue && priceRightValue>priceLeftValue) || (indRightValue0; i--) g_tempBuffer[i]=iMA(NULL,0,i_barsPeriod2,0,MODE_EMA,i_indAppliedPrice,i)-iMA(NULL,0,i_barsPeriod1,0,MODE_EMA,i_indAppliedPrice,i); for(int i=limit; i>0; i--) { g_indValues[i]=iMAOnArray(g_tempBuffer,0,i_barsPeriod3,0,MODE_EMA,i); if(i+i_divergenceDepth+i_findExtInterval+2>=total) continue; ProcessBar(i,total); } } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Displaying of indicators values | //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ void ShowIndicatorData(int limit,int total) { if(i_indicatorType==WILLIAM_BLAU) { CalculateDataByWilliamBlau(limit,total); return; } for(int i=limit; i>0; i--) { g_indValues[i]=GetBaseIndicatorValue(i); if(i+i_divergenceDepth+i_findExtInterval+2>=total) continue; ProcessBar(i,total); } } //+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| 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[]) { if(!g_activate) return rates_total; if(g_indSubWindow<0) { g_indSubWindow=WindowFind(g_indName); if(g_indSubWindow<0) return 0; } int total; int limit=GetRecalcIndex(total,rates_total,prev_calculated); ShowIndicatorData(limit,total); WindowRedraw(); return rates_total; } //+------------------------------------------------------------------+