//------------------------------------------------------------------
#property copyright   "mladen"
#property link        "mladenfx@gmail.com"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_buffers 2

//
//
//
//
//

extern string forSymbol            = "";
extern string MAPeriods            = "9;15;50;60;100;200";
extern int    MAMethod             = MODE_EMA;
extern int    MasWidth             = 0;
extern int    MasStyle             = STYLE_SOLID;
extern int    AppliedPrice         = PRICE_CLOSE;
extern bool   AllVisible           = false;
extern color  Color1               = PaleVioletRed;
extern color  Color2               = PaleVioletRed;
extern color  Color3               = PaleVioletRed;
extern color  Color4               = DeepSkyBlue;
extern color  Color5               = DeepSkyBlue;
extern color  Color6               = DeepSkyBlue;
extern color  Color7               = PaleVioletRed;
extern color  Color8               = PaleVioletRed;
extern color  Color9               = PaleVioletRed;
extern color  Color10              = DeepSkyBlue;
extern color  Color11              = DeepSkyBlue;
extern color  Color12              = DeepSkyBlue;
extern string __                   = "Chose timeframes";
extern string timeFrames           = "M5;M15;M30;H1;H4;D1";
extern int    barsPerTimeFrame     = 50;
extern string UniqueID             = "All time frames Guppy";
extern bool   shiftRight           = false;
extern bool   currentFirst         = false; 
extern bool   candlesAsBack        = true;
extern int    BodyWidth            = 4;
extern color  BodyUpColor          = Green; 
extern color  BodyDownColor        = Red; 
extern color  WickColor            = Gray; 
extern color  txtColor             = DimGray; 
extern color  separatorColor       = DimGray; 

//
//
//
//
//
//

double ExtMapBuffer7[];
double ExtMapBuffer8[];

//
//
//
//
//

string shortName;
string labels[];
int    periods[];
double mins[];
double maxs[];
int    Shift; 
int    prices;
int    window;
int    maPeriods[];


//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

void addMaPeriod(int period)
{
   if (period>1)
   {
      ArrayResize(maPeriods,ArraySize(maPeriods)+1);
                  maPeriods[ArraySize(maPeriods)-1] = period;
   }
}

//
//
//
//
//

int init()
{
      if (shiftRight) Shift = 1;
      else            Shift = 0;
      if (forSymbol == "") forSymbol=Symbol();
      
         barsPerTimeFrame = MathMax(barsPerTimeFrame,15);
         shortName = UniqueID+" "+forSymbol;
                     IndicatorShortName(shortName);
   
      //
      //
      //
      //
      //

      IndicatorBuffers(8);
      SetIndexBuffer(0,ExtMapBuffer7); SetIndexLabel(0,NULL); SetIndexStyle(0,DRAW_NONE);
      SetIndexBuffer(1,ExtMapBuffer8); SetIndexLabel(1,NULL); SetIndexStyle(1,DRAW_NONE);
         for (int i = 0; i<8; i++) SetIndexShift(i,Shift*(barsPerTimeFrame+1));
   
      //
      //
      //
      //
      //
      
      timeFrames = StringTrimLeft(StringTrimRight(timeFrames));
      if (StringSubstr(timeFrames,StringLen(timeFrames),1) != ";")
                       timeFrames = StringConcatenate(timeFrames,";");

         //
         //
         //
         //
         //                                   
            
         int s = 0;
         int time;
         i = StringFind(timeFrames,";",s);
         string current;
            while (i > 0)
            {
               current = StringSubstr(timeFrames,s,i-s);
               time    = stringToTimeFrame(current);
               if (time > 0) {
                     ArrayResize(labels ,ArraySize(labels)+1);
                     ArrayResize(periods,ArraySize(periods)+1);
                                 labels[ArraySize(labels)-1] = timeFrameToString(time); 
                                 periods[ArraySize(periods)-1] = time; }
                                 s = i + 1;
                                     i = StringFind(timeFrames,";",s);
            }
            ArrayResize(mins,ArraySize(periods));
            ArrayResize(maxs,ArraySize(periods));

      //
      //
      //
      //
      //
      
      MAPeriods = StringTrimLeft(StringTrimRight(MAPeriods));
      if (StringSubstr(MAPeriods,StringLen(MAPeriods),1) != ";")
                       MAPeriods = StringConcatenate(MAPeriods,";");

         //
         //
         //
         //
         //                                   
            
         
         s = 0;
         i = StringFind(MAPeriods,";",s);
         while (i > 0)
         {
            current = StringSubstr(MAPeriods,s,i-s);
            int cPeriod = StrToInteger(current); addMaPeriod(cPeriod);
                s = i + 1;
                    i = StringFind(MAPeriods,";",s);
         }
      
      //
      //
      //
      //
      //

      if(currentFirst)
         for (i=1;i<ArraySize(periods);i++)
         if (Period()==periods[i])
            {
               string tmpLbl = labels[i];
               int    tmpPer = periods[i];
               
               //
               //
               //
               //
               //
               
               for (int k=i ;k>0; k--)
                     {
                        labels[k]  = labels[k-1];
                        periods[k] = periods[k-1];
                     }                     
               labels[0]  = tmpLbl;
               periods[0] = tmpPer;
            }
   return(0);
}

