//+---------------------------------------------------------------------+
//|                                          ZP_SAR-5Parameters_v01.mq4 |
//|                                       Copyright © 2009, Ron Mauldin |
//|                                                                     |
//| Ron Mauldin's 5 Parameter SAR                                       |
//|                                                                     |
//| There are other 5 Parameter SARs on the internet. Please note that  |
//| this one is somewhat different. Here are my three added             |
//| parameters...                                                       |
//| • Start value that can be set to be different than Step... The      |
//|   build=in Metatrader SAR always sets Start to equal Step.          |
//| • CrossoverNoiseFilter - that is intended to reduce whipsaw.        |
//| • DeadZone - This parameter eliminates signals when the parabolic   |
//|   curve is close to the period close. Creating a deadzone is        |
//|   effective in both reducing whipsaw and eliminating some faulty    |
//|   signals during times of low trending.                             |
//|                                                                     |
//| After creating this program and analyzing it, I do not think it is  |
//| fit for use on short timeframe scalping programs because all        |
//| parameters (except SAR5_DeadZone) delay signals further. However,   |
//| you may find it useful for trading longer timeframes... but since I |
//| only scalp, I did not test it for longer periods.                   |
//|                                                                     |
//| Collaborators Wanted                                                |
//| Do you have an interesting idea or indicator designed for scalping? |
//| Would you like to collaborate and turn it into an EA trading robot? |
//| If I like your idea, I will help you fully analyze it.              |
//| If the analysis is good, then I will help you turn your idea into   |
//| an EA robot that we will both share.                                |
//|                                                                     |
//| Are you a "quality" MT4 programmer with "plenty of time" to work on |
//| joint venture (JV) projects?                                        |
//| If so, I have plenty of ideas and would like to discuss a JV.       |
//|                                                                     |
//|  NOTE!!!                                                            |
//|  I am NOT looking for back-testers or programmers for hire.         |
//|  I am looking for entrepreneurial technical analysts or programmers |
//|  who really believe that well coded forex robot could make millions.|
//|  Please don't yank my chain if you are not serious about hard work. |
//|                                                                     |
//| Email: ronmauldin51-mt4 at yahoo dot com                            |
//|  (if you have any success with this indicator, please drop me       |
//|   a line.)                                                          |
//|                                                                     |
//| This is the forex broker I use: fx41.com                            |
//+---------------------------------------------------------------------+
#property copyright "Ron Mauldin"
#property link      "http://fx41.com"

#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Chartreuse
#property indicator_color3 Teal
#property indicator_chart_window
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2

//---- input parameters
extern double SAR5_Start     = 0.06;//Try from 0.01 to 0.08. The higher numbers have less delay, but more changes in direction..
extern double SAR5_Step      = 0.06;//Try from 0.01 to 0.08. The higher numbers have less delay, but more changes in direction.
extern double SAR5_Maximum   = 0.5; //In short term trading, I could not see that this variable had any impact.
extern double SAR5_CrossoverNoiseFilter = 0; //This will reduce whipsaw and increase delay. Try 1 to 4
extern double SAR5_DeadZone = 5.0; //In Pips. This is really good at eliminating whipsaw and faulty signals during low trending.

double SAR5_IndicatorMargin = 8.0; //This only moves the indicator signal in relation to the parabolic curve.
int    SAR5_Precision = 7;   //Precision format, number of digits after decimal point (0-8).

//---- buffers
double sarUp[],sarDn[],sar5ParabolaBuffer[];

//----
int    sar5SaveLastReverse;
bool   sar5SaveLastDirLong;
double sar5SaveLastStart;
double sar5SaveLastHigh;
double sar5SaveLastLow;
double sar5SaveLastExtremePoint;
double sar5SaveLastSAR;
int    sar5SaveLastBartime;
double myPoint;

int init(){
 myPoint = SetPoint(Symbol());
//---- indicators
 IndicatorShortName("SAR4 Step:"+SAR5_Step+" Maximum:"+SAR5_Maximum+" Precision:"+SAR5_Precision+"   ");
 SetIndexBuffer(0,sarDn);
  SetIndexLabel(0,"SAR Down Channel");
  SetIndexStyle(0,DRAW_ARROW);
  SetIndexArrow(0,226);
  SetIndexDrawBegin(0,2);
 SetIndexBuffer(1,sarUp);
  SetIndexLabel(1,"SAR Up Channel");
  SetIndexStyle(1,DRAW_ARROW);
  SetIndexArrow(1,225);
  SetIndexDrawBegin(1,2);
 SetIndexBuffer(2, sar5ParabolaBuffer);
  SetIndexStyle(2, DRAW_LINE);
//----
 return(0);
}

