SpearmanRankCorrelation_Histogram_Alerts

Author: Copyright © 2007, MetaQuotes Software Corp.
Miscellaneous
It issuies visual alerts to the screenIt sends emails
0 Views
0 Downloads
0 Favorites
SpearmanRankCorrelation_Histogram_Alerts
ÿþ//+------------------------------------------------------------------+

//|                     SpearmanRankCorrelation_Histogram_Alerts.mq5 |

//|                      Copyright © 2007, MetaQuotes Software Corp. |

//|                                        http://www.metaquotes.net |

//+------------------------------------------------------------------+

// http://www.infamed.com/stat/s05.html

#property copyright "Copyright © 2007, MetaQuotes Software Corp."

#property link      "http://www.metaquotes.net"

//---- =><5@ 25@A88 8=48:0B>@0

#property version   "1.00"

//---- >B@8A>2:0 8=48:0B>@0 2 >B45;L=>< >:=5

#property indicator_separate_window

//---- :>;8G5AB2> 8=48:0B>@=KE 1CD5@>2 2

#property indicator_buffers 2 

//---- 8A?>;L7>20=> 2A53> >4=> 3@0D8G5A:>5 ?>AB@>5=85

#property indicator_plots   1

//+----------------------------------------------+

//|  0@0<5B@K >B@8A>2:8 8=48:0B>@0              |

//+----------------------------------------------+

//---- >B@8A>2:0 8=48:0B>@0 2 2845 G5BK@QEF25B=>9 38AB>3@0<<K

#property indicator_type1 DRAW_COLOR_HISTOGRAM

//---- 2 :0G5AB25 F25B>2 G5BK@QEF25B=>9 38AB>3@0<<K 8A?>;L7>20=K

#property indicator_color1 clrMagenta,clrPurple,clrGray,clrBlue,clrDodgerBlue

//---- ;8=8O 8=48:0B>@0 - A?;>H=0O

#property indicator_style1 STYLE_SOLID

//---- B>;I8=0 ;8=88 8=48:0B>@0 @02=0 2

#property indicator_width1 2

//+----------------------------------------------+

//---- ?0@0<5B@K <8=8<0;L=>3> 8 <0:A8<0;L=>3> 7=0G5=89 8=48:0B>@0

#property indicator_minimum -1.0

#property indicator_maximum +1.0

//+----------------------------------------------+

//|  >1JO2;5=85 ?5@5G8A;5=89                     |

//+----------------------------------------------+

enum ENUM_APPLIED_PRICE_ //"8? :>=AB0=BK

  {

   PRICE_CLOSE_ = 1,     //PRICE_CLOSE

   PRICE_OPEN_,          //PRICE_OPEN

   PRICE_HIGH_,          //PRICE_HIGH

   PRICE_LOW_,           //PRICE_LOW

   PRICE_MEDIAN_,        //PRICE_MEDIAN

   PRICE_TYPICAL_,       //PRICE_TYPICAL

   PRICE_WEIGHTED_,      //PRICE_WEIGHTED

   PRICE_SIMPL_,         //PRICE_SIMPL_

   PRICE_QUARTER_,       //PRICE_QUARTER_

   PRICE_TRENDFOLLOW0_,  //PRICE_TRENDFOLLOW0_

   PRICE_TRENDFOLLOW1_,  // TrendFollow_2 Price 

   PRICE_DEMARK_         // Demark Price 

  };

//+----------------------------------------------+

//| E>4=K5 ?0@0<5B@K 8=48:0B>@0                 |

//+----------------------------------------------+

input int  rangeN=14;

input int  CalculatedBars=0;

input int  Maxrange=30;

input bool direction=true;

input ENUM_APPLIED_PRICE_ IPC=PRICE_CLOSE_;  // F5=>20O :>=AB0=B0

input double inHighLevel=+0.5;

input double inLowLevel=-0.5;

input uint NumberofBar=1;          // ><5@ 10@0 4;O ?>40G8 A83=0;0

input bool SoundON=true;           //  07@5H5=85 0;5@B0

input uint NumberofAlerts=2;       // >;8G5AB2> 0;5@B>2

input bool EMailON=false;          //  07@5H5=85 ?>GB>2>9 >B?@02:8 A83=0;0

input bool PushON=false;           //  07@5H5=85 >B?@02:8 A83=0;0 =0 <>18;L=K9

//+----------------------------------------------+

//---- 1JO2;5=85 F5;KE ?5@5<5==KE =0G0;0 >BAGQB0 40==KE

