FX_FISH_2MA

Author: Copyright 2018, MetaQuotes Software Corp.
Price Data Components
0 Views
0 Downloads
0 Favorites
FX_FISH_2MA
ÿþ//+------------------------------------------------------------------+

//|                                                  FX_FISH_2MA.mq5 |

//|                        Copyright 2018, MetaQuotes Software Corp. |

//|                                                 https://mql5.com |

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

#property copyright "Copyright 2018, MetaQuotes Software Corp."

#property link      "https://mql5.com"

#property version   "1.00"

#property description "Forex Fish 2MA indicator"

#property indicator_separate_window

#property indicator_buffers 5

#property indicator_plots   3

//--- plot OSC

#property indicator_label1  "FxFish2MA"

#property indicator_type1   DRAW_COLOR_HISTOGRAM

#property indicator_color1  clrLimeGreen,clrDarkSeaGreen,clrOrangeRed,clrDarkSalmon,clrDarkGray

#property indicator_style1  STYLE_SOLID

#property indicator_width1  8

//--- plot MA1

#property indicator_label2  "Signal 1"

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrTomato

#property indicator_style2  STYLE_SOLID

#property indicator_width2  1

//--- plot MA2

#property indicator_label3  "Signal 2"

#property indicator_type3   DRAW_LINE

#property indicator_color3  clrBlue

#property indicator_style3  STYLE_SOLID

#property indicator_width3  1

//--- enums

enum ENUM_INPUT_YES_NO

  {

   INPUT_YES   =  1,    // Yes

   INPUT_NO    =  0     // No

  };

//---

enum ENUM_APPLIED_PRICE_EXT

  {

   PRICE_CLOSE_EXT      =  PRICE_CLOSE,      // Close

   PRICE_OPEN_EXT       =  PRICE_OPEN,       // Open

   PRICE_HIGH_EXT       =  PRICE_HIGH,       // High

   PRICE_LOW_EXT        =  PRICE_LOW,        // Low

   PRICE_MEDIAN_EXT     =  PRICE_MEDIAN,     // Median (High+Low)/2

   PRICE_TYPICAL_EXT    =  PRICE_TYPICAL,    // Typical (High+Low+Close)/3

   PRICE_WEIGHTED_EXT   =  PRICE_WEIGHTED,   // Weighted (High+Low+Close*2)/4

   PRICE_MEDIAN_BODY    =  PRICE_WEIGHTED+1  // Median body (Open+Close)/2

  };

//--- input parameters

input uint                    InpPeriod         =  30;               // Period

input ENUM_APPLIED_PRICE_EXT  InpAppliedPrice   =  PRICE_CLOSE_EXT;  // Applied price

input uint                    InpPeriodMA1      =  1;                // First MA period

input uint                    InpPeriodMA2      =  5;                // Second MA period

input ENUM_MA_METHOD          InpMethodMA1      =  MODE_EMA;         // First MA method

input ENUM_MA_METHOD          InpMethodMA2      =  MODE_EMA;         // Second MA method

input double                  InpThreshold      =  0.0;              // Threshold

input ENUM_INPUT_YES_NO       InpReverseSig     =  INPUT_NO;         // Reverse signals

input ENUM_INPUT_YES_NO       InpShowSig        =  INPUT_NO;         // Show signal descriptions

input color                   InpColorEntryB    =  clrBlue;          // Entry Buy color

input color                   InpColorExitB     =  clrDodgerBlue;    // Exit Buy color

input color                   InpColorEntryS    =  clrRed;           // Entry Sell color

input color                   InpColorExitS     =  clrDarkOrange;    // Exit Sell color

input ENUM_INPUT_YES_NO       InpUseAlert       =  INPUT_YES;        // Use alerts

input ENUM_INPUT_YES_NO       InpSendMail       =  INPUT_NO;         // Send mail

input ENUM_INPUT_YES_NO       InpSendPush       =  INPUT_YES;        // Send push-notifications

//--- indicator buffers

double         BufferOSC[];

double         BufferColors[];

double         BufferMA1[];

double         BufferMA2[];

double         BufferPrice[];

//--- global variables

