Hey everyone!
I've hit a snag with my current EA. I've found iCustom to be a bit of a pain to work with when you need to call an indicator twice for different timeframes, and have decided to simplify my indicators into functions I can call inside the program. The Donchian channels were easy to convert to a function so I pushed ahead with a Choppiness Index. I can't seem to arrive at the same value as the indicator though. Here's my attempt as well as the logic flow:
/*Choppiness Index Formula
Sum True Range for the past n periods.
Divide by the result of the following two steps:
Calculate the lowest TrueLow for n periods.
Subtract from the highest TrueHigh for n periods.
Calculate Log10 of the result then Multiply by 100.
Divide the result by Log10 of n.*/
//double ChoppinessIndex(string symbol, ENUM_TIMEFRAMES timeframe, int lookback){
double CI(double InpChoPeriod){
for(int i = 0; i < inpChoPeriod+1;i++){
double AddATR = iATR(_Symbol,PERIOD_H1,1);
double SumATR = 0;
SumATR = AddATR + SumATR;
double HH = iHigh(_Symbol,PERIOD_H1,iHighest(_Symbol,PERIOD_H1,MODE_HIGH,inpChoPeriod,0));
double LL = iLow(_Symbol,PERIOD_H1,iLowest(_Symbol,PERIOD_H1,MODE_LOW,inpChoPeriod,0));
if(i == inpChoPeriod){
double Chop = 100*(log10(SumATR/(HH-LL)) / log10(InpChoPeriod));
return Chop;
}
}
return 0;
}
For reference, this is the indicator who's values I cannot match:
//------------------------------------------------------------------
#property copyright "© mladen, 2018"
#property version "1.00"
#property description "Choppiness index"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_label1 "Choppiness index"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrCrimson
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//
//---
//
input int inpChoPeriod = 14; // Choppiness index period
double csi[];
//------------------------------------------------------------------
//
//------------------------------------------------------------------
int OnInit()
{
SetIndexBuffer(0,csi,INDICATOR_DATA);
IndicatorSetString(INDICATOR_SHORTNAME,"Choppiness index ("+string(inpChoPeriod)+")");
return(INIT_SUCCEEDED);
}
//
//---
//
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[])
{
double _log = MathLog(inpChoPeriod)/100.00;
for (int i=(int)MathMax(prev_calculated-1,0); i<rates_total; i++)
{
double atrSum = 0.00;
double maxHig = high[i];
double minLow = low[i];
for (int k = 0; k<inpChoPeriod && (i-k-1)>=0; k++)
{
atrSum += MathMax(high[i-k],close[i-k-1])-MathMin(low[i-k],close[i-k-1]);
maxHig = MathMax(maxHig,MathMax(high[i-k],close[i-k-1]));
minLow = MathMin(minLow,MathMin( low[i-k],close[i-k-1]));
}
csi[i] = (maxHig!=minLow) ? MathLog(atrSum/(maxHig-minLow))/_log : 0;
}
return(rates_total);
}
Any advice would be greatly appreciated!