//+------------------------------------------------------------------+
//|                                    Non Repainting SuperTrend.mq4 |
//|                     Copyright © 2012, Marketcalls (Rajandran R). |
//|                                        http://www.marketcalls.in |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, Marketcalls"
#property link      "http://www.marketcalls.in"

#property indicator_chart_window
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_width1 1
#property indicator_width2 1
#property indicator_color3 Blue
#property indicator_color4 Red
#property indicator_width3 1
#property indicator_width4 1
#property indicator_buffers 4
double TrendUp[], TrendDown[];
double UpBuffer[];
double DnBuffer[];


int changeOfTrend;

extern string TimeFrame        = "Current time frame";
extern int    Nbr_Periods      = 10;
extern double Multiplier       = 4.0;
extern string note             = "turn on Alert = true; turn off = false";
extern bool   alertsOn         = true;
extern bool   alertsOnCurrent  = false;
extern bool   alertsMessage    = true;
extern bool   alertsSound      = true;
extern bool   alertsNotify     = false;
extern bool   alertsEmail      = false;
extern string soundfile        = "alert2.wav";

extern int    sidFontSize      = 30;
extern string sidFontName      = "Ariel";
extern string NoteRedGreenBlue = "Red/Green/Blue each 0..255";
extern int    sidRed           = 30;
extern int    sidGreen         = 30;
extern int    sidBlue          = 30;
extern int    sidXPos          = 30;
extern int    sidYPos          = 150;
 
extern bool   tagDisplayText   = true;
extern string tagText          = "www.marketcalls.in";
extern int    tagFontSize      = 15;
extern string tagFontName      = "Ariel";
extern int    tagRed           = 30;
extern int    tagGreen         = 30;
extern int    tagBlue          = 30;
extern int    tagXPos          = 200;
extern int    tagYPos          = 300;
extern bool   ArrowsOnFirstBar = true;
 
//---- data
string SID = "Symbol";
int sidRGB = 0;
string TAG = "Tag";
int tagRGB = 0;
string tf;
string indicatorFileName;
bool   returnBars;
int    timeFrame; 

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexBuffer(0, TrendUp);
   SetIndexStyle(0, DRAW_LINE, 1, 1);
   SetIndexLabel(0, "Trend Up");
   SetIndexBuffer(1, TrendDown);
   SetIndexStyle(1, DRAW_LINE, 1, 1);
   SetIndexLabel(1, "Trend Down");
   
   SetIndexStyle(2,DRAW_ARROW,EMPTY);
   SetIndexStyle(3,DRAW_ARROW,EMPTY);
   
   SetIndexBuffer(2,UpBuffer);
   SetIndexBuffer(3,DnBuffer);
  
   SetIndexArrow(2,233);
   SetIndexArrow(3,234);

   SetIndexLabel(3,"Up Signal");
   SetIndexLabel(4,"Down Signal");
   indicatorFileName = WindowExpertName();
   returnBars        = TimeFrame == "returnBars";     if (returnBars)     return(0);
   timeFrame         = stringToTimeFrame(TimeFrame);
   IndicatorShortName(timeFrameToString(timeFrame)+" Non Repainting Supertrend");
return(0);
}
   
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
ObjectDelete(SID);
ObjectDelete(TAG);
      
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   int counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
           int limit=MathMin(Bars-counted_bars,Bars-1);
           if (returnBars) { TrendUp[0] = limit+1; return(0); }
   
            if (timeFrame!=Period())
            {
               int shift = -1; if (ArrowsOnFirstBar) shift=1;
               limit = MathMax(limit,MathMin(Bars-1,iCustom(NULL,timeFrame,indicatorFileName,"returnBars",0,0)*timeFrame/Period()));
               for (int i=limit; i>=0; i--)
               {
                  int y = iBarShift(NULL,timeFrame,Time[i]);
                  int x = iBarShift(NULL,timeFrame,Time[i+shift]);               
                     TrendUp[i]   = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Nbr_Periods,Multiplier,"",alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundfile,
                                    sidFontSize,sidFontName,NoteRedGreenBlue,sidRed,sidGreen,sidBlue,sidXPos,sidYPos,tagDisplayText,tagText,tagFontSize,tagFontName,tagRed,tagGreen,tagBlue,tagXPos,tagYPos,0,y);
                     TrendDown[i] = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Nbr_Periods,Multiplier,"",alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundfile,
                                    sidFontSize,sidFontName,NoteRedGreenBlue,sidRed,sidGreen,sidBlue,sidXPos,sidYPos,tagDisplayText,tagText,tagFontSize,tagFontName,tagRed,tagGreen,tagBlue,tagXPos,tagYPos,1,y);
                  if (x!=y)
                  {
                     UpBuffer[i]  = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Nbr_Periods,Multiplier,"",alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundfile,
                                    sidFontSize,sidFontName,NoteRedGreenBlue,sidRed,sidGreen,sidBlue,sidXPos,sidYPos,tagDisplayText,tagText,tagFontSize,tagFontName,tagRed,tagGreen,tagBlue,tagXPos,tagYPos,2,y);
                     DnBuffer[i]  = iCustom(NULL,timeFrame,indicatorFileName,"calculateValue",Nbr_Periods,Multiplier,"",alertsOn,alertsOnCurrent,alertsMessage,alertsSound,alertsNotify,alertsEmail,soundfile,
                                    sidFontSize,sidFontName,NoteRedGreenBlue,sidRed,sidGreen,sidBlue,sidXPos,sidYPos,tagDisplayText,tagText,tagFontSize,tagFontName,tagRed,tagGreen,tagBlue,tagXPos,tagYPos,3,y);
                  }
                   
               }
               return(0);
            }
  
    double ClosePrice=Close[0];
   
   //watermark(TAG, tagText, tagFontSize, tagFontName, tagRGB, tagXPos, tagYPos); 
    string str=StringConcatenate("www.marketcalls.in      LTP : ",ClosePrice);
    watermarkclose(TAG,str,tagFontSize, tagFontName, tagRGB, 80, 20); 
 
   int flag, flagh, trend[5000];
   double up[5000], dn[5000], medianPrice, atr;
   counted_bars = IndicatorCounted();
