//+------------------------------------------------------------------+
//|                                            Double Stochastic.mq4 |
//|                                                           mladen |
//+------------------------------------------------------------------+
#property copyright "mladen"
#property link      ""

#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 2
#property indicator_color1 Green
#property indicator_color2 Red
#property indicator_style2 STYLE_DOT

//
//
// PriceField
//       0 - low/high
//       1 - close/close
//
//

extern int    KPeriod    =34;
extern int    DPeriod    = 1;
extern int    Slowing    = 1;
extern int    MAMode     = 2;
extern int    PriceField = 0;    
extern bool   Double     = false;
extern bool   ShowLevels = true; 
extern double Level1     = 80;
extern double Level2     = 50;
extern double Level3     = 20;
extern color  zoneColor  = C'30,33,36';

//
//
//
//
//

double MainBuffer[];
double SignalBuffer[];
double HighesBuffer[];
double LowesBuffer[];
double MainBuffera[];
double HighesBuffera[];
double LowesBuffera[];
double Prices[];
string ShortName;


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int init()
{
   IndicatorBuffers(8);
   SetIndexBuffer(0, MainBuffer);
   SetIndexBuffer(1, SignalBuffer);
   SetIndexBuffer(2, HighesBuffer);
   SetIndexBuffer(3, LowesBuffer);
   SetIndexBuffer(4, HighesBuffera);
   SetIndexBuffer(5, LowesBuffera);
   SetIndexBuffer(6, MainBuffera);
   SetIndexBuffer(7, Prices);

   ShortName=MakeUniqueName("D.stochastic "," ("+KPeriod+","+DPeriod+","+Slowing+")");
   IndicatorShortName(ShortName);
   SetIndexLabel(0,"Stochastic");
   SetIndexLabel(1,"Signal");
   return(0);
}
int deinit()
{
   DeleteBounds();
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

int start()
{
   double crossing;
   int    counted_bars=IndicatorCounted();
   int    i,k,limit;

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
         limit = MathMin(Bars - counted_bars,Bars-KPeriod);

   //
   //
   //
   //
   //
   
   for(i = limit; i >= 0 ; i--)
   {
      if (PriceField==0)
         {
            LowesBuffer[i] = Low[ArrayMinimum(Low ,KPeriod,i)];
            HighesBuffer[i]=High[ArrayMaximum(High,KPeriod,i)];
         }
      else         
         {
            Prices[i] = iCustom(NULL,0,"T3 basic",14,PRICE_CLOSE,0.618,false,0,i);
            LowesBuffer[i] =Prices[ArrayMinimum(Prices,KPeriod,i)];
            HighesBuffer[i]=Prices[ArrayMaximum(Prices,KPeriod,i)];
         }
      
         //
         //
         //
         //
         //
      
         double sumlow  = 0.0;
         double sumhigh = 0.0;
            for(k=(i+Slowing-1);k>=i;k--)
            {
               if (PriceField==0)
                     sumlow  += Close[k] -LowesBuffer[k];
               else  sumlow  += Prices[k]-LowesBuffer[k];
               sumhigh += HighesBuffer[k]-LowesBuffer[k];
            }
            if(sumhigh==0.0) 
                  MainBuffera[i] = 100.0;
            else  MainBuffera[i] = sumlow/sumhigh*100.0;
   }
   
   //
   //
   //
   //
   //
   
   if (Double)
   {
      for(i = limit; i >= 0 ; i--)
      {
         LowesBuffera[i] =MainBuffera[ArrayMinimum(MainBuffera,KPeriod,i)];
         HighesBuffera[i]=MainBuffera[ArrayMaximum(MainBuffera,KPeriod,i)];
      
         //
         //
         //
         //
         //
      
         sumlow  = 0.0;
         sumhigh = 0.0;
            for(k=(i+Slowing-1);k>=i;k--)
            {
               sumlow  += MainBuffera[k]  -LowesBuffera[k];
               sumhigh += HighesBuffera[k]-LowesBuffera[k];
            }
            if(sumhigh==0.0) 
                  MainBuffer[i] = 100.0;
            else  MainBuffer[i] = sumlow/sumhigh*100.0;
      }
   }      
   else
   {
      for(i=limit; i>=0; i--) MainBuffer[i] = MainBuffera[i];
   }      

   //
   //
   //
   //
   //
         
   for(i=0; i<limit; i++) SignalBuffer[i]=iMAOnArray(MainBuffer,0,DPeriod,0,MAMode,i);
   if (ShowLevels) UpdateBounds();
   
   //
   //
   //
   //
   //
   
   return(0);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

string MakeUniqueName(string first, string rest)
{
   string result = first+(MathRand()%1001)+rest;

   while (WindowFind(result)> 0)
          result = first+(MathRand()%1001)+rest;
   return(result);
}


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

void DeleteBounds()
{
   ObjectDelete(ShortName+"-1");
   ObjectDelete(ShortName+"-2");
   ObjectDelete(ShortName+"-3");
}
void UpdateBounds()
{
   if (Level1 > 0) SetUpBound(ShortName+"-1",100        ,Level1);
   if (Level2 > 0) SetUpBound(ShortName+"-2",Level2*1.01,Level2*0.99);
   if (Level3 > 0) SetUpBound(ShortName+"-3",Level3     ,       0.00);
}
void SetUpBound(string name, double up, double down)
{
   if (ObjectFind(name) == -1)
      {
         ObjectCreate(name,OBJ_RECTANGLE,WindowFind(ShortName),0,0);
         ObjectSet(name,OBJPROP_PRICE1,up);
         ObjectSet(name,OBJPROP_PRICE2,down);
         ObjectSet(name,OBJPROP_COLOR,zoneColor);
         ObjectSet(name,OBJPROP_BACK,true);
         ObjectSet(name,OBJPROP_TIME1,iTime(NULL,0,Bars-1));
      }
   if (ObjectGet(name,OBJPROP_TIME2) != iTime(NULL,0,0))
       ObjectSet(name,OBJPROP_TIME2,    iTime(NULL,0,0));
}