string         prefix;

double         threshold;

int            period_ma1;

int            period_ma2;

int            range;

int            period_max;

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- set global variables

   prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_";

   period_ma1=int(InpPeriodMA1<1 ? 1 : InpPeriodMA1);

   period_ma2=int(InpPeriodMA2<1 ? 1 : InpPeriodMA2);

   range=int(InpPeriod<1 ? 1 : InpPeriod);

   period_max=fmax(range,fmax(period_ma1,period_ma2));

   threshold=InpThreshold;

//--- indicator buffers mapping

   SetIndexBuffer(0,BufferOSC,INDICATOR_DATA);

   SetIndexBuffer(1,BufferColors,INDICATOR_COLOR_INDEX);

   SetIndexBuffer(2,BufferMA1,INDICATOR_DATA);

   SetIndexBuffer(3,BufferMA2,INDICATOR_DATA);

   SetIndexBuffer(4,BufferPrice,INDICATOR_CALCULATIONS);

//--- setting buffer arrays as timeseries

   ArraySetAsSeries(BufferOSC,true);

   ArraySetAsSeries(BufferColors,true);

   ArraySetAsSeries(BufferMA1,true);

   ArraySetAsSeries(BufferMA2,true);

   ArraySetAsSeries(BufferPrice,true);

//--- setting plot buffers parameters

   PlotIndexSetString(0,PLOT_LABEL,"FxFish2MA("+(string)range+")");

   PlotIndexSetString(1,PLOT_LABEL,MethodToString(InpMethodMA1)+"("+(string)period_ma1+")");

   PlotIndexSetString(2,PLOT_LABEL,MethodToString(InpMethodMA2)+"("+(string)period_ma2+")");

//--- setting indicator parameters

   IndicatorSetString(INDICATOR_SHORTNAME,"FxFish2MA("+(string)range+","+(string)period_ma1+","+(string)period_ma2+")");

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

   if(threshold>0)

     {

      IndicatorSetInteger(INDICATOR_LEVELS,2);

      IndicatorSetDouble(INDICATOR_LEVELVALUE,0,threshold);

      IndicatorSetDouble(INDICATOR_LEVELVALUE,1,-threshold);

      IndicatorSetString(INDICATOR_LEVELTEXT,0,"Upper threshold");

      IndicatorSetString(INDICATOR_LEVELTEXT,1,"Lower threshold");

     }

   else

      IndicatorSetInteger(INDICATOR_LEVELS,0);

//---

   return(INIT_SUCCEEDED);

  }

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

//| Custom indicator deinitialization function                       |

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

void OnDeinit(const int reason)

  {

//--- delete objects

   ObjectsDeleteAll(0,prefix,0);

   ChartRedraw();

//---

  }

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

//| Custom indicator iteration function                              |

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

