//+------------------------------------------------------------------+
//|                                       smKinetic TrendMode_v1.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010.08.09 SwingMan"
#property link      ""

#property indicator_separate_window

#property indicator_buffers 6 
#property indicator_color1 MediumTurquoise
#property indicator_color2 Tomato
#property indicator_color3 MediumTurquoise
#property indicator_color4 Tomato
#property indicator_color5 Green
#property indicator_color6 Red

#property indicator_width1 3
#property indicator_width2 3
#property indicator_width3 3
#property indicator_width4 3
// signals
#property indicator_width5 1
#property indicator_width6 1

#property indicator_maximum 1
#property indicator_minimum -1
#property indicator_level1 0
#property indicator_levelstyle STYLE_SOLID
#property indicator_levelwidth 1

#define histValue 0.6

//---- input parameters 
//+------------------------------------------------------------------+
extern bool Draw_VerticalLines = true;
extern bool Draw_EntryArrows = true;
extern int periodCloses = 6; 
extern int periodOpens = 8; 
extern string ____ZeroLag_MACD="";
extern int FastEMA = 12; 
extern int SlowEMA = 24;
extern int SignalEMA = 9;
extern int ma_method  = MODE_EMA;
extern int MaxBars = 2000;
extern string ____Colors="";
extern color ColorVLine_Long  = Blue;
extern color ColorVLine_Short = Red;
extern color ColorLevel_Long = Aqua;
extern color ColorLevel_Short = Magenta;
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+

//---- buffers 
double UpTrend[], DnTrend[]; 
double UpTrend2[], DnTrend2[]; 
double signalUP[],signalDN[];
//---- buffers2
double MACDBuffer[];
double MACDBufferUp[];
double MACDBufferDn[];
double SignalBuffer[];
double FastEMABuffer[];
double SlowEMABuffer[];
double SignalEMABuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
   ArraySetAsSeries(MACDBuffer,true);
   ArraySetAsSeries(MACDBufferUp,true);
   ArraySetAsSeries(MACDBufferDn,true);
   ArraySetAsSeries(SignalBuffer,true);
   ArraySetAsSeries(FastEMABuffer,true);
   ArraySetAsSeries(SlowEMABuffer,true);
   ArraySetAsSeries(SignalEMABuffer,true);

   string sParam = " (" +periodCloses+","+periodOpens+", "+FastEMA+","+SlowEMA+","+SignalEMA+")";
   IndicatorShortName("SwingMan KineticTrendMode"+sParam);
   // histograms ....................................................
   SetIndexBuffer(0, UpTrend); 
   SetIndexBuffer(1, DnTrend); 
   SetIndexBuffer(2, UpTrend2); 
   SetIndexBuffer(3, DnTrend2); 
    
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexStyle(1,DRAW_HISTOGRAM);
   SetIndexStyle(2,DRAW_HISTOGRAM);
   SetIndexStyle(3,DRAW_HISTOGRAM);
   
   SetIndexLabel(0,NULL); SetIndexLabel(1,NULL); 
   SetIndexLabel(2,NULL); SetIndexLabel(3,NULL);
   
   // signals .......................................................
   int arrowUP=233;
   int arrowDN=234;
   SetIndexBuffer(4, signalUP); SetIndexStyle(4,DRAW_ARROW); SetIndexArrow(4,arrowUP);
   SetIndexBuffer(5, signalDN); SetIndexStyle(5,DRAW_ARROW); SetIndexArrow(5,arrowDN);
   
   SetIndexLabel(4,"Kinetic UP");     
   SetIndexLabel(5,"Kinetic DOWN");   
   
   IndicatorDigits(0);
   return(0);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   Delete_Objects("line_");
   Delete_Objects("entry_");
   Delete_Objects("entry2_");
   Delete_Objects("entry3_");
   return(0);
}