int min_rates_total;

//---- >1JO2;5=85 48=0<8G5A:8E <0AA82>2, :>B>@K5 1C4CB 2 40;L=59H5< 8A?>;L7>20=K 2 :0G5AB25 8=48:0B>@=KE 1CD5@>2

double IndBuffer[],ColorIndBuffer[];

double multiply;

double R2[],TrueRanks[];

int    PriceInt[],SortInt[],Maxrange_;

//+------------------------------------------------------------------+

//| calculate  RSP  function                                         |

//+------------------------------------------------------------------+

double SpearmanRankCorrelation(double &Ranks[],int N)

  {

//----

   double res,z2=0.0;



   for(int iii=0; iii<N; iii++) z2+=MathPow(Ranks[iii]-iii-1,2);

   res=1-6*z2/(MathPow(N,3)-N);

//----

   return(res);

  }

//+------------------------------------------------------------------+

//| Ranking array of prices function                                 |

//+------------------------------------------------------------------+

void RankPrices(double &TrueRanks_[],int &InitialArray[])

  {

//----

   int i,k,m,dublicat,counter,etalon;

   double dcounter,averageRank;



   ArrayCopy(SortInt,InitialArray,0,0,WHOLE_ARRAY);



   for(i=0; i<rangeN; i++) TrueRanks_[i]=i+1;

   

   ArraySort(SortInt);

   

   for(i=0; i<rangeN-1; i++)

     {

      if(SortInt[i]!=SortInt[i+1]) continue;



      dublicat=SortInt[i];

      k=i+1;

      counter=1;

      averageRank=i+1;



      while(k<rangeN)

        {

         if(SortInt[k]==dublicat)

           {

            counter++;

            averageRank+=k+1;

            k++;

           }

         else

            break;

        }

      dcounter=counter;

      averageRank=averageRank/dcounter;



      for(m=i; m<k; m++)

         TrueRanks_[m]=averageRank;

      i=k;

     }

   for(i=0; i<rangeN; i++)

     {

      etalon=InitialArray[i];

      k=0;

      while(k<rangeN)

        {

         if(etalon==SortInt[k])

           {

            R2[i]=TrueRanks_[k];

            break;

           }

         k++;

        }

     }

//----

   return;

  }

//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+  

void OnInit()

  {

//---- @0A?@545;5=85 ?0<OB8 ?>4 <0AA82K ?5@5<5==KE   

   ArrayResize(R2,rangeN);

   ArrayResize(PriceInt,rangeN);

   ArrayResize(SortInt,rangeN);

//---- 87<5=5=85 8=45:A0F88 M;5<5=B>2 2 <0AA825 ?5@5<5==KE

   if(direction) ArraySetAsSeries(SortInt,true);

   ArrayResize(TrueRanks,rangeN);

//---- 8=8F80;870F8O ?5@5<5==KE

   if(Maxrange<=0) Maxrange_=10;

   else Maxrange_=Maxrange;

   multiply=MathPow(10,_Digits);

//---- ?@52@0I5=85 48=0<8G5A:>3> <0AA820 IndBuffer 2 8=48:0B>@=K9 1CD5@

   SetIndexBuffer(0,IndBuffer,INDICATOR_DATA);

//---- >ACI5AB2;5=85 A42830 =0G0;0 >BAGQB0 >B@8A>2:8 8=48:0B>@0

   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,rangeN);

//---- CAB0=>2:0 7=0G5=89 8=48:0B>@0, :>B>@K5 =5 1C4CB 2848<K =0 3@0D8:5

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);

//---- 70?@5B =0 >B>1@065=85 7=0G5=89 8=48:0B>@0 2 ;52>< 25@E=5< C3;C >:=0 8=48:0B>@0

   PlotIndexSetInteger(0,PLOT_SHOW_DATA,false);

//---- 8=45:A0F8O M;5<5=B>2 2 1CD5@5 :0: 2 B09<A5@88

   ArraySetAsSeries(IndBuffer,true);

//---- ?@52@0I5=85 48=0<8G5A:>3> <0AA820 2 F25B>2>9, 8=45:A=K9 1CD5@   

   SetIndexBuffer(1,ColorIndBuffer,INDICATOR_COLOR_INDEX);

//---- 8=45:A0F8O M;5<5=B>2 2 1CD5@5 :0: 2 B09<A5@88

   ArraySetAsSeries(ColorIndBuffer,true);