int OnCalculate(const int rates_total,

                const int prev_calculated,

                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[])

  {

//--- #AB0=>2:0 <0AA82>2 1CD5@>2 :0: B09<A5@89

   ArraySetAsSeries(open,true);

   ArraySetAsSeries(high,true);

   ArraySetAsSeries(low,true);

   ArraySetAsSeries(close,true);

   ArraySetAsSeries(time,true);

//--- @>25@:0 :>;8G5AB20 4>ABC?=KE 10@>2

   if(rates_total<fmax(period_max,4)) return 0;

//--- @>25@:0 8 @0AGQB :>;8G5AB20 ?@>AG8BK205<KE 10@>2

   int limit=rates_total-prev_calculated;

   if(limit>1)

     {

      limit=rates_total-2;

      ArrayInitialize(BufferOSC,EMPTY_VALUE);

      ArrayInitialize(BufferColors,4);

      ArrayInitialize(BufferMA1,EMPTY_VALUE);

      ArrayInitialize(BufferMA2,EMPTY_VALUE);

      ArrayInitialize(BufferPrice,0);

     }

//--- >43>B>2:0 40==KE

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

     {

      switch(InpAppliedPrice)

        {

         case PRICE_CLOSE_EXT    :  BufferPrice[i]=close[i];                        break;

         case PRICE_OPEN_EXT     :  BufferPrice[i]=open[i];                         break;

         case PRICE_HIGH_EXT     :  BufferPrice[i]=high[i];                         break;

         case PRICE_LOW_EXT      :  BufferPrice[i]=low[i];                          break;

         case PRICE_MEDIAN_EXT   :  BufferPrice[i]=(high[i]+low[i])/2.0;            break;

         case PRICE_TYPICAL_EXT  :  BufferPrice[i]=(high[i]+low[i]+close[i])/3.0;   break;

         case PRICE_WEIGHTED_EXT :  BufferPrice[i]=(high[i]+low[i]+close[i]*2)/4.0; break;

         //---PRICE_MEDIAN_BODY

         default                 :  BufferPrice[i]=(open[i]+close[i])/2.0;          break;

        }

     }

   

//---  0AGQB 8=48:0B>@0

   double value=0,value1=0,fish=0,fish1=0,fish2=0;

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

     {

      int bh=iHighest(NULL,PERIOD_CURRENT,MODE_HIGH,range,i);

      int bl=iLowest(NULL,PERIOD_CURRENT,MODE_LOW,range,i);

      if(bh==WRONG_VALUE || bl==WRONG_VALUE)

         continue;

      double maxh = high[bh];

      double minl = low[bl];

      if(maxh==0 || minl==0)

         continue;



      double v=0.33*2*((BufferPrice[i]-minl)/(maxh-minl)-0.5)+0.67*value1;

      value=fmin(fmax(v,-0.999),0.999);

      fish=0.5*log((1+value)/(1-value))+0.5*fish1;



      if(fish<0 && fish1>0)

        {

         if(InpShowSig)

           {

            string op=(InpReverseSig ? "sell" : "buy");

            color  clr=(InpReverseSig ? InpColorExitS : InpColorExitB);

            ENUM_ANCHOR_POINT anchor=(InpReverseSig ? ANCHOR_LEFT_UPPER : ANCHOR_LEFT_LOWER);

            DrawText(prefix+"exit_"+op+"_"+TimeToString(time[i]),0,BufferPrice[i],time[i],clr,8,anchor,"Exit "+op+" at "+DoubleToString(BufferPrice[i],Digits()));

           }

        }

      if(fish>0 && fish1<0)

        {

         if(InpShowSig)

           {

            string op=(InpReverseSig ? "buy" : "sell");

            color  clr=(InpReverseSig ? InpColorExitB : InpColorExitS);

            ENUM_ANCHOR_POINT anchor=(InpReverseSig ? ANCHOR_LEFT_LOWER : ANCHOR_LEFT_UPPER);

            DrawText(prefix+"exit_"+op+"_"+TimeToString(time[i]),0,BufferPrice[i],time[i],clr,8,anchor,"Exit "+op+" at "+DoubleToString(BufferPrice[i],Digits()));

           }

        }

      BufferOSC[i]=fish;

      BufferColors[i]=

        (

         fish>0 ? (BufferOSC[i]>BufferOSC[i+1] ? 0 : 1) : 

         fish<0 ? (BufferOSC[i]<BufferOSC[i+1] ? 2 : 3) : 

         4

        );



      if(fish<-threshold && fish>fish1 && fish1<=fish2)

        {

         if(InpShowSig)

           {

            string op=(InpReverseSig ? "buy" : "sell");

            color  clr=(InpReverseSig ? InpColorEntryB : InpColorEntryS);

            ENUM_ANCHOR_POINT anchor=(InpReverseSig ? ANCHOR_LEFT_UPPER : ANCHOR_LEFT_LOWER);

            DrawText(prefix+"entry_"+op+"_"+TimeToString(time[i]),0,BufferPrice[i],time[i],clr,8,anchor,"Entry "+op+" at "+DoubleToString(BufferPrice[i],Digits()));

           }

        }



      if(fish>threshold && fish<fish1 && fish1>=fish2)

        {

         if(InpShowSig)

           {

            string op=(InpReverseSig ? "sell" : "buy");

            color  clr=(InpReverseSig ? InpColorEntryS : InpColorEntryB);

            ENUM_ANCHOR_POINT anchor=(InpReverseSig ? ANCHOR_LEFT_LOWER : ANCHOR_LEFT_UPPER);

            DrawText(prefix+"entry_"+op+"_"+TimeToString(time[i]),0,BufferPrice[i],time[i],clr,8,anchor,"Entry "+op+" at "+DoubleToString(BufferPrice[i],Digits()));

           }

        }

      value1=value;

      fish2=fish1;

      fish1=fish;

     }

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

     {

      BufferMA1[i]=GetMA(rates_total,i,InpMethodMA1,period_ma1,BufferOSC,BufferMA1);

      BufferMA2[i]=GetMA(rates_total,i,InpMethodMA2,period_ma2,BufferMA1,BufferMA2);

     }

   

//--- return value of prev_calculated for next call

   return(rates_total);

  }

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

