#property strict #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 1 #property indicator_label1 "eATR" #property indicator_type1 DRAW_LINE #property indicator_color1 clrOrange #property indicator_style1 STYLE_SOLID #property indicator_width1 2 input int AtrPeriod = 14; // 描画用 double EatrBuffer[]; // 計算用(TR) double TrBuffer[]; int OnInit() { SetIndexBuffer(0, EatrBuffer, INDICATOR_DATA); SetIndexBuffer(1, TrBuffer, INDICATOR_CALCULATIONS); IndicatorSetString(INDICATOR_SHORTNAME, StringFormat("eATR(%d)", AtrPeriod)); PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 1); 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[] ) { if(rates_total < 2 || AtrPeriod <= 0) return 0; // 配列方向を oldest -> newest に統一 ArraySetAsSeries(high, false); ArraySetAsSeries(low, false); ArraySetAsSeries(close, false); ArraySetAsSeries(EatrBuffer, false); ArraySetAsSeries(TrBuffer, false); double alpha = 2.0 / (AtrPeriod + 1.0); int start = 0; if(prev_calculated > 1) start = prev_calculated - 1; // 直前バーから再計算 for(int i = start; i < rates_total; i++) { // --- True Range if(i == 0) { TrBuffer[i] = high[i] - low[i]; EatrBuffer[i] = TrBuffer[i]; // 初期値 } else { double tr1 = high[i] - low[i]; double tr2 = MathAbs(high[i] - close[i - 1]); double tr3 = MathAbs(low[i] - close[i - 1]); TrBuffer[i] = MathMax(tr1, MathMax(tr2, tr3)); // --- EMA(TR) EatrBuffer[i] = alpha * TrBuffer[i] + (1.0 - alpha) * EatrBuffer[i - 1]; } } return rates_total; }