//---- 8=8F80;870F88 ?5@5<5==>9 4;O :>@>B:>3> 8<5=8 8=48:0B>@0

   string shortname;

   if(rangeN>Maxrange_) shortname="Decrease rangeN input!";

   else StringConcatenate(shortname,"SpearmanRankCorrelation_Histogram_Alerts(",rangeN,")");

//--- A>740=85 <5B:8 4;O >B>1@065=8O 2 DataWindow

   PlotIndexSetString(0,PLOT_LABEL,shortname);

//--- A>740=85 8<5=8 4;O >B>1@065=8O 2 >B45;L=>< ?>4>:=5 8 2> 2A?;K20NI59 ?>4A:07:5

   IndicatorSetString(INDICATOR_SHORTNAME,shortname);

//--- >?@545;5=85 B>G=>AB8 >B>1@065=8O 7=0G5=89 8=48:0B>@0

   IndicatorSetInteger(INDICATOR_DIGITS,2);

//---- :>;8G5AB2>  3>@87>=B0;L=KE C@>2=59 8=48:0B>@0    

   IndicatorSetInteger(INDICATOR_LEVELS,3);

//---- 7=0G5=8O 3>@87>=B0;L=KE C@>2=59 8=48:0B>@0   

   IndicatorSetDouble(INDICATOR_LEVELVALUE,0,inHighLevel);

   IndicatorSetDouble(INDICATOR_LEVELVALUE,1,0);

   IndicatorSetDouble(INDICATOR_LEVELVALUE,2,inLowLevel);

//---- 2 :0G5AB25 F25B>2 ;8=89 3>@87>=B0;L=KE C@>2=59 8A?>;L7>20= @>7>2K9 8 A8=89 F25B0  

   IndicatorSetInteger(INDICATOR_LEVELCOLOR,0,clrMagenta);

   IndicatorSetInteger(INDICATOR_LEVELCOLOR,1,clrGray);

   IndicatorSetInteger(INDICATOR_LEVELCOLOR,2,clrBlue);

//---- 2 ;8=88 3>@87>=B0;L=>3> C@>2=O 8A?>;L7>20= :>@>B:89 HB@8E-?C=:B8@  

   IndicatorSetInteger(INDICATOR_LEVELSTYLE,0,STYLE_DASHDOTDOT);

   IndicatorSetInteger(INDICATOR_LEVELSTYLE,1,STYLE_DASH);

   IndicatorSetInteger(INDICATOR_LEVELSTYLE,2,STYLE_DASHDOTDOT);

//----

  }

//+------------------------------------------------------------------+

//| Custom indicator iteration function                              |

//+------------------------------------------------------------------+

int OnCalculate(

                const int rates_total,    // :>;8G5AB2> 8AB>@88 2 10@0E =0 B5:CI5< B8:5

                const int prev_calculated,// :>;8G5AB2> 8AB>@88 2 10@0E =0 ?@54K4CI5< B8:5

                const datetime &Time[],

                const double &Open[],

                const double &High[],

                const double &Low[],

                const double &Close[],

                const long &Tick_Volume[],

                const long &Volume[],

                const int &Spread[]

                )

  {

//---- ?@>25@:0 :>;8G5AB20 10@>2 =0 4>AB0B>G=>ABL 4;O @0AG5B0

   if(rates_total<rangeN) return(0);

   if(rangeN>Maxrange_) return(0);



//---- >1JO2;5=8O ;>:0;L=KE ?5@5<5==KE 

   int limit;



//---- @0AG5B AB0@B>2>3> =><5@0 limit 4;O F8:;0 ?5@5AG5B0 10@>2

   if(prev_calculated>rates_total || prev_calculated<=0) // ?@>25@:0 =0 ?5@2K9 AB0@B @0AG5B0 8=48:0B>@0

     {

      limit=rates_total-2-rangeN; // AB0@B>2K9 =><5@ 4;O @0AG5B0 2A5E 10@>2

     }

   else

     {

      if(!CalculatedBars) limit = rates_total - prev_calculated;

      else limit = CalculatedBars;

     }



//---- 8=45:A0F8O M;5<5=B>2 2 <0AA820E :0: 2 B09<A5@8OE 

   ArraySetAsSeries(Close,true);

   ArraySetAsSeries(Open,true); 

   ArraySetAsSeries(High,true); 

   ArraySetAsSeries(Low,true);

   ArraySetAsSeries(Spread,true); 



//---- >A=>2=>9 F8:; @0AG5B0 8=48:0B>@0

   for(int bar=limit; bar>=0 && !IsStopped(); bar--)

     {

      for(int k=0; k<rangeN; k++) PriceInt[k]=int(PriceSeries(IPC,bar+k,Open,Low,High,Close)*multiply);



      RankPrices(TrueRanks,PriceInt);

      IndBuffer[bar]=SpearmanRankCorrelation(R2,rangeN);

      

      int clr=2;

      double res=IndBuffer[bar];



      if(res>0)

        {

         if(res>inHighLevel) clr=4;

         else clr=3;

        }        

      if(res<0)

        {

         if(res<inLowLevel) clr=0;

         else clr=1;

        }        

      ColorIndBuffer[bar]=clr;

     }

//---     

   BuySignal("SpearmanRankCorrelation_Histogram_Alerts",rates_total,prev_calculated,Close,Spread);

   SellSignal("SpearmanRankCorrelation_Histogram_Alerts",rates_total,prev_calculated,Close,Spread);

//---           

   return(rates_total);

  }