int deinit()
{
   for(int l=0;l<ArraySize(periods);l++) {
         ObjectDelete(shortName+l);
         ObjectDelete(shortName+l+"label");
      }         
   DeletePrices();      
   return(0);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

double work[][12];
int start()
{
     string separator;
     int    k=0;

     //
     //
     //
     //
     //
     
     window=WindowFind(shortName);
     DeletePrices();
            double min=Close[0];
            double max=Close[0];
            for(int p=0; p<ArraySize(periods);p++)
            {
               maxs[p] = iHigh(forSymbol,periods[p],iHighest(forSymbol,periods[p],MODE_HIGH,barsPerTimeFrame,0));
               mins[p] = iLow (forSymbol,periods[p], iLowest(forSymbol,periods[p],MODE_LOW ,barsPerTimeFrame,0));
                  max  = MathMax(max,maxs[p]);
                  min  = MathMin(min,mins[p]);
            }
            double range = max-min;
            double gmin  = min;
            double gmax  = max;
            int    totalMas = MathMin(ArraySize(maPeriods),12);
            
            //
            //
            //
            //
            //

            if (ArrayRange(work,0)!=Bars) ArrayResize(work,Bars);            
            for(p=0; p<ArraySize(periods);p++)
            {
               double prange = maxs[p]-mins[p];
               for(int i=0; i<barsPerTimeFrame;i++,k++)
               {
                  for (int m=0; m<totalMas; m++)
                  {
                     work[Bars-k-1][m] = min+(iMA(forSymbol,periods[p],maPeriods[m],0,MAMethod,AppliedPrice,i)-mins[p])*(range/prange); 
                                 gmin  = MathMin(gmin,work[Bars-k-1][m]);
                                 gmax  = MathMax(gmax,work[Bars-k-1][m]);
                  }                                             
                  DrawPrice(periods[p],i,k,min,range,mins[p],prange);
               }                           
               for (m=0; m<totalMas; m++) work[Bars-k-1][m] = EMPTY_VALUE; k++;
                           
               //
               //
               //
               //
               //
                           
               separator = shortName+p;
                  if(ObjectFind(separator)==-1)
                     ObjectCreate(separator,OBJ_TREND,window,0,0);
                        ObjectSet(separator,OBJPROP_TIME1,barTime(k-Shift*(barsPerTimeFrame+1)-1));
                        ObjectSet(separator,OBJPROP_TIME2,barTime(k-Shift*(barsPerTimeFrame+1)-1));
                        ObjectSet(separator,OBJPROP_COLOR ,separatorColor);
                        ObjectSet(separator,OBJPROP_WIDTH ,2);
               separator = shortName+p+"label";
                  if(ObjectFind(separator)==-1)
                     ObjectCreate(separator,OBJ_TEXT,window,0,0);
                        ObjectSet(separator,OBJPROP_TIME1,barTime(k-Shift*(barsPerTimeFrame)-1)+(barsPerTimeFrame*Period()*60)/2.0);
                        ObjectSetText(separator,forSymbol+" "+labels[p],9,"Arial bold",txtColor);
            }
      for (p=0; p<2; p++) SetIndexDrawBegin(p,Bars-k);
      
      //
      //
      //
      //
      //

      if (AllVisible) { min = gmin; max = gmax; } 
      for(p=0; p<ArraySize(periods);p++)
         {
            separator = shortName+p;
               ObjectSet(separator,OBJPROP_PRICE1,max*1.2);
               ObjectSet(separator,OBJPROP_PRICE2,min);
            separator = shortName+p+"label";
               ObjectSet(separator,OBJPROP_PRICE1,max);
         }
      for(i=k;i>=0 ;i--)
         {
            ExtMapBuffer7[i] = max;
            ExtMapBuffer8[i] = min;
            for (m=0; m<totalMas; m++) 
            {
               if (work[Bars-i-1][m] != EMPTY_VALUE && work[Bars-i-2][m] != EMPTY_VALUE) 
                     plot("zma"+m+":",work[Bars-i-1][m],work[Bars-i-2][m],i,i+1,getColor(m),MasWidth,MasStyle);
            }
         }
   return(0);
}


//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

color getColor(int i)
{
   switch (i+1)
   {
      case 1:  return(Color1);
      case 2:  return(Color2);
      case 3:  return(Color3);
      case 4:  return(Color4);
      case 5:  return(Color5);
      case 6:  return(Color6);
      case 7:  return(Color7);
      case 8:  return(Color8);
      case 9:  return(Color9);
      case 10: return(Color10);
      case 11: return(Color11);
      case 12: return(Color12);
   }
   return(Color1);      
}
void plot(string namex,double valueA, double valueB, int shiftA, int shiftB, color theColor, int width=0,int style=STYLE_SOLID)
{
   string name = shortName+namex+":"+Time[shiftA];
   
   //
   //
   //
   //
   //
   
   if (ObjectFind(name) == -1) 
       ObjectCreate(name,OBJ_TREND,window,Time[shiftA],valueA,Time[shiftB],valueB);
          ObjectSet(name,OBJPROP_RAY,false);
          ObjectSet(name,OBJPROP_BACK,true);
          ObjectSet(name,OBJPROP_STYLE,style);
          ObjectSet(name,OBJPROP_WIDTH,width);
          ObjectSet(name,OBJPROP_COLOR,theColor);
          ObjectSet(name,OBJPROP_PRICE1,valueA);
          ObjectSet(name,OBJPROP_PRICE2,valueB);
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

int barTime(int a)
{
   if(a<0)
         return(Time[0]+Period()*60*MathAbs(a));
   else  return(Time[a]);   
}

//
//
//
//
//

void DeletePrices()
{
   int lookForLength = StringLen(shortName);
   for (int i=ObjectsTotal()-1; i>=0; i--) 
   {
      string name = ObjectName(i); if (StringSubstr(name,0,lookForLength) == shortName) ObjectDelete(name);
   }
}

//
//
//
//
//

void DrawPrice(int period, int shift,int ovearAll, double min, double range, double pmin, double prange)
{
   datetime time  = barTime(ovearAll);
   double   high  = min+(iHigh (forSymbol,period,shift)-pmin)*(range/prange);
   double   low   = min+(iLow  (forSymbol,period,shift)-pmin)*(range/prange);
   double   open  = min+(iOpen (forSymbol,period,shift)-pmin)*(range/prange);
   double   close = min+(iClose(forSymbol,period,shift)-pmin)*(range/prange);
   string name;


   
   prices += 1;
   name    = shortName+"prices"+prices;
      ObjectCreate(name,OBJ_TREND,window,time,high,time,low);
         ObjectSet(name,OBJPROP_COLOR,WickColor);
         ObjectSet(name,OBJPROP_RAY  ,false);
         ObjectSet(name,OBJPROP_BACK,candlesAsBack);
      
   //
   //
   //
   //
   //
         
   prices += 1;
   name    = shortName+"prices"+prices+"body";
      ObjectCreate(name,OBJ_TREND,window,time,open,time,close);
         ObjectSet(name,OBJPROP_WIDTH,3);
         ObjectSet(name,OBJPROP_RAY  ,false);
         ObjectSet(name,OBJPROP_BACK,candlesAsBack);
         ObjectSet(name,OBJPROP_WIDTH,BodyWidth);
         if (open<close)
               ObjectSet(name,OBJPROP_COLOR,BodyUpColor);
         else  ObjectSet(name,OBJPROP_COLOR,BodyDownColor);
}


//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

//
//
//
//
//

int toInt(double value) { return(value); }
int stringToTimeFrame(string tfs)
{
   tfs = stringUpperCase(tfs);
   int max = ArraySize(iTfTable)-1, add=0;
   int nxt = (StringFind(tfs,"NEXT1")>-1); if (nxt>0) { tfs = ""+Period(); add=1; }
       nxt = (StringFind(tfs,"NEXT2")>-1); if (nxt>0) { tfs = ""+Period(); add=2; }
       nxt = (StringFind(tfs,"NEXT3")>-1); if (nxt>0) { tfs = ""+Period(); add=3; }

      //
      //
      //
      //
      //
         
      for (int i=max; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(iTfTable[toInt(MathMin(max,i+add))]);
                                                      return(Period());
}
string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}

//
//
//
//
//

string stringUpperCase(string str)
{
   string   s = str;

   for (int length=StringLen(str)-1; length>=0; length--)
   {
      int char = StringGetChar(s, length);
         if((char > 96 && char < 123) || (char > 223 && char < 256))
                     s = StringSetChar(s, length, char - 32);
         else if(char > -33 && char < 0)
                     s = StringSetChar(s, length, char + 224);
   }
   return(s);
}