//####################################################################
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   ArrayResize(MACDBuffer,Bars);
   ArrayResize(MACDBufferUp,Bars);
   ArrayResize(MACDBufferDn,Bars);
   ArrayResize(SignalBuffer,Bars);
   ArrayResize(FastEMABuffer,Bars);
   ArrayResize(SlowEMABuffer,Bars);
   ArrayResize(SignalEMABuffer,Bars);
   
   int limit;
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
   if (limit>MaxBars) limit = MaxBars;

   //---- main loop
   for(int i=0; i<limit; i++)
   {
      UpTrend[i] = EMPTY_VALUE;
      DnTrend[i] = EMPTY_VALUE;
      UpTrend2[i] = EMPTY_VALUE;
      DnTrend2[i] = EMPTY_VALUE;

               //*********************************      
               //    MOVING AVERAGES             *
               //*********************************
      double closeLine = iMA(Symbol(),Period(), periodCloses,0,ma_method,PRICE_CLOSE,i);
      double openLine  = iMA(Symbol(),Period(), periodOpens, 0,ma_method,PRICE_OPEN,i);
      
      bool Cond_Long  = (closeLine>openLine);                        
      bool Cond_Short = (closeLine<openLine);
                            
      // Trend Long ---------------------------------------
      if (Cond_Long)
         UpTrend[i] = histValue;
      else         
      // Trend Short --------------------------------------
      if (Cond_Short)
         DnTrend[i] = histValue;
   }
   
               //*********************************      
               //    ZeroLag MACD                *
               //*********************************
   Get_ZeroLagMACDValues(limit);
   for(i=0; i<limit; i++)
   {      
      if (MACDBufferUp[i]!=EMPTY_VALUE) UpTrend2[i]=-histValue;
      if (MACDBufferDn[i]!=EMPTY_VALUE) DnTrend2[i]=-histValue;   
   }   

               //*********************************      
               //    SIGNALS                     *
               //*********************************      
   double dThird, dValue, maxVal, minVal;
   for(i=limit; i>=0; i--)
   {                     
      signalUP[i] = EMPTY_VALUE;
      signalDN[i] = EMPTY_VALUE;
      
      // LONG signal ------------------------------------------------
      if (UpTrend[i]!=EMPTY_VALUE)
      {
         if (UpTrend2[i]!=EMPTY_VALUE && DnTrend2[i+1]!=EMPTY_VALUE)
         {
            signalUP[i] = 0;
            if (Draw_VerticalLines)
               Draw_VerticalLine(i,"long",ColorVLine_Long);
         }   
         if (Draw_EntryArrows && signalUP[i+1]!=EMPTY_VALUE)
         {
            maxVal = MathMax(Open[i+1],Close[i+1]);
            minVal = MathMin(Open[i+1],Close[i+1]);
            dThird = (maxVal-minVal)*0.3333;
            dValue = maxVal - dThird;
            DrawArrow_Entry3th(i+1, dValue, ColorLevel_Long);
         }      
      }
      else
      // SHORT signal -----------------------------------------------
      if (DnTrend[i]!=EMPTY_VALUE)
      {
         if (DnTrend2[i]!=EMPTY_VALUE && UpTrend2[i+1]!=EMPTY_VALUE)
         {
            signalDN[i] = 0;
            if (Draw_VerticalLines)
               Draw_VerticalLine(i,"short",ColorVLine_Short);
         }      
         if (Draw_EntryArrows && signalDN[i+1]!=EMPTY_VALUE)
         {
            maxVal = MathMax(Open[i+1],Close[i+1]);
            minVal = MathMin(Open[i+1],Close[i+1]);
            dThird = (maxVal-minVal)*0.3333;            
            dValue = minVal + dThird;
            DrawArrow_Entry3th(i+1, dValue, ColorLevel_Short);
         }   
      }
   }   
//----
   return(0);
}//start
//+------------------------------------------------------------------+


//___________________________________________________________________
void Draw_VerticalLine(int iBar, string sDirection, color dColor)
{
   string sObjName = "line_" + TimeToStr(Time[iBar]);
   Delete_Objects(sObjName);
   
   ObjectCreate(sObjName,OBJ_VLINE,0,Time[iBar],0);
   ObjectSet(sObjName,OBJPROP_COLOR,dColor);
   ObjectSet(sObjName,OBJPROP_WIDTH,1);
   ObjectSet(sObjName,OBJPROP_STYLE,STYLE_DOT);
   ObjectSet(sObjName,OBJPROP_BACK,false);
}//Draw_VerticalLine


