#property  copyright "Copyright © 2005, Yura Prokofiev"
#property  link      "Yura.prokofiev@gmail.com"

#property  indicator_separate_window
#property  indicator_buffers 3
#property  indicator_color1  Black
#property  indicator_color2  Lime
#property  indicator_color3  Red
 
extern int period=10;
extern int bars_count=1000;
extern string ahi0=" ******* Alert settings:";
extern bool PopupAlerts            = TRUE;
extern bool EmailAlerts            = FALSE;
extern bool PushNotificationAlerts = FALSE;
extern bool SoundAlerts            = FALSE;
extern string SoundFileLong        = "alert.wav";
extern string SoundFileShort       = "alert2.wav";
bool alarm=true;
double         ExtBuffer0[];
double         ExtBuffer1[];
double         ExtBuffer2[];

int alertBar,last;
int init()
  {
   
   
   SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,2,Red);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,2,Lime);
   SetIndexStyle(2,DRAW_HISTOGRAM);
   IndicatorDigits(Digits+1);

   SetIndexBuffer(0,ExtBuffer0);
   SetIndexBuffer(1,ExtBuffer1);
   SetIndexBuffer(2,ExtBuffer2);

   IndicatorShortName("Fisher");
   SetIndexLabel(1,NULL);
   SetIndexLabel(2,NULL);

   return(0);
  }


int start()
  {
   //int     period=10;
   int    limit;
   int    counted_bars=IndicatorCounted();
   double prev,current,old;
   double Value=0,Value1=0,Value2=0,Fish=0,Fish1=0,Fish2=0;
   double price;
   double MinL=0;
   double MaxH=0;  
   

   if(counted_bars>0) counted_bars--;
   if(bars_count > Bars || bars_count==0)
   {
      limit=Bars - period;
   }
   else
   {
      limit=bars_count-period;
   }


   for(int i=0; i<limit; i++)
    {  MaxH = High[Highest(NULL,0,MODE_HIGH,period,i)];
       MinL = Low[Lowest(NULL,0,MODE_LOW,period,i)];
      price = (High[i]+Low[i])/2;
      Value = 0.33*2*((price-MinL)/(MaxH-MinL)-0.5) + 0.67*Value1;     
      Value=MathMin(MathMax(Value,-0.999),0.999); 
      ExtBuffer0[i]=0.5*MathLog((1+Value)/(1-Value))+0.5*Fish1;
      Value1=Value;
      Fish1=ExtBuffer0[i];
      
    }


   bool up=true;
   for(i=limit-2; i>=0; i--)
     {
      current=ExtBuffer0[i];
      prev=ExtBuffer0[i+1];
           
      if (((current<0)&&(prev>0))||(current<0))   up= false;    
      if (((current>0)&&(prev<0))||(current>0))   up= true;
      
      if(!up)
        {
         ExtBuffer2[i]=current;
         ExtBuffer1[i]=0.0;
         if (alarm && i==0 && last != 2 && ExtBuffer1[i] == 0 && Bars>alertBar) 
        {
            doAlerts("crossing Down",SoundFileShort);//Alert("Fisher Crossing Down on ",Period()," ",Symbol());
            alertBar = Bars;last = 2;
        }
        }
       else
         {
          ExtBuffer1[i]=current;
          ExtBuffer2[i]=0.0;
          if (alarm && i==0 && last != 1 && ExtBuffer2[i] == 0 && Bars>alertBar) 
        {
            doAlerts("crossing UP",SoundFileLong);//Alert("Fisher Crossing Up on ",Period()," ",Symbol());
            alertBar = Bars;
            last = 1;
         }
     }}

   return(0);
  }
  void doAlerts(string msg,string SoundFile) {
        msg="Fisher_Yur4ik_Correct Alert on "+Symbol()+", period "+TFtoStr(Period())+": "+msg+", bid = "+DoubleToStr(MarketInfo(Symbol(),MODE_BID),Digits)+", servertime: "+TimeToStr(TimeCurrent());
 string emailsubject="MT4 alert on acc. "+AccountNumber()+", "+WindowExpertName()+" - Alert on "+Symbol()+", period "+TFtoStr(Period());
  if (PopupAlerts) Alert(msg);
  if (EmailAlerts) SendMail(emailsubject,msg);
  if (PushNotificationAlerts) SendNotification(msg);
  if (SoundAlerts) PlaySound(SoundFile);
}//void doAlerts(string msg,string SoundFile) {

string TFtoStr(int period) {
 if (period==0) period=Period();
 switch(period) {
  case 1     : return("M1");  break;
  case 5     : return("M5");  break;
  case 15    : return("M15"); break;
  case 30    : return("M30"); break;
  case 60    : return("H1");  break;
  case 240   : return("H4");  break;
  case 1440  : return("D1");  break;
  case 10080 : return("W1");  break;
  case 43200 : return("MN1"); break;
  default    : return(DoubleToStr(period,0));
 }
 return("UNKNOWN");
}//string TFtoStr(int period) {