void SaveLastReverse(int last, int dir, double sar5Start, double sar5Low, double sar5High,double sar5ExtremePoint, double sar){
 sar5SaveLastReverse = last;
 sar5SaveLastDirLong = dir;
 sar5SaveLastStart = sar5Start;
 sar5SaveLastLow = sar5Low;
 sar5SaveLastHigh = sar5High;
 sar5SaveLastExtremePoint = sar5ExtremePoint;
 sar5SaveLastSAR = sar;
}
void SaveBuffers(double sar5Parabola, int bar){
 sar5Parabola = NormalizeDouble(sar5Parabola,SAR5_Precision);
 sar5ParabolaBuffer[bar] = sar5Parabola; 
// if(sar5Parabola >= iHigh(Symbol(),0,bar)-SAR5_CrossoverNoiseFilter*myPoint){
// if(sar5Parabola >= Close[bar]-SAR5_CrossoverNoiseFilter*myPoint){
 if(sar5Parabola > Close[bar]+SAR5_DeadZone*myPoint){
  sarUp[bar] = 0;
  sarDn[bar] = sar5Parabola+SAR5_IndicatorMargin*myPoint;
 }else if(sar5Parabola < Close[bar]-SAR5_DeadZone*myPoint){
  sarUp[bar] = sar5Parabola-SAR5_IndicatorMargin*myPoint;  
  sarDn[bar] = 0;
 }else{
  sarUp[bar] = 0;  
  sarDn[bar] = 0;
 }
}
double SetPoint(string mySymbol){
 double mPoint, myDigits;
 myDigits = MarketInfo (mySymbol, MODE_DIGITS);
 if (myDigits < 4)
  mPoint = 0.01;
 else
  mPoint = 0.0001;
 return(mPoint);
}
//+------------------------------------------------------------------+
//| Parabolic Sell And Reverse system                                |
//+------------------------------------------------------------------+
int start(){
 static bool sar5First = true;
 bool   sar5DirLong;
 double sar5Start, sar5LastHigh, sar5LastLow;
 double sar5ExtremePoint, sar5SAR_Next, sar5Low, sar5High, sar5SAR_Now;
 int    bar, counted_bars = IndicatorCounted();
//----
 if(Bars < 3)return(0);
 
//---- initial settings
 bar = Bars - 2;
 
//----
 if(counted_bars == 0 || sar5First){
  sar5First = false;
  sar5DirLong = true;
  sar5Start = SAR5_Start;
  sar5LastHigh = -10000000.0;
  sar5LastLow = 10000000.0;
  //----
  while(bar > 0){
   sar5SaveLastReverse = bar;
   sar5Low = Low[bar];
   //----
   if(sar5LastLow > sar5Low)sar5LastLow = sar5Low;
   sar5High = High[bar];
   //----
   if(sar5LastHigh < sar5High)sar5LastHigh = sar5High;
   //----
   if(sar5High > High[bar+1] && sar5Low > Low[bar+1]) break;
   //----
   if(sar5High < High[bar+1] && sar5Low < Low[bar+1]){ 
    sar5DirLong = false; 
    break; 
   }
   bar--;
  }
  //---- initial zero
  int k = bar;
  Print("  k=", k, "  Bars=", Bars);      
  //----
  while(k < Bars){
   sar5ParabolaBuffer[k] = 0.0;
   k++;
  }
  //---- check further
  if(sar5DirLong){ 
   sar5ParabolaBuffer[bar] = Low[bar+1];
   sar5ExtremePoint = High[bar];
  }else{ 
   sar5ParabolaBuffer[bar] = High[bar+1]; 
   sar5ExtremePoint = Low[bar]; 
  }
  bar--;
 }else{
  bar =         sar5SaveLastReverse;
  sar5Start =     sar5SaveLastStart;
  sar5DirLong =   sar5SaveLastDirLong;
  sar5LastHigh = sar5SaveLastHigh;
  sar5LastLow =  sar5SaveLastLow;
  sar5ExtremePoint =        sar5SaveLastExtremePoint;
  sar5SAR_Next =       sar5SaveLastSAR;
  if(Time[0] != sar5SaveLastBartime){
   sar5SaveLastBartime = Time[0];
   bar++;
  }
 }
//----
 while(bar >= 0){
  sar5High = High[bar];
  sar5Low = Low[bar];
  
  //--- check for reverse from long to short
  if(sar5DirLong && sar5Low < sar5ParabolaBuffer[bar+1]-SAR5_CrossoverNoiseFilter*myPoint){
   SaveLastReverse(bar, true, sar5Start, sar5Low, sar5LastHigh, sar5ExtremePoint, sar5SAR_Next);
   sar5Start = SAR5_Start; 
   sar5DirLong = false;
   sar5ExtremePoint = sar5Low;  
   sar5LastLow = sar5Low;
   SaveBuffers(sar5LastHigh,bar);
   bar--;
   continue;//Go to next bar
  }
  
  //--- check for reverse from short to long  
  if(!sar5DirLong && sar5High > sar5ParabolaBuffer[bar+1]+SAR5_CrossoverNoiseFilter*myPoint){
   SaveLastReverse(bar, false, sar5Start, sar5LastLow, sar5High, sar5ExtremePoint, sar5SAR_Next);
   sar5Start = SAR5_Start; 
   sar5DirLong = true;
   sar5ExtremePoint = sar5High; 
   sar5LastHigh = sar5High;
   SaveBuffers(sar5LastLow,bar);
   bar--;
   continue;//Go to next bar
  }
  
  //--- no change in direction
  sar5SAR_Now = sar5ParabolaBuffer[bar+1];
  sar5SAR_Next = sar5SAR_Now + sar5Start*(sar5ExtremePoint - sar5SAR_Now);
  if(sar5DirLong){//Long
   if(sar5ExtremePoint < sar5High && (sar5Start + SAR5_Step) <= SAR5_Maximum) 
      sar5Start += SAR5_Step;
   if(sar5High < High[bar+1] && bar == Bars - 2)  
      sar5SAR_Next = sar5ParabolaBuffer[bar+1];
   sar5SAR_Now = Low[bar+1];
   if(sar5SAR_Next > sar5SAR_Now)
      sar5SAR_Next = sar5SAR_Now;
   sar5SAR_Now = Low[bar+2];
   if(sar5SAR_Next > sar5SAR_Now)
      sar5SAR_Next = sar5SAR_Now;
   if(sar5SAR_Next-SAR5_CrossoverNoiseFilter*myPoint > sar5Low){//Reverse To Short
    SaveLastReverse(bar, true, sar5Start, sar5Low, sar5LastHigh, sar5ExtremePoint, sar5SAR_Next);
    sar5Start = SAR5_Start; 
    sar5DirLong = false; 
    sar5ExtremePoint = sar5Low;
    sar5LastLow = sar5Low;
    SaveBuffers(sar5LastHigh,bar);
    bar--;
    continue;//Go to next bar
   }
   if(sar5ExtremePoint < sar5High){
    sar5LastHigh = sar5High;
    sar5ExtremePoint = sar5High;
   }
  }else{//Short
   if(sar5ExtremePoint > sar5Low && (sar5Start + SAR5_Step) <= SAR5_Maximum) 
      sar5Start += SAR5_Step;
   if(sar5Low < Low[bar+1] && bar == Bars - 2)  
      sar5SAR_Next = sar5ParabolaBuffer[bar+1];
   sar5SAR_Now = High[bar+1];
   if(sar5SAR_Next < sar5SAR_Now)
      sar5SAR_Next = sar5SAR_Now;
   sar5SAR_Now = High[bar+2];
   if(sar5SAR_Next < sar5SAR_Now)
      sar5SAR_Next = sar5SAR_Now;
   if(sar5SAR_Next+SAR5_CrossoverNoiseFilter*myPoint < sar5High){//Reverse To Long
    SaveLastReverse(bar, false, sar5Start, sar5LastLow, sar5High, sar5ExtremePoint,sar5SAR_Next);
    sar5Start = SAR5_Start; 
    sar5DirLong = true; 
    sar5ExtremePoint = sar5High;
    sar5LastHigh = sar5High;
    SaveBuffers(sar5LastLow,bar);
    bar--;
    continue;//Go to next bar
   }
   if(sar5ExtremePoint > sar5Low){
    sar5LastLow = sar5Low; 
    sar5ExtremePoint = sar5Low; 
   }
  }
  SaveBuffers(sar5SAR_Next,bar);
  bar--;
 }        
 return(0);
}
//+------------------------------------------------------------------+