//+------------------------------------------------------------------+
//|                                       Damon smSilverTrend_v2.mq4 |
//|                                                         SwingMan |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "© 2008, SwingMan"
#property link      ""
//--------------------------------------------------------------------
//  Source code:
//#property copyright "Copyright © 2005, Shurka"
//#property link      "http://shforex.narod.ru"
//--------------------------------------------------------------------
//  Damon smSHI_SilverTrendSig:
// v1 - no repaint version
// v2 - HiLo lines, TriggerChannel, Signals
//--------------------------------------------------------------------

#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 LightSeaGreen
#property indicator_color4 LightSeaGreen
#property indicator_color5 Gold
#property indicator_color6 Gold
#property indicator_color7 Lime
#property indicator_color8 Red

//--------------------------------------------------------------------
extern int     AllBars=0;
extern int     Otstup=20; //--30
extern int  Per=9;
extern int Shift = 1;
extern bool Show_TriggerChannel = true;
extern bool Show_HiLoChannel = false;
extern bool Show_AllDots = true;
//--------------------------------------------------------------------

//---- constants
#define  SH_BUY   1
#define  SH_SELL  -1

//---- variables
int      SH,NB,i,UD, lastUD;
double   R,SHMax,SHMin;
double   BufD[], BufU[];
double   UpperBuf[], LowerBuf[];
double   Highs[], Lows[];
string   sWindows;
datetime thisTime, oldTime;
double   BufDall[], BufUall[];

//--------------------------------------------------------------------

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{  
   int Ots = Get_DefaultOtstup();
   if (Ots > 0) Otstup = Ots;
   
   UD = 0;
   lastUD = 0;

   if (Bars<AllBars+Per || AllBars==0) NB=Bars-Per; else NB=AllBars;
   sWindows = "Damon smSilverTrend_v2";
   IndicatorShortName(sWindows);
   string st = "  (Per=" + DoubleToStr(Per,0);
   st = st + ",  Otstup=" + Otstup + ")";
   Comment(sWindows + st);

   SetIndexBuffer(0,BufU); SetIndexStyle(0,DRAW_ARROW,0,3); SetIndexArrow(0,159); SetIndexLabel(0,"SilverTrend LongSig");
   SetIndexBuffer(1,BufD); SetIndexStyle(1,DRAW_ARROW,0,3); SetIndexArrow(1,159); SetIndexLabel(1,"SilverTrend ShortSig");
   
   SetIndexDrawBegin(0,Bars-NB);
   SetIndexDrawBegin(1,Bars-NB);
   ArrayInitialize(BufD,0.0);
   ArrayInitialize(BufU,0.0);
   
   if (Show_TriggerChannel) {
      SetIndexBuffer(2,UpperBuf); SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,1); SetIndexLabel(2,"TriggerChannel Short");
      SetIndexBuffer(3,LowerBuf); SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,1); SetIndexLabel(3,"TriggerChannel Long");
   } else {
      SetIndexBuffer(2,UpperBuf); SetIndexStyle(2,DRAW_NONE); SetIndexLabel(2,NULL);
      SetIndexBuffer(3,LowerBuf); SetIndexStyle(3,DRAW_NONE); SetIndexLabel(3,NULL);
   }
   
   if (Show_HiLoChannel) {
      SetIndexBuffer(4,Highs);  SetIndexStyle(4,DRAW_LINE,STYLE_SOLID,1); SetIndexLabel(4,"Channel Highs");   
      SetIndexBuffer(5,Lows);   SetIndexStyle(5,DRAW_LINE,STYLE_SOLID,1); SetIndexLabel(5,"Channel Lows");   
   } else {
      SetIndexBuffer(4,Highs);  SetIndexStyle(4,DRAW_NONE); SetIndexLabel(4,NULL);   
      SetIndexBuffer(5,Lows);   SetIndexStyle(5,DRAW_NONE); SetIndexLabel(5,NULL);      
   }
   
   if (Show_AllDots) {
      SetIndexBuffer(6,BufUall);  SetIndexStyle(6,DRAW_ARROW,0,0); SetIndexArrow(6,159); SetIndexLabel(6,"Possible Long");   
      SetIndexBuffer(7,BufDall);  SetIndexStyle(7,DRAW_ARROW,0,0); SetIndexArrow(7,159); SetIndexLabel(7,"Possible Short");   
   } else {
      SetIndexBuffer(6,BufUall);  SetIndexStyle(6,DRAW_NONE); SetIndexLabel(6,NULL);   
      SetIndexBuffer(7,BufDall);  SetIndexStyle(7,DRAW_NONE); SetIndexLabel(7,NULL);      
   }
 
