//------------------------------------------------------------------------------------------------------------------------ #property copyright "© mladen, 2023" #property link "mladenfx@gmail.com" #property description "Momentum deviation bands" #property version "1.00" //------------------------------------------------------------------------------------------------------------------------ #property indicator_chart_window #property indicator_buffers 3 #property indicator_plots 3 #property indicator_label1 "Upper band" #property indicator_type1 DRAW_LINE #property indicator_color1 clrLimeGreen #property indicator_style1 STYLE_DASHDOTDOT #property indicator_label2 "Average" #property indicator_type2 DRAW_LINE #property indicator_color2 clrDarkGray #property indicator_label3 "Lower band" #property indicator_type3 DRAW_LINE #property indicator_color3 clrCoral #property indicator_style3 STYLE_DASHDOTDOT // // // input int inpPeriod = 30; // Period input double inpMultiplier = 2.0; // Deviations input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price // // // double val[],bandup[],banddn[]; struct sGlobalStruct { int period; }; sGlobalStruct global; //------------------------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------------------------ // // // int OnInit() { SetIndexBuffer(0,bandup,INDICATOR_DATA); SetIndexBuffer(1,val ,INDICATOR_DATA); SetIndexBuffer(2,banddn,INDICATOR_DATA); // // // global.period = MathMax(inpPeriod,1); IndicatorSetString(INDICATOR_SHORTNAME,StringFormat("Weighted deviation bands (%i,%.2f)",inpPeriod,inpMultiplier)); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { return; } //------------------------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------------------------ // // // 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 limit = (prev_calculated>0) ? prev_calculated-1 : 0; // // // for (int i=limit; i= period) { m_work.data[i].valueSum = m_work.data[i-1].valueSum + m_work.data[i].value - m_work.data[i-period].value; m_work.data[i].valueWeightSum = m_work.data[i-1].valueWeightSum - m_work.data[i-1].valueSum + m_work.data[i].value*(double)period; } else { period = i+1; m_work.weightSum = (double)period; m_work.data[i].valueWeightSum = (double)period*m_work.data[i].value; m_work.data[i].valueSum = m_work.data[i].value; // // // for(int k=1; k=k; k++) { double weight = period-k; m_work.weightSum += weight; m_work.data[i].valueWeightSum += m_work.data[i-k].value*weight; m_work.data[i].valueSum += m_work.data[i-k].value; } } // // // double mean = average = m_work.data[i].valueWeightSum/m_work.weightSum; double sums = 0; for (int k=0, weight=period; k=k; k++,weight--) { sums += (double)weight*(m_work.data[i-k].value-mean)*(m_work.data[i-k].value-mean); } // // // return(sqrt(sums/m_work.weightSum)); } //------------------------------------------------------------------------------------------------------------------------ // //------------------------------------------------------------------------------------------------------------------------ // // // template double iGetPrice(ENUM_APPLIED_PRICE tprice, type& open[], type& high[], type& low[], type& close[], int i) { switch(tprice) { case PRICE_CLOSE: return(close[i]); case PRICE_OPEN: return(open[i]); case PRICE_HIGH: return(high[i]); case PRICE_LOW: return(low[i]); case PRICE_MEDIAN: return((high[i]+low[i])/2.0); case PRICE_TYPICAL: return((high[i]+low[i]+close[i])/3.0); case PRICE_WEIGHTED: return((high[i]+low[i]+close[i]+close[i])/4.0); } return(0); }