#property copyright   "Custom"
#property version     "5.3"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2

input int    TickPeriod  = 400;    // EMA-jakso (tikit)
input double StepPips    = 5.0;    // Steppi-koko pipseissä
input color  LineColor   = clrDodgerBlue;
input int    LineWidth   = 2;

double StepBuf[];   // Piirrettävä step-viiva
double MABuf[];     // EMA-arvo (sisäinen)
double NumBuf[];
double DenBuf[];

double gK, gK1, gPipSize;
string gLabel;

#define EMA_STEP(i) \
{ \
   double _v   = (double)Volume[(i)]; \
   NumBuf[(i)] = Close[(i)] * _v * gK + NumBuf[(i)+1] * gK1; \
   DenBuf[(i)] = _v * gK + DenBuf[(i)+1] * gK1; \
   MABuf[(i)]  = DenBuf[(i)] > 0.0 ? NumBuf[(i)] / DenBuf[(i)] : Close[(i)]; \
}

int OnInit()
{
   if(TickPeriod < 2)
   {
      Alert("TickPeriod on oltava vähintään 2");
      return(INIT_PARAMETERS_INCORRECT);
   }
   if(StepPips <= 0.0)
   {
      Alert("StepPips on oltava suurempi kuin 0");
      return(INIT_PARAMETERS_INCORRECT);
   }

   gK       = 2.0 / (TickPeriod + 1);
   gK1      = 1.0 - gK;

   // Tunnista pip-koko: 5-desimaalin parit käyttävät 0.00001, muut 0.0001
   // JPY-parit (esim. USDJPY) käyttävät 0.01 / 0.001
   gPipSize = Point;
   if(Digits == 5 || Digits == 3) gPipSize = Point * 10.0;

   gLabel = "Step Ticks MA(" + IntegerToString(TickPeriod) +
            ", " + DoubleToString(StepPips, 1) + " pip)";

   SetIndexBuffer(0, StepBuf);
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, LineWidth, LineColor);
   SetIndexLabel(0, gLabel);
   SetIndexEmptyValue(0, EMPTY_VALUE);

   SetIndexBuffer(1, MABuf);
   SetIndexStyle(1, DRAW_NONE);
   SetIndexEmptyValue(1, EMPTY_VALUE);

   SetIndexBuffer(2, NumBuf);
   SetIndexStyle(2, DRAW_NONE);
   SetIndexEmptyValue(2, 0.0);

   SetIndexBuffer(3, DenBuf);
   SetIndexStyle(3, DRAW_NONE);
   SetIndexEmptyValue(3, 0.0);

   IndicatorShortName(gLabel);
   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 == prev_calculated) return(rates_total);
   if(rates_total < TickPeriod)       return(0);

   double stepSize = StepPips * gPipSize;
   int    start;

   // ── TÄYSI ALUSTUS ──────────────────────────────────────────────────────────
   if(prev_calculated <= 0 || prev_calculated > rates_total)
   {
      int oldest = rates_total - 1;

      for(int i = oldest; i > oldest - TickPeriod; i--)
      {
         StepBuf[i] = EMPTY_VALUE;
         MABuf[i]   = EMPTY_VALUE;
         NumBuf[i]  = 0.0;
         DenBuf[i]  = 0.0;
      }

      int seed = oldest - TickPeriod;
      if(seed < 0) seed = 0;

      double numSum = 0.0, denSum = 0.0;
      for(int i = seed; i <= oldest; i++)
      {
         double v  = (double)Volume[i];
         numSum   += Close[i] * v;
         denSum   += v;
      }
      NumBuf[seed]  = denSum > 0.0 ? numSum / denSum : Close[seed];
      DenBuf[seed]  = denSum > 0.0 ? 1.0 : 0.0;
      MABuf[seed]   = NumBuf[seed];
      StepBuf[seed] = MABuf[seed];

      start = seed - 1;
   }
   else
   {
      start = prev_calculated - 2;
      if(start < 0) start = 0;
   }

   // ── PÄÄSILMUKKA ────────────────────────────────────────────────────────────
   for(int i = start; i >= 0; i--)
   {
      EMA_STEP(i)

      if(i == 0)
      {
         // Live-baari: näytä oma EMA-arvo reaaliajassa, ei step-logiikkaa
         StepBuf[0] = MABuf[0];
      }
      else
      {
         // Suljettu baari: step-ehto
         // Edellinen step-arvo on StepBuf[i+1]
         double prevStep = StepBuf[i + 1];
         double currMA   = MABuf[i + 1];   // suljetun baariston EMA (i+1 = juuri sulkeutunut)

         if(prevStep == EMPTY_VALUE)
         {
            // Ei vielä step-arvoa – käynnistä seuranta
            StepBuf[i] = currMA;
         }
         else if(MathAbs(currMA - prevStep) >= stepSize)
         {
            // EMA on liikkunut vähintään StepPips → uusi step
            StepBuf[i] = currMA;
         }
         else
         {
            // Liike liian pieni → pidä edellinen step-taso
            StepBuf[i] = prevStep;
         }
      }
   }

   return(rates_total);
}