//+------------------------------------------------------------------+
//|                                                        CLOUD.mq4 |
//|                             Copyright (c) 2016, Gehtsoft USA LLC | 
//|                                            http://fxcodebase.com |
//|                         Donate / Support:  http://goo.gl/cEP5h5  | 
//+------------------------------------------------------------------+
//|                                      Developed by : Mario Jemic  |                    
//|                                          mario.jemic@gmail.com   |
//|                     BitCoin: 1MfUHS3h86MBTeonJzWdszdzF2iuKESCKU  |
//+------------------------------------------------------------------+

#property indicator_buffers 10
#property indicator_chart_window

enum en_method{ SMA=0, EMA=1, SMMA=2, LWMA=3 };
enum en_price{ CLOSE=0, OPEN=1, LOW=2, HIGH=3, MEDIAN=4, TYPICAL=5, WEIGHTED=6 };

extern int      FastAveragePeriod = 50;
input  en_method FastMAMethod      = EMA;
input  en_price  FastMAPriceType     = CLOSE;

extern int      SlowAveragePeriod = 200;
input  en_method SlowMAMethod      = SMA;
input  en_price  SlowMAPriceType     = CLOSE;

extern color    Color_Up            = clrGreen;
extern color    Color_UpDown        = clrLime;
extern color    Color_DownUp        = clrOrange;
extern color    Color_Down          = clrRed;
extern color    ColorFastMA       = clrYellow;
extern color    ColorSlowMA       = clrWhite;

extern bool     Alert_ON            = true;

double FastMA[];
double SlowMA[];
double Up_min[];     double Up_max[];
double UpDown_min[]; double UpDown_max[];
double DownUp_min[]; double DownUp_max[];
double Down_min[];   double Down_max[];

bool   OriginalCalculation = false;

int i;
datetime LastAlert;

int init(){
   
   IndicatorShortName("CLOUD");
   
   SetIndexBuffer(0,FastMA);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2,ColorFastMA);
   SetIndexLabel(0,"Fast MA");
   
   SetIndexBuffer(1,SlowMA);
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2,ColorSlowMA);
   SetIndexLabel(1,"Slow MA");
   
   SetIndexStyle(2,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_Up);
   SetIndexBuffer(2,Up_min);
   SetIndexLabel(2,"Up Cloud");
   
   SetIndexStyle(3,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_Up);
   SetIndexBuffer(3,Up_max);
   SetIndexLabel(3,"Up Cloud");
   
   SetIndexStyle(4,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_UpDown);
   SetIndexBuffer(4,UpDown_min);
   SetIndexLabel(4,"UpDown Cloud");
   
   SetIndexStyle(5,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_UpDown);
   SetIndexBuffer(5,UpDown_max);
   SetIndexLabel(6,"UpDown Cloud");
   
   SetIndexStyle(6,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_DownUp);
   SetIndexBuffer(6,DownUp_min);
   SetIndexLabel(6,"DownUp Cloud");
   
   SetIndexStyle(7,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_DownUp);
   SetIndexBuffer(7,DownUp_max);
   SetIndexLabel(7,"DownUp Cloud");
   
   SetIndexStyle(8,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_Down);
   SetIndexBuffer(8,Down_min);
   SetIndexLabel(8,"Down Cloud");
   
   SetIndexStyle(9,DRAW_HISTOGRAM, STYLE_SOLID, 4, Color_Down);
   SetIndexBuffer(9,Down_max);
   SetIndexLabel(9,"Down Cloud");
   
   return(0);
}

int start()
  {
   
   int counted_bars=IndicatorCounted();
   int limit = Bars-counted_bars-1;
   
   double max_ma, min_ma;
   
   for(i=limit; i>=0; i--){
      FastMA[i] = iMA(NULL,0,FastAveragePeriod,0,FastMAMethod,FastMAPriceType,i);
      SlowMA[i] = iMA(NULL,0,SlowAveragePeriod,0,SlowMAMethod,SlowMAPriceType,i);
      
      max_ma = MathMax(FastMA[i],SlowMA[i]);
      min_ma = MathMin(FastMA[i],SlowMA[i]);
      
      if (OriginalCalculation){
      
         if (FastMA[i] >= FastMA[i+1]){
            if (SlowMA[i] >= SlowMA[i+1]){
               Up_max[i] = max_ma;
               Up_min[i] = min_ma;
            }else{
               UpDown_max[i] = max_ma;
               UpDown_min[i] = min_ma;
            }
         }else{
            if (SlowMA[i] >= SlowMA[i+1]){
               DownUp_max[i] = max_ma;
               DownUp_min[i] = min_ma;
            }else{
               Down_max[i] = max_ma;
               Down_min[i] = min_ma;
            }
         }
      
      // This is a twist of the original calculation:
      // - When Fast MA is above Slow MA the cloud is Green
      // - When Fast MA is below Slow MA the cloud is Red
      // - When is Green but the fast is beginning to decrease the color of the cloud will change to another green tonality, same with red
      }else{
         if (FastMA[i] >= SlowMA[i]){
            if (FastMA[i] >= FastMA[i+1]){
               Up_max[i] = max_ma;
               Up_min[i] = min_ma;
            }else{
               UpDown_max[i] = max_ma;
               UpDown_min[i] = min_ma;
            }
         }else{
            if (FastMA[i] >= FastMA[i+1]){
               DownUp_max[i] = max_ma;
               DownUp_min[i] = min_ma;
            }else{
               Down_max[i] = max_ma;
               Down_min[i] = min_ma;
            }
         }
      }
      
   }
   
   if (Alert_ON && Time[0] > LastAlert){
      
      if (FastMA[0] > SlowMA[0] && FastMA[1] < SlowMA[1]){
         Alert(Symbol() + " " + TFToStr(Period()) + ": Cloud Mode changed to UP");
         LastAlert = TimeCurrent();
      }
      
      if (FastMA[0] < SlowMA[0] && FastMA[1] > SlowMA[1]){
         Alert(Symbol() + " " + TFToStr(Period()) + ": Cloud Mode changed to DOWN");
         LastAlert = TimeCurrent();
      }
   }
   
//----
   return(0);
}

string TFToStr(int tf)   { 
  if (tf == 0)        tf = Period();
  if (tf >= 43200)    return("MN");
  if (tf >= 10080)    return("W1");
  if (tf >=  1440)    return("D1");
  if (tf >=   240)    return("H4");
  if (tf >=    60)    return("H1");
  if (tf >=    30)    return("M30");
  if (tf >=    15)    return("M15");
  if (tf >=     5)    return("M5");
  if (tf >=     1)    return("M1");
  return("");
}