
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property version     "1.0"
#property description "by Morsche"
#property strict

#include <stdlib.mqh>

//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 clrFireBrick
#property indicator_color2 clrRoyalBlue

//--- input parameters
extern double renko   = 100.0; // renko size (point)
extern double percent = 0.0;   // shift %

//--- buffers
double buffer1[];
double buffer2[];

//--- global variables
string shortname;
double clac;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  custom indicator initialization function
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

int OnInit()
{
   //--- set global variables
   renko = NormalizeDouble(renko * _Point, _Digits);
   clac = 1;
   if (0 < percent) clac = (percent / 100);

   //--- checking input data
   if (_Point >= renko) return (INIT_PARAMETERS_INCORRECT); // INIT_FAILED

   //--- indicator buffers mapping
   IndicatorBuffers(2);
   SetIndexBuffer(0, buffer1); SetIndexEmptyValue(0, 0.0);
   SetIndexBuffer(1, buffer2); SetIndexEmptyValue(1, 0.0);

   //--- drawing settings
   IndicatorDigits(_Digits);
   SetIndexStyle(0, DRAW_LINE); SetIndexLabel(0, "open");
   SetIndexStyle(1, DRAW_LINE); SetIndexLabel(1, "close");

   //--- set short name
   shortname = "renko separate window (" + DoubleToString(renko, _Digits) + ")";
   IndicatorShortName(shortname);

   //--- initialization done
   return (INIT_SUCCEEDED);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  custom indicator deinitialization function
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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[])
{
   //---
   static double pClose, pHigh, pLow, pOpen;

   if (!prev_calculated)
   {
      pOpen  = NormalizeDouble(floor(close[rates_total-1] / renko) * renko, _Digits);
      pLow   = pOpen;
      pClose = pHigh = NormalizeDouble(pLow + renko, _Digits);
      PushBuffer(pOpen, pClose, rates_total);
   }

   //---
   for (int i=rates_total-(prev_calculated?prev_calculated:2);0<=i;i--)
   {
      bool uptrend = high[i]+low[i] > high[i+1]+low[i+1];

      while (uptrend && (low[i] < pLow - clac * renko || CompareDoubles(low[i], pLow  - clac * renko)))
      {
         pOpen  = pHigh = NormalizeDouble(pHigh - clac * renko, _Digits);
         pClose = pLow  = NormalizeDouble( pLow - clac * renko, _Digits);
         PushBuffer(pOpen, pClose, rates_total);
      }

      while (high[i] > pHigh + clac * renko || CompareDoubles(high[i], pHigh + clac * renko))
      {
         pClose = pHigh = NormalizeDouble(pHigh + clac * renko, _Digits);
         pOpen  = pLow  = NormalizeDouble( pLow + clac * renko, _Digits);
         PushBuffer(pOpen, pClose, rates_total);
      }

      while (!uptrend && (low[i] < pLow - clac * renko || CompareDoubles(low[i], pLow  - clac * renko)))
      {
         pOpen  = pHigh = NormalizeDouble(pHigh - clac * renko, _Digits);
         pClose = pLow  = NormalizeDouble( pLow - clac * renko, _Digits);
         PushBuffer(pOpen, pClose, rates_total);
      }
   }

   //---
   return (rates_total);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  subroutines and functions
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void PushBuffer(double open, double close, int rates_total)
{
   static double O[], C[];
   static int counted_bars = 0;
              counted_bars ++;

   if (ArraySize(O) < counted_bars)
   {
      ArraySetAsSeries(O, false);
      ArraySetAsSeries(C, false);
      //----
      ArrayResize(O, counted_bars);
      ArrayResize(C, counted_bars);
      //----
      ArraySetAsSeries(O, true);
      ArraySetAsSeries(C, true);
   }

   O[0] = open;
   C[0] = close;

   ArrayCopy(buffer1, O, 0, 0, fmin(counted_bars, rates_total));
   ArrayCopy(buffer2, C, 0, 0, fmin(counted_bars, rates_total));

   return;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