//+------------------------------------------------------------------+

//| Buy signal function                                              |

//+------------------------------------------------------------------+

void BuySignal(string SignalSirname,      // B5:AB 8<5=8 8=48:0B>@0 4;O ?>GB>2KE 8 ?CH-A83=0;>2

               const int Rates_total,     // B5:CI55 :>;8G5AB2> 10@>2

               const int Prev_calculated, // :>;8G5AB2> 10@>2 =0 ?@54K4CI5< B8:5

               const double &Close[],     // F5=0 70:@KB8O

               const int &Spread[])       // A?@54

  {

//---

   static uint counter=0;

   if(Rates_total!=Prev_calculated) counter=0;



   string SignalText="";

   bool BuySignal=false;

   int index=int(NumberofBar);

   int index1=int(NumberofBar)+1;

   //--- 

   if(IndBuffer[index1]<=0 && IndBuffer[index]>0)  

     {

      BuySignal=true;

      SignalText=SignalText+"@>1>9 =C;O! ";

     }  

    //--- 

    if(ColorIndBuffer[index1]<4 && ColorIndBuffer[index]==4)

     {

      BuySignal=true;

      SignalText=SignalText+"@>1>9 C@>2=O ?5@5:C?;5==>AB8! ";

     } 

    //--- 

    if(ColorIndBuffer[index1]==1 && ColorIndBuffer[index]>2)

     {

      BuySignal=true;

      SignalText=SignalText+"KE>4 87 7>=K ?5@5?@>40==>AB8! ";

     }        

   //---              

   if(BuySignal && counter<=NumberofAlerts)

     {

      counter++;

      MqlDateTime tm;

      TimeToStruct(TimeCurrent(),tm);

      string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min);

      double Ask=Close[index];

      double Bid=Close[index];

      Bid+=Spread[index]*_Point;

      string sAsk=DoubleToString(Ask,_Digits);

      string sBid=DoubleToString(Bid,_Digits);

      string sPeriod=GetStringTimeframe(ChartPeriod());

      if(SoundON) Alert("BUY signal "+SignalText+"\n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);

      if(EMailON) SendMail(SignalSirname+": BUY signal "+SignalText," at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);

      if(PushON) SendNotification(SignalSirname+": BUY signal "+SignalText+" at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);

     }



//---

  }

//+------------------------------------------------------------------+

//| Sell signal function                                             |

//+------------------------------------------------------------------+

void SellSignal(string SignalSirname,      // B5:AB 8<5=8 8=48:0B>@0 4;O ?>GB>2KE 8 ?CH-A83=0;>2

                const int Rates_total,     // B5:CI55 :>;8G5AB2> 10@>2

                const int Prev_calculated, // :>;8G5AB2> 10@>2 =0 ?@54K4CI5< B8:5

                const double &Close[],     // F5=0 70:@KB8O

                const int &Spread[])       // A?@54

  {

//---

   static uint counter=0;

   if(Rates_total!=Prev_calculated) counter=0;

   string SignalText="";

   bool SellSignal=false;

   int index=int(NumberofBar);

   int index1=int(NumberofBar)+1;

   //---   

   if(IndBuffer[index1]>=0 && IndBuffer[index]<0)

     {

      SellSignal=true;

      SignalText=SignalText+"@>1>9 =C;O! ";

     }  

    //--- 

    if(ColorIndBuffer[index1]>0 && ColorIndBuffer[index]==0)

     {

      SellSignal=true;

      SignalText=SignalText+"@>1>9 C@>2=O ?5?@>40==>AB8! ";

     }  

    //--- 

    if(ColorIndBuffer[index1]==4 && ColorIndBuffer[index]<4)

     {

      SellSignal=true;

      SignalText=SignalText+"KE>4 87 7>=K ?5@5:C?;5==>AB8! ";

     }       

   //--

   if(SellSignal && counter<=NumberofAlerts)

     {

      counter++;

      MqlDateTime tm;

      TimeToStruct(TimeCurrent(),tm);

      string text=TimeToString(TimeCurrent(),TIME_DATE)+" "+string(tm.hour)+":"+string(tm.min);

      double Ask=Close[index];

      double Bid=Close[index];

      Bid+=Spread[index]*_Point;

      string sAsk=DoubleToString(Ask,_Digits);

      string sBid=DoubleToString(Bid,_Digits);

      string sPeriod=GetStringTimeframe(ChartPeriod());

      if(SoundON) Alert("SELL signal "+SignalText+"\n Ask=",Ask,"\n Bid=",Bid,"\n currtime=",text,"\n Symbol=",Symbol()," Period=",sPeriod);

      if(EMailON) SendMail(SignalSirname+": SELL signal "+SignalText," at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);

      if(PushON) SendNotification(SignalSirname+": SELL signal "+SignalText+" at Ask="+sAsk+", Bid="+sBid+", Date="+text+" Symbol="+Symbol()+" Period="+sPeriod);

     }

//---

  }

//+------------------------------------------------------------------+

//|  >;CG5=85 B09<D@59<0 2 2845 AB@>:8                              |

//+------------------------------------------------------------------+

string GetStringTimeframe(ENUM_TIMEFRAMES timeframe)

  {

//----

   return(StringSubstr(EnumToString(timeframe),7,-1));

//----

  }

//+------------------------------------------------------------------+   

//| >;CG5=85 7=0G5=8O F5=>2>9 B09<A5@88                             |

//+------------------------------------------------------------------+ 

double PriceSeries

(

 uint applied_price,// &5=>20O :>=AB0=B0

 uint   bar,// =45:A A42830 >B=>A8B5;L=> B5:CI53> 10@0 =0 C:070==>5 :>;8G5AB2> ?5@8>4>2 =0704 8;8 2?5@Q4).

 const double &Open[],

 const double &Low[],

 const double &High[],

 const double &Close[]

 )

//PriceSeries(applied_price, bar, open, low, high, close)

//+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+

  {

//----

   switch(applied_price)

     {

      //---- &5=>2K5 :>=AB0=BK 87 ?5@5G8A;5=8O ENUM_APPLIED_PRICE

      case  PRICE_CLOSE: return(Close[bar]);

      case  PRICE_OPEN: return(Open [bar]);

      case  PRICE_HIGH: return(High [bar]);

      case  PRICE_LOW: return(Low[bar]);

      case  PRICE_MEDIAN: return((High[bar]+Low[bar])/2.0);

      case  PRICE_TYPICAL: return((Close[bar]+High[bar]+Low[bar])/3.0);

      case  PRICE_WEIGHTED: return((2*Close[bar]+High[bar]+Low[bar])/4.0);



      //----                            

      case  8: return((Open[bar] + Close[bar])/2.0);

      case  9: return((Open[bar] + Close[bar] + High[bar] + Low[bar])/4.0);

      //----                                

      case 10:

        {

         if(Close[bar]>Open[bar])return(High[bar]);

         else

           {

            if(Close[bar]<Open[bar])

               return(Low[bar]);

            else return(Close[bar]);

           }

        }

      //----         

      case 11:

        {

         if(Close[bar]>Open[bar])return((High[bar]+Close[bar])/2.0);

         else

           {

            if(Close[bar]<Open[bar])

               return((Low[bar]+Close[bar])/2.0);

            else return(Close[bar]);

           }

         break;

        }

      //----         

      case 12:

        {

         double res=High[bar]+Low[bar]+Close[bar];

         if(Close[bar]<Open[bar]) res=(res+Low[bar])/2;

         if(Close[bar]>Open[bar]) res=(res+High[bar])/2;

         if(Close[bar]==Open[bar]) res=(res+Close[bar])/2;

         return(((res-Low[bar])+(res-High[bar]))/2);

        }

      //----

      default: return(Close[bar]);

     }

//----

//return(0);

  }

//+------------------------------------------------------------------+

Comments