//| >72@0I05B MA ?> B8?C                                            |

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

double GetMA(const int rates_total,const int shift,const ENUM_MA_METHOD method,const int period_ma,const double &buffer_price[],const double &buffer_ma[])

  {

   switch(method)

     {

      case MODE_EMA  : return EMA(rates_total,buffer_price[shift],buffer_ma[shift+1],period_ma,shift);

      case MODE_SMMA : return SMMA(rates_total,buffer_price,buffer_ma[shift+1],period_ma,shift);

      case MODE_LWMA : return LWMA(rates_total,buffer_price,period_ma,shift);

      //---MODE_SMA

      default        : return SMA(rates_total,buffer_price,period_ma,shift);

     }

  }

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

//| Simple Moving Average                                            |

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

double SMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return array_src[shift];

   double sum=0;

   for(int i=0; i<period; i++)

      sum+=array_src[shift+i];

   return(sum/period);

  }

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

//| Exponential Moving Average                                       |

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

double EMA(const int rates_total,const double price,const double prev,const int period,const int shift)

  {

   return(shift>=rates_total-2 || period<1 ? price : prev+2.0/(1+period)*(price-prev));

  }

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

//| Linear Weighted Moving Average                                   |

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

double LWMA(const int rates_total,const double &array_src[],const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double sum=0;

   double weight=0;

   for(int i=0; i<period; i++)

     {

      weight+=(period-i);

      sum+=array_src[shift+i]*(period-i);

     }

   return(weight>0 ? sum/weight : 0);

  }

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

//| Smoothed Moving Average                                          |

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

double SMMA(const int rates_total,const double &array_src[],const double prev,const int period,const int shift)

  {

   if(period<1 || shift>rates_total-period-1)

      return 0;

   double smma=0;

   if(shift==rates_total-period-1)

      smma=SMA(rates_total,array_src,period,shift);

   else if(shift<rates_total-period-1)

     {

      double sum=0;

      for(int i = 0; i<period; i++)

         sum+=array_src[shift+i+1];

      smma=(sum-prev+array_src[shift])/period;

     }

   return smma;

  }

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

//| >72@0I05B =08<5=>20=85 <5B>40                                 |

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

string MethodToString(ENUM_MA_METHOD method)

  {

   return StringSubstr(EnumToString(method),5);

  }

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

//| K2>48B B5:AB                                                    |

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

void DrawText(const string name,

              const int sub_win,

              const double price,

              const datetime time,

              const color text_color,

              const int font_size,

              const ENUM_ANCHOR_POINT anchor,

              const string text,

              const string font_name="Calibri",

              const string tooltip="\n")

  {

   if(ObjectFind(0,name)<0)

     {

      ObjectCreate(0,name,OBJ_TEXT,sub_win,time,price);

      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);

      ObjectSetInteger(0,name,OBJPROP_SELECTED,false);

      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);

      ObjectSetString(0,name,OBJPROP_FONT,font_name);

     }

   ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor);

   ObjectSetInteger(0,name,OBJPROP_TIME,0,time);

   ObjectSetDouble(0,name,OBJPROP_PRICE,0,price);

//---

   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,font_size);

   ObjectSetInteger(0,name,OBJPROP_COLOR,text_color);

   ObjectSetString(0,name,OBJPROP_TEXT,text);

   ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);

  }

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

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---