//___________________________________________________________________
void DrawArrow_Entry3th(int iBar, double dValue, color dColor)
{
   string sObjName = "entry_" + TimeToStr(Time[iBar])+"_";
   Delete_Objects(sObjName);
   sObjName = sObjName + DoubleToStr(dValue,Digits);
   ObjectCreate(sObjName,OBJ_ARROW,0,Time[iBar],dValue);
   ObjectSet(sObjName,OBJPROP_COLOR,dColor);
   ObjectSet(sObjName,OBJPROP_WIDTH,3);
   ObjectSet(sObjName,OBJPROP_ARROWCODE,4); //little line
   ObjectSet(sObjName,OBJPROP_BACK,false);
   //--
   sObjName = "entry2_" + TimeToStr(Time[iBar])+"_";
   Delete_Objects(sObjName);
   sObjName = sObjName + DoubleToStr(dValue,Digits);
   ObjectCreate(sObjName,OBJ_ARROW,0,Time[iBar],dValue);
   ObjectSet(sObjName,OBJPROP_COLOR,dColor);
   ObjectSet(sObjName,OBJPROP_WIDTH,1);
   ObjectSet(sObjName,OBJPROP_ARROWCODE,252); //hacken
   ObjectSet(sObjName,OBJPROP_BACK,false);
      //--
   sObjName = "entry3_" + TimeToStr(Time[iBar-1])+"_";
   Delete_Objects(sObjName);
   sObjName = sObjName + DoubleToStr(dValue,Digits);
   ObjectCreate(sObjName,OBJ_ARROW,0,Time[iBar-1],dValue);
   ObjectSet(sObjName,OBJPROP_COLOR,dColor);
   ObjectSet(sObjName,OBJPROP_WIDTH,3);
   ObjectSet(sObjName,OBJPROP_ARROWCODE,4); //little line
   ObjectSet(sObjName,OBJPROP_BACK,false);
   return;
}//DrawArrow_Entry3th

//___________________________________________________________________
void Delete_Objects(string sText)
{
   int total = ObjectsTotal();
   for (int i = total; i>= 0; i--)
   {
      string sObjectName = ObjectName(i);
      if (StringFind(sObjectName, sText, 0) != -1) {
         ObjectDelete(sObjectName);
      }
   }   
}//Delete_Objects



//___________________________________________________________________
void Get_ZeroLagMACDValues(int limit)
{
double EMA, ZeroLagEMAp, ZeroLagEMAq;

   for(int i = 0; i < limit; i++)
     {
       FastEMABuffer[i] = iMA(NULL, 0, FastEMA, 0, MODE_EMA, PRICE_CLOSE, i);
       SlowEMABuffer[i] = iMA(NULL, 0, SlowEMA, 0, MODE_EMA, PRICE_CLOSE, i);
     }
   for(i = 0; i < limit; i++)
     {
        EMA = iMAOnArray(FastEMABuffer, Bars, FastEMA, 0, MODE_EMA, i);
        ZeroLagEMAp = FastEMABuffer[i] + FastEMABuffer[i] - EMA;
        EMA = iMAOnArray(SlowEMABuffer, Bars, SlowEMA, 0, MODE_EMA, i);
        ZeroLagEMAq = SlowEMABuffer[i] + SlowEMABuffer[i] - EMA;
        MACDBuffer[i] = ZeroLagEMAp - ZeroLagEMAq;
     }
   for(i = 0; i < limit; i++)
       SignalEMABuffer[i] = iMAOnArray(MACDBuffer, Bars, SignalEMA, 0, MODE_EMA, i);
   for(i = 0; i < limit; i++)
     {
       EMA = iMAOnArray(SignalEMABuffer, Bars, SignalEMA, 0, MODE_EMA, i);
       SignalBuffer[i] = SignalEMABuffer[i] + SignalEMABuffer[i] - EMA;
   }
   for (i=limit-1; i>=0; i--) {
      if (MACDBufferUp[i+1] != EMPTY_VALUE && MACDBufferUp[i+1] == MACDBuffer[i+1]) {
         MACDBufferUp[i] = MACDBuffer[i];
      } else if (MACDBufferDn[i+1] != EMPTY_VALUE && MACDBufferDn[i+1] == MACDBuffer[i+1]) {
         MACDBufferDn[i] = MACDBuffer[i];
      }

      if (MACDBuffer[i+1] < MACDBuffer[i]) {
         MACDBufferUp[i] = MACDBuffer[i];
         MACDBufferDn[i] = EMPTY_VALUE;
      } else if (MACDBuffer[i+1] > MACDBuffer[i]) {
         MACDBufferDn[i] = MACDBuffer[i];
         MACDBufferUp[i] = EMPTY_VALUE;
      }
     }
}//Get_ZeroLagMACDValues