//--------------------------------------------------------------------------------------------------------------------- #property copyright "© mladen, 2022" #property link "mladenfx@gmail.com" //--------------------------------------------------------------------------------------------------------------------- #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 1 #property indicator_label1 "SmoothStep" #property indicator_type1 DRAW_COLOR_LINE #property indicator_color1 clrDarkGray,clrDodgerBlue,clrCoral #property indicator_width1 2 #property indicator_level1 0.2 #property indicator_level2 0.8 #property strict // // // input int inpPeriod = 32; // Period enum enPrices { pr_close, // Close pr_open, // Open pr_high, // High pr_low, // Low pr_median, // Median pr_typical, // Typical pr_weighted, // Weighted pr_lowhigh, // Low/High/Close }; input enPrices inpPrice = pr_close; // Price input int inpOrder = 1; // Order // // // double val[],valc[]; struct sGlobalStruct { int period; int order; }; sGlobalStruct global; //--------------------------------------------------------------------------------------------------------------------- // //--------------------------------------------------------------------------------------------------------------------- // // // int OnInit() { SetIndexBuffer(0,val ,INDICATOR_DATA); SetIndexBuffer(1,valc,INDICATOR_COLOR_INDEX); // // // global.period = MathMax(inpPeriod,1); global.order = MathMax(MathMin(inpOrder,16),0); // // // PlotIndexSetString(0,PLOT_LABEL,"SmoothStep "+(string)global.order+" order"); IndicatorSetString(INDICATOR_SHORTNAME,StringFormat("Smooth step (%i, order %i)",global.period,global.order)); 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; // // // static double m_lows[]; static int m_lowsSize = -1; if (m_lowsSize 0 && global.period>1) { int _minMaxPeriod = global.period-1; int _start = i-global.period+1; if(_start<0) { _start = 0; _minMaxPeriod = i+1; } m_work[i].prevmin = m_lows [ArrayMinimum(m_lows ,_start,_minMaxPeriod)]; m_work[i].prevmax = m_highs[ArrayMaximum(m_highs,_start,_minMaxPeriod)]; } else { m_work[i].prevmin = m_lows[i]; m_work[i].prevmax = m_highs[i]; } } double min = (m_work[i].prevmin < _pricel) ? m_work[i].prevmin : _pricel; double max = (m_work[i].prevmax > _priceh) ? m_work[i].prevmax : _priceh; double raw = (max!=min) ? (_price - min)/(max- min) : 0; double result = 0; for (int k = 0; k<=global.order; ++k) result += iPascalTriangle(-global.order-1, k) * iPascalTriangle(2 * global.order + 1, global.order - k) * MathPow(raw, global.order + k + 1); // // // val[i] = MathMin(MathMax(result,0),1.0); valc[i] = (i>0) ? (val[i]>val[i-1]) ? 1 : (val[i]