//---- check for possible errors
   if(counted_bars < 0) return(-1);
//---- last counted bar will be recounted
   if(counted_bars > 0) counted_bars--;
   limit=Bars-1-counted_bars;
   
   //Print(limit);
   
//----
   for (i = Bars; i >= 1; i--) {
      TrendUp[i] = EMPTY_VALUE;
      TrendDown[i] = EMPTY_VALUE;
      atr = iATR(NULL, 0, Nbr_Periods, i);
      //Print("atr: "+atr[i]);
      medianPrice = (High[i]+Low[i])/2;
      //Print("medianPrice: "+medianPrice[i]);
      up[i]=medianPrice+(Multiplier*atr);
      //Print("up: "+up[i]);
      dn[i]=medianPrice-(Multiplier*atr);
      //Print("dn: "+dn[i]);
      trend[i]=1;
   
      
      if (Close[i]>up[i+1]) {
         trend[i]=1;
         if (trend[i+1] == -1) changeOfTrend = 1;
         //Print("trend: "+trend[i]);
         
      }
      else if (Close[i]<dn[i+1]) {
         trend[i]=-1;
         if (trend[i+1] == 1) changeOfTrend = 1;
         //Print("trend: "+trend[i]);
      }
      else if (trend[i+1]==1) {
         trend[i]=1;
         changeOfTrend = 0;       
      }
      else if (trend[i+1]==-1) {
         trend[i]=-1;
         changeOfTrend = 0;
      }

      if (trend[i]<0 && trend[i+1]>0) {
         flag=1;
         //Print("flag: "+flag);
      }
      else {
         flag=0;
         //Print("flagh: "+flag);
      }
      
      if (trend[i]>0 && trend[i+1]<0) {
         flagh=1;
         //Print("flagh: "+flagh);
      }
      else {
         flagh=0;
         //Print("flagh: "+flagh);
      }
      
      if (trend[i]>0 && dn[i]<dn[i+1])
         dn[i]=dn[i+1];
      
      if (trend[i]<0 && up[i]>up[i+1])
         up[i]=up[i+1];
      
      if (flag==1)
         up[i]=medianPrice+(Multiplier*atr);
         
      if (flagh==1)
         dn[i]=medianPrice-(Multiplier*atr);
         
      //-- Draw the indicator
      if (trend[i]==1) {
         TrendUp[i]=dn[i];
         if (changeOfTrend == 1) {
            TrendUp[i+1] = TrendDown[i+1];
            changeOfTrend = 0;
         }
      }
      else if (trend[i]==-1) {
         TrendDown[i]=up[i];
         if (changeOfTrend == 1) {
            TrendDown[i+1] = TrendUp[i+1];
            changeOfTrend = 0;
         }
                 
      }
      if (trend[i]==1 && trend[i+1]==-1) {
        UpBuffer[i] = iLow(Symbol(),0,i)-(3*Point);
        DnBuffer[i] = EMPTY_VALUE;

      }
      if (trend[i]==-1 && trend[i+1]==1) {
         UpBuffer[i] = EMPTY_VALUE;
         DnBuffer[i] = iHigh(Symbol(),0,i)+(3*Point);  
      }
      
   }
   WindowRedraw();
      
   if (alertsOn)
   {
         
         if (alertsOnCurrent)
              int whichBar = 0;
         else     whichBar = 1;
         if (trend[whichBar] != trend[whichBar+1])
         if (trend[whichBar] == 1)
               doAlert("up trend");
         else  doAlert("down trend");       
   }
return(0);           
}

//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//

void doAlert(string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doWhat || previousTime != Time[0]) {
          previousAlert  = doWhat;
          previousTime   = Time[0];

          //
          //
          //
          //
          //

          message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," SuperTrend ",doWhat);
             if (alertsMessage) Alert(message);
             if (alertsNotify)  SendNotification(StringConcatenate(Symbol(), Period() ," SuperTrend " +" "+message));
             if (alertsEmail)   SendMail(StringConcatenate(Symbol()," SuperTrend "),message);
             if (alertsSound)   PlaySound(soundfile);
      }
}


void watermarkclose(string obj, string text, int fontSize, string fontName, color colour, int xPos, int yPos)
{
      ObjectCreate(obj, OBJ_LABEL, 0, 0, 0); 
      ObjectSetText(obj, text, fontSize, fontName, Red);
      ObjectSet(obj, OBJPROP_CORNER, 0); 
      ObjectSet(obj, OBJPROP_XDISTANCE, xPos); 
      ObjectSet(obj, OBJPROP_YDISTANCE, yPos);
      ObjectSet(obj, OBJPROP_BACK, true);
}

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

//
//
//
//
//

int stringToTimeFrame(string tfs)
{
   tfs = stringUpperCase(tfs);
   for (int i=ArraySize(iTfTable)-1; i>=0; i--)
         if (tfs==sTfTable[i] || tfs==""+iTfTable[i]) return(MathMax(iTfTable[i],Period()));
                                                      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);
}

