//+------------------------------------------------------------------ #property copyright "mladen" #property link "mladenfx@gmail.com" #property description "Step averages" //+------------------------------------------------------------------ #property indicator_chart_window #property indicator_buffers 3 #property indicator_plots 1 #property indicator_label1 "Step average" #property indicator_type1 DRAW_COLOR_LINE #property indicator_color1 clrDarkGray,clrDodgerBlue,clrSandyBrown #property indicator_width1 2 // //--- input parameters // input int inpMaPeriod = 14; // Average period (<=1 for no average calculation) input ENUM_MA_METHOD inpMaType = MODE_EMA; // Average type input ENUM_APPLIED_PRICE inpPrice = PRICE_CLOSE; // Price input double inpStepSize = 2.5; // Step size (in pips) // //--- buffers and global variables declarations // double val[],valc[],average[],¹_stepSize; int ¹_hma,¹_maPeriod; //------------------------------------------------------------------ // Custom indicator initialization function //------------------------------------------------------------------ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,val,INDICATOR_DATA); SetIndexBuffer(1,valc,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,average,INDICATOR_CALCULATIONS); //--- ¹_stepSize = inpStepSize*_Point*MathPow(10,_Digits%2); ¹_maPeriod = MathMax(inpMaPeriod,1); ¹_hma = iMA(_Symbol,0,¹_maPeriod,0,inpMaType,inpPrice); if (!_checkHandle(¹_hma,"Moving average")) return(INIT_FAILED); //--- IndicatorSetString(INDICATOR_SHORTNAME,"Step average ("+(string)inpMaPeriod+","+(string)inpStepSize+")"); return (INIT_SUCCEEDED); } void OnDeinit(const int reason) { } //------------------------------------------------------------------ // 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[]) { int _copyCount = rates_total-prev_calculated+1; if (_copyCount>rates_total) _copyCount=rates_total; if (CopyBuffer(¹_hma,0,0,_copyCount,average) !=_copyCount) { Comment("Error copying average"); return(prev_calculated); } // //--- // int i = (prev_calculated>0 ? prev_calculated-1 : 0); for (; i0) ? (val[i]>val[i-1]) ? 1 : (val[i]0 && stepSize>0) { int _indP = (i-1)%_stepValRingSize; double _diff = value-_stepValWork[_indP][_steps]; _stepValWork[_indC][_steps] = _stepValWork[_indP][_steps]+((_diff-stepSize) ? 0 : (int)(_diff/stepSize)*stepSize); } else _stepValWork[_indC][_steps] = (stepSize>0) ? MathRound(value/stepSize)*stepSize : value; return(_stepValWork[_indC][_steps]); #undef _steps } // //--- // bool _checkHandle(int _handle, string _description) { static int _handles[]; int _size = ArraySize(_handles); bool _answer = (_handle!=INVALID_HANDLE); if (_answer) { ArrayResize(_handles,_size+1); _handles[_size]=_handle; } else { for (int i=_size-1; i>=0; i--) IndicatorRelease(_handles[i]); ArrayResize(_handles,0); Alert(_description+" initialization failed"); } return(_answer); } //+------------------------------------------------------------------+