Price Data Components
1
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 Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---