124 lines
9.3 KiB
Plaintext
124 lines
9.3 KiB
Plaintext
//+------------------------------------------------------------------
|
|
#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 (; i<rates_total && !_StopFlag; i++)
|
|
{
|
|
if (average[i]==EMPTY_VALUE) average[i] = close[i];
|
|
val[i] = iStepVal(average[i],¹_stepSize,i);
|
|
valc[i] = (i>0) ? (val[i]>val[i-1]) ? 1 : (val[i]<val[i-1]) ? 2 : valc[i-1] : 0 ;
|
|
}
|
|
return (i);
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// custom functions
|
|
//------------------------------------------------------------------
|
|
//
|
|
//---
|
|
//
|
|
#define _stepValInstances 1
|
|
#define _stepValInstancesSize 1
|
|
#define _stepValRingSize 6
|
|
double _stepValWork[_stepValRingSize][_stepValInstances*_stepValInstancesSize];
|
|
//
|
|
//---
|
|
//
|
|
double iStepVal(double value, double stepSize, int i, int instance=0)
|
|
{
|
|
int _indC = (i)%_stepValRingSize;
|
|
int _inst = instance*_stepValInstancesSize;
|
|
#define _steps _inst
|
|
|
|
//
|
|
//---
|
|
//
|
|
|
|
if (i>0 && stepSize>0)
|
|
{
|
|
int _indP = (i-1)%_stepValRingSize;
|
|
double _diff = value-_stepValWork[_indP][_steps];
|
|
_stepValWork[_indC][_steps] = _stepValWork[_indP][_steps]+((_diff<stepSize && _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);
|
|
}
|
|
//+------------------------------------------------------------------+
|