//----
   return(0);
}
  
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
{
   Comment("");
   return(0);
 }
  
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
{
   int CB=IndicatorCounted();
   if(CB<0) return(-1); else if(NB>Bars-CB) NB=Bars-CB;
   
   
   //-- start every minute, no repaint...  
   thisTime = Time[0];
   //if (thisTime == oldTime) return(0);
   //oldTime = thisTime;
//~~   if (NB < 3) NB = 3;
   //-- Draw channels
   for (SH=0;SH<NB;SH++)
   {
      SHMax = High[Highest(Symbol(),0,MODE_HIGH,Per,SH)];
      SHMin = Low[Lowest(Symbol(),0,MODE_LOW,Per,SH)];
      
      //-- HiLo channel       
      Highs[SH] = SHMax;
      Lows[SH]  = SHMin;
      //-- trigger channel
      UpperBuf[SH] = SHMax-(SHMax-SHMin)*Otstup/100.0;
      LowerBuf[SH] = SHMin+(SHMax-SHMin)*Otstup/100.0;         
   }

// 4.
   //-- start every minute, no repaint...  
   thisTime = Time[0];
   if (thisTime == oldTime) return(0);
   oldTime = thisTime;
   if (NB < 3) NB = 3;
   
   for (SH=1; SH<NB; SH++)
   {
      for (R=0,i=SH;i<SH+10;i++) {R+=(10+SH-i)*(High[i]-Low[i]);}      R/=55; // BarRange
      double offset = R*0.3;
      
      SHMax = High[Highest(Symbol(),0,MODE_HIGH,Per,SH)];
      SHMin = Low[Lowest(Symbol(),0,MODE_LOW,Per,SH)];
      
      //-- Long signal
      if (Close[SH]<=SHMin+(SHMax-SHMin)*Otstup/100.0) {             
         BufUall[SH]=Low[SH]-offset;
         if (UD!=SH_SELL) {
            BufU[SH]=Low[SH]-offset;
            BufD[SH]=EMPTY_VALUE;
            UD=SH_SELL;
            if (SH==1) {
               if (lastUD == SH_BUY || lastUD == 0) {
                  lastUD = SH_SELL;
               }
            }
         } else {
            BufU[SH]=EMPTY_VALUE;
         }
      }
      
      //-- short signal
      if (Close[SH]>=SHMax-(SHMax-SHMin)*Otstup/100.0) {
         BufDall[SH]=High[SH]+offset;
         if (UD!=SH_BUY) { 
            BufU[SH]=EMPTY_VALUE;
            BufD[SH]=High[SH]+offset;
            UD=SH_BUY; 
            if (SH==1) {
               if (lastUD == SH_SELL || lastUD == 0) {
                  lastUD = SH_BUY;
               }
            }
         } else {
            BufD[SH]=EMPTY_VALUE;
         }   
      }
   
/* 3.   
   //-- Get signals
   for (SH=0;SH<NB;SH++)
   {
      for (R=0,i=SH;i<SH+10;i++) {R+=(10+SH-i)*(High[i]-Low[i]);}      R/=55; // BarRange
      double offset = R*0.9;
      
//~~      SHMax = High[Highest(Symbol(),0,MODE_HIGH,Per,SH)];
//~~      SHMin = Low[Lowest(Symbol(),0,MODE_LOW,Per,SH)];
      
      //-- HiLo channel       
//~~      Highs[SH] = SHMax;
//~~      Lows[SH]  = SHMin;
      //-- trigger channel
//~~      UpperBuf[SH] = SHMax-(SHMax-SHMin)*Otstup/100.0;
//~~      LowerBuf[SH] = SHMin+(SHMax-SHMin)*Otstup/100.0;      
   
//~~      if (thisTime != oldTime) {
//~~         oldTime = thisTime;   
         SHMax = Highs[SH+Shift];
         SHMin = Lows[SH+Shift];
         if (Close[SH+Shift]<SHMin+(SHMax-SHMin)*Otstup/100.0 && UD!=SH_SELL) {             
            BufU[SH+Shift]=Low[SH+Shift]-offset;  
            BufD[SH+Shift]=EMPTY_VALUE;
            UD=SH_SELL;
            if (SH==0) {
            //if (SH==1) {
               if (lastUD == SH_BUY || lastUD == 0) {
                  lastUD = SH_SELL;
               }
            }
         }
      
         if (Close[SH+Shift]>SHMax-(SHMax-SHMin)*Otstup/100.0 && UD!=SH_BUY) { 
            BufU[SH+Shift]=EMPTY_VALUE;
            BufD[SH+Shift]=High[SH+Shift]+offset;
            UD=SH_BUY; 
            if (SH==0) {
            //if (SH==1) {
               if (lastUD == SH_SELL || lastUD == 0) {
                  lastUD = SH_BUY;
               }
            }
//~~         }
      }
*/      
/* 2.
   //-- start every minute, no repaint...  
   thisTime = Time[0];
   if (thisTime == oldTime) return(0);
   oldTime = thisTime;
   if (NB < 3) NB = 3;
   
   for (SH=0;SH<NB;SH++)
   //for (SH=1;SH<NB;SH++)
   {
      for (R=0,i=SH;i<SH+10;i++) {R+=(10+SH-i)*(High[i]-Low[i]);}      R/=55; // BarRange
      double offset = R*0.3;
      
      SHMax = High[Highest(Symbol(),0,MODE_HIGH,Per,SH+Shift)];
      SHMin = Low[Lowest(Symbol(),0,MODE_LOW,Per,SH+Shift)];
      
      //-- HiLo channel       
      Highs[SH+Shift] = SHMax;
      Lows[SH+Shift]  = SHMin;
      //-- trigger channel
      UpperBuf[SH+Shift] = SHMax-(SHMax-SHMin)*Otstup/100.0;
      LowerBuf[SH+Shift] = SHMin+(SHMax-SHMin)*Otstup/100.0;      
      
      if (Close[SH+Shift]<SHMin+(SHMax-SHMin)*Otstup/100.0 && UD!=SH_SELL) {             
            BufU[SH+Shift]=Low[SH+Shift]-offset;  
            BufD[SH+Shift]=EMPTY_VALUE;
            UD=SH_SELL;
            if (SH==1) {
               if (lastUD == SH_BUY || lastUD == 0) {
                  lastUD = SH_SELL;
               }
            }
      }
      
      if (Close[SH+Shift]>SHMax-(SHMax-SHMin)*Otstup/100.0 && UD!=SH_BUY) { 
            BufU[SH+Shift]=EMPTY_VALUE;
            BufD[SH+Shift]=High[SH+Shift]+offset;
            UD=SH_BUY; 
            if (SH==1) {
               if (lastUD == SH_SELL || lastUD == 0) {
                  lastUD = SH_BUY;
               }
            }
      }
*/      
/* 1.
      
      SHMax = High[Highest(Symbol(),0,MODE_HIGH,Per,SH)];
      SHMin = Low[Lowest(Symbol(),0,MODE_LOW,Per,SH)];
      
      //-- HiLo channel       
      Highs[SH] = SHMax;
      Lows[SH]  = SHMin;
      //-- trigger channel
      UpperBuf[SH] = SHMax-(SHMax-SHMin)*Otstup/100.0;
      LowerBuf[SH] = SHMin+(SHMax-SHMin)*Otstup/100.0;      
      
      if (Close[SH]<SHMin+(SHMax-SHMin)*Otstup/100.0 && UD!=SH_SELL) {             
            BufU[SH]=Low[SH]-offset;  
            BufD[SH]=EMPTY_VALUE;
            UD=SH_SELL;
            if (SH==1) {
               if (lastUD == SH_BUY || lastUD == 0) {
                  lastUD = SH_SELL;
               }
            }
      }
      
      if (Close[SH]>SHMax-(SHMax-SHMin)*Otstup/100.0 && UD!=SH_BUY) { 
            BufU[SH]=EMPTY_VALUE;
            BufD[SH]=High[SH]+offset;
            UD=SH_BUY; 
            if (SH==1) {
               if (lastUD == SH_SELL || lastUD == 0) {
                  lastUD = SH_BUY;
               }
            }
      }
*/      
   }  
//----
   return(0);
}
//+------------------------------------------------------------------+

int Get_DefaultOtstup()
{
   if (Symbol() == "AUDUSD") return(15);
   if (Symbol() == "EURUSD") return(15);
   if (Symbol() == "GBPUSD") return(20);
   if (Symbol() == "USDCAD") return(10);
   if (Symbol() == "USDCHF") return(15);
   if (Symbol() == "USDJPY") return(15);
   if (Symbol() == "GBPJPY") return(15);
   if (Symbol() == "GBPCHF") return(20);
   if (Symbol() == "EURGBP") return(15);
   if (Symbol() == "NZDUSD") return(10);
   if (Symbol() == "EURJPY") return(15);
   if (Symbol() == "EURCHF") return(20);
   if (Symbol() == "EURAUD") return(30);
   if (Symbol() == "EURCAD") return(20);   
   return(-1);
}