Here's a breakdown of what the script does, explained in a way that someone without programming knowledge can understand:
This script is a tool for the MetaTrader 4 platform designed to help traders identify potential buying and selling opportunities based on "waves" in the price movements of a currency pair. It attempts to identify trends across multiple timeframes to give a more comprehensive view.
Here's a simplified explanation of the key aspects:
-
What it does: The script analyzes the price history of a currency pair to find patterns resembling waves. When it detects an upward wave, it suggests a potential "buy" signal. When it detects a downward wave, it suggests a potential "sell" signal. The more timeframes that agree on the wave direction, the stronger the signal.
-
Timeframes: The script analyzes price data across multiple timeframes (e.g., 1-minute, 5-minute, 1-hour, daily charts). This helps determine if the wave pattern is consistent across different perspectives. The trader can set the beginning and ending timeframes to be analyzed.
-
Alerts: The script can generate alerts to notify the trader of potential trading opportunities. These alerts can be pop-up messages on the screen, email notifications, or push notifications to a mobile device.
-
Visuals: The script can display arrows on the chart to indicate the direction of the waves (up for buy, down for sell). It also displays text information about the currency pair, account details, and the indicator's signal.
-
How it Works (Simplified):
- The script first gathers price data (high, low, close) for the selected currency pair across different timeframes.
- It then calculates a moving average, which is like a line that smooths out the price data to show the general trend.
- The script compares the current price to the moving average on each timeframe.
- Based on these comparisons, it determines the direction of the "wave" (up or down) on each timeframe.
- If enough timeframes show a consistent upward wave, the script generates a "buy" signal. If enough timeframes show a downward wave, it generates a "sell" signal.
-
Inputs: The trader can customize the script's behavior by adjusting several input parameters, such as:
- Which timeframes to consider
- Whether to display alerts
- The colors of the arrows
- Whether to send email or mobile notifications
Important Note: This script provides potential trading signals based on a specific analysis method. It's crucial to understand that no trading system is perfect, and all trading involves risk. The signals generated by this script should not be blindly followed but rather used as one piece of information in a broader trading strategy.
//+------------------------------------------------------------------+
//| WaveMTF.mq4 |
//| Copyright 2019, Roberto Jacobs (3rjfx) |
//| https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Roberto Jacobs (3rjfx) ~ By 3rjfx ~ Created: 2019/01/26"
#property link "https://www.mql5.com/en/users/3rjfx"
#property version "2.00"
#property strict
#property description "Indicator WaveMTF Bull and Bear System with Signal and Alert"
#property description "for MetaTrader 4 with options to display signal on the chart."
/* Update_01: 2019/02/23 ~ Remove any of bugs and error, and the not used code. */
#property description "version: 2.00 ~ Last update 27/08/2020"
/*
Update version 2.00
~ Fix buffers error
*/
//--
#property indicator_chart_window
#property indicator_buffers 2
//--
//--
enum YN
{
No,
Yes
};
//--
enum corner
{
NotShow=-1, // Not Show Arrow
topchart=0, // On Top Chart
bottomchart=1 // On Bottom Chart
};
//--
enum StrTF
{
M1, // TF-M1
M5, // TF-M5
M15, // TF-M15
M30, // TF-M30
H1, // TF-H1
H4, // TF-H4
D1, // TF-D1
W1, // TF-W1
MN // TF-MN
};
//--
//--
input StrTF stf = M5; // Time Frames Calculation Signal Starts
input StrTF etf = D1; // Last Time Frames Calculation Signal
input corner cor = topchart; // Arrow Move Position
input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No)
input YN EmailAlert = No; // Email Alert (Yes) or (No)
input YN sendnotify = No; // Send Notification (Yes) or (No)
input YN displayinfo = Yes; // Display Trade Info
input color textcolor = clrSnow; // Text Color
input color ArrowUp = clrLime; // Arrow Up Color
input color ArrowDn = clrRed; // Arrow Down Color
input color NTArrow = clrYellow; // Arrow No Signal
//---
//---- indicator buffers
double BufferUp[];
double BufferDn[];
//--
//--- spacing
int scaleX=35,scaleY=40,scaleYt=18,offsetX=250,offsetY=3,fontSize=7; // coordinate
int txttf,
arrtf;
color arclr;
ENUM_BASE_CORNER bcor;
//--- arrays for various things
int BBTF[]={1,5,15,30,60,240,1440,10080,43200};
int XBB[10];
string periodStr[]={"M1","M5","M15","M30","H1","H4","D1","W1","MN","MOVE"}; // Text Timeframes
//--
double
pricepos;
datetime
cbartime;
int cur,prv;
int imnn,imnp;
int cmnt,pmnt;
int arr;
long CI;
static int fbar;
string posisi,
sigpos,
iname,
msgText;
string frtext="wave";
#define MAX_BAR 120
//---------//
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
IndicatorBuffers(2);
//--
SetIndexBuffer(0,BufferUp);
SetIndexBuffer(1,BufferDn);
//--
SetIndexStyle(0,DRAW_NONE);
SetIndexStyle(1,DRAW_NONE);
//--
//----
//-- name for DataWindow
SetIndexLabel(0,"Bullish");
SetIndexLabel(1,"Bearish");
//--
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
//---- indicator short name
IndicatorDigits(_Digits);
iname=WindowExpertName();
IndicatorShortName(iname);
CI=ChartID();
arr=ArraySize(XBB);
//--
if(cor>=0)
{
if(cor==topchart) {bcor=CORNER_LEFT_UPPER; txttf=45; arrtf=-20;}
if(cor==bottomchart) {bcor=CORNER_LEFT_LOWER; txttf=45; arrtf=-12;}
}
else
{
string name;
for(int i=ObjectsTotal()-1; i>=0; i--)
{
name=ObjectName(i);
if(StringFind(name,frtext,0)>-1) ObjectDelete(0,name);
}
}
//--
//---
return(INIT_SUCCEEDED);
}
//---------//
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
Comment("");
string name;
for(int i=ObjectsTotal()-1; i>=0; i--)
{
name=ObjectName(i);
if(StringFind(name,frtext,0)>-1) ObjectDelete(0,name);
}
//--
GlobalVariablesDeleteAll();
//----
return(0);
}
//---------//
//+------------------------------------------------------------------+
//| 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[])
{
//---
//--- Set Last error value to Zero
ResetLastError();
RefreshRates();
//---
int limit=0,barc;
//--- check for rates total
if(rates_total>MAX_BAR) limit=MAX_BAR;
barc=limit-1;
//--
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(time,true);
//--
ArrayResize(BufferUp,limit);
ArrayResize(BufferDn,limit);
ArraySetAsSeries(BufferUp,true);
ArraySetAsSeries(BufferDn,true);
//--
int tfcnt=etf-stf;
arclr=NTArrow;
//--
imnn=Seconds();
//--
if(imnn!=imnp)
{
for(int w=barc; w>=0; w--)
{
int tr=0,xbup=0,xbdn=0,i;
cbartime=time[w];
if(cor>=0)
{
for(int x=0; x<arr; x++)
{
CreateArrowLabel(CI,frtext+"_tfx_arrow_"+string(x),periodStr[x],"Bodoni MT Black",fontSize,textcolor,bcor,
txttf+x*scaleX+offsetX,scaleY+offsetY+7,true); //"Georgia" "Bodoni MT Black" "Verdana" "Arial Black"
}
}
//--
for(i=0; i<arr-1; i++)
{
XBB[i]=GetDirection(BBTF[i],w);
if(cor>=0)
{
if(XBB[i]>0) arclr=ArrowUp;
if(XBB[i]<0) arclr=ArrowDn;
CreateArrowLabel(CI,frtext+"_win_arrow_"+string(i),CharToString(108),"Wingdings",14,arclr,bcor,
txttf+i*scaleX+offsetX,arrtf+scaleY+offsetY+7,true);
}
if(i>=stf && i<=etf)
{
if(XBB[i]>0) xbup++;
if(XBB[i]<0) xbdn++;
}
}
if(i==9)
{
if(xbup>=tfcnt)
{
tr=1;
XBB[i]=xbup;
arclr=ArrowUp;
BufferUp[w]=GetPrice(_Period,tr,w);
BufferDn[w]=0.0;
pricepos=BufferUp[w];
cur=1;
fbar=iBarShift(Symbol(),0,cbartime,false);
}
else
if(xbdn>=tfcnt)
{
tr=-1;
XBB[i]=xbdn;
arclr=ArrowDn;
BufferDn[w]=GetPrice(_Period,tr,w);
BufferUp[w]=0.0;
pricepos=BufferDn[w];
cur=-1;
fbar=iBarShift(Symbol(),0,cbartime,false);
}
else
{
XBB[i]=0;
arclr=NTArrow;
BufferDn[w]=0.0;
BufferUp[w]=0.0;
pricepos=close[w];
cur=0;
fbar=iBarShift(Symbol(),0,cbartime,false);
}
//--
if(cor>=0) CreateArrowLabel(CI,frtext+"_win_arrow_"+string(i),CharToString(108),"Wingdings",14,arclr,bcor,
txttf+i*scaleX+offsetX+8,arrtf+scaleY+offsetY+7,true);
}
}
//--
imnp=imnn;
}
//--
if(alerts==Yes||EmailAlert==Yes||sendnotify==Yes) Do_Alerts(cur,fbar);
if(displayinfo==Yes) ChartComm();
//--
//--- return value of prev_calculated for next call
return(rates_total);
}
//---------//
// getting the price direction
int GetDirection(int xtf,int bar)
{
//---
int ret=0;
RefreshRates();
//--
double ptpc1=(iHigh(Symbol(),xtf,bar+1)+iLow(Symbol(),xtf,bar+1)+iClose(Symbol(),xtf,bar+1))/3;
double ptpc0=(iHigh(Symbol(),xtf,bar)+iLow(Symbol(),xtf,bar)+iClose(Symbol(),xtf,bar))/3;
//--
double mapw1=iMA(Symbol(),xtf,13,0,MODE_SMMA,PRICE_WEIGHTED,bar+1);
double mapw0=iMA(Symbol(),xtf,13,0,MODE_SMMA,PRICE_WEIGHTED,bar);
//--
double bb1=ptpc1-mapw1;
double bb0=ptpc0-mapw0;
//--
if(bb0>bb1) ret=1;
if(bb0<bb1) ret=-1;
//--
return(ret);
//---
}
//---------//
// getting the price position
double GetPrice(int xtf,int bb,int bx)
{
//---
int bar=30;
double ppos=0;
//--
int HH=iHighest(Symbol(),xtf,MODE_HIGH,bar,bx);
int LL=iLowest(Symbol(),xtf,MODE_LOW,bar,bx);
//--
if(bb>0) {ppos=iLow(Symbol(),xtf,LL); cbartime=iTime(Symbol(),xtf,LL);}
if(bb<0) {ppos=iHigh(Symbol(),xtf,HH); cbartime=iTime(Symbol(),xtf,HH);}
//--
return(ppos);
//---
}
//---------//
void Do_Alerts(int fcur,int fb)
{
//--
cmnt=Minute();
if(cmnt!=pmnt)
{
//--
if(fcur==1)
{
msgText="Wave Price Up Start"+" at bars: "+string(fb);
posisi="Bullish";
sigpos="Open BUY Order";
}
else
if(fcur==-1)
{
msgText="Wave Price Down Start"+" at bars: "+string(fb);
posisi="Bearish";
sigpos="Open SELL Order";
}
else
{
msgText="Wave Price Not Found!";
posisi="Not Found!";
sigpos="Wait for Confirmation!";
}
//--
if(fcur!=prv)
{
Print(iname,"--- "+Symbol()+" "+TF2Str(_Period)+": "+msgText+
"\n--- at: ",TimeToString(iTime(Symbol(),0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);
//--
if(alerts==Yes)
Alert(iname,"--- "+Symbol()+" "+TF2Str(_Period)+": "+msgText+
"--- at: ",TimeToString(iTime(Symbol(),0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);
//--
if(EmailAlert==Yes)
SendMail(iname,"--- "+Symbol()+" "+TF2Str(_Period)+": "+msgText+
"\n--- at: "+TimeToString(iTime(Symbol(),0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);
//--
if(sendnotify==Yes)
SendNotification(iname+"--- "+Symbol()+" "+TF2Str(_Period)+": "+msgText+
"\n--- at: "+TimeToString(iTime(Symbol(),0,0),TIME_DATE|TIME_MINUTES)+" - "+sigpos);
//--
prv=fcur;
}
//--
pmnt=cmnt;
}
//--
return;
//---
}
//---------//
string TF2Str(int period)
{
//---
switch(period)
{
//--
case PERIOD_M1: return("M1");
case PERIOD_M5: return("M5");
case PERIOD_M15: return("M15");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H4: return("H4");
case PERIOD_D1: return("D1");
case PERIOD_W1: return("W1");
case PERIOD_MN1: return("MN");
//--
}
//--
return(string(period));
//---
}
//---------//
string AccountMode() // function: to known account trade mode
{
//----
//--- Demo, Contest or Real account
ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE);
//---
string trade_mode;
//--
switch(account_type)
{
case ACCOUNT_TRADE_MODE_DEMO:
trade_mode="Demo";
break;
case ACCOUNT_TRADE_MODE_CONTEST:
trade_mode="Contest";
break;
default:
trade_mode="Real";
break;
}
//--
return(trade_mode);
//----
} //-end AccountMode()
//---------//
void ChartComm() // function: write comments on the chart
{
//----
//--
Comment("\n :: Server Date Time : ",(string)Year(),".",(string)Month(),".",(string)Day(), " ",TimeToString(TimeCurrent(),TIME_SECONDS),
"\n ------------------------------------------------------------",
"\n :: Broker : ",TerminalCompany(),
"\n :: Acc. Name : ",AccountName(),
"\n :: Acc, Number : ",(string)AccountNumber(),
"\n :: Acc,TradeMode : ",AccountMode(),
"\n :: Acc. Leverage : 1 : ",(string)AccountLeverage(),
"\n :: Acc. Balance : ",DoubleToString(AccountBalance(),2),
"\n :: Acc. Equity : ",DoubleToString(AccountEquity(),2),
"\n --------------------------------------------",
"\n :: Indicator Name : ",iname,
"\n :: Currency Pair : ",Symbol(),
"\n :: Current Spread : ",IntegerToString(SymbolInfoInteger(Symbol(),SYMBOL_SPREAD),0),
"\n :: Signal Start : at bar ",string(iBarShift(Symbol(),0,cbartime,false)),
"\n :: Wave Start : ",DoubleToString(pricepos,_Digits),
"\n :: Indicator Signal : ",posisi,
"\n :: Suggested : ",sigpos);
//---
ChartRedraw();
return;
//----
} //-end ChartComm()
//---------//
bool CreateArrowLabel(long chart_id,
string lable_name,
string label_text,
string font_model,
int font_size,
color label_color,
int chart_corner,
int x_cor,
int y_cor,
bool price_hidden)
{
//---
//--
ObjectDelete(chart_id,lable_name);
//--
if(!ObjectCreate(chart_id,lable_name,OBJ_LABEL,0,0,0,0,0))
{
//Print(__FUNCTION__,
// ": failed to create \"Arrow Label\" sign! Error code = ",GetLastError());
return(false);
}
//--
ObjectSetString(chart_id,lable_name,OBJPROP_TEXT,label_text);
ObjectSetString(chart_id,lable_name,OBJPROP_FONT,font_model);
ObjectSetInteger(chart_id,lable_name,OBJPROP_FONTSIZE,font_size);
ObjectSetInteger(chart_id,lable_name,OBJPROP_COLOR,label_color);
ObjectSetInteger(chart_id,lable_name,OBJPROP_CORNER,chart_corner);
ObjectSetInteger(chart_id,lable_name,OBJPROP_XDISTANCE,x_cor);
ObjectSetInteger(chart_id,lable_name,OBJPROP_YDISTANCE,y_cor);
ObjectSetInteger(chart_id,lable_name,OBJPROP_HIDDEN,price_hidden);
//--- successful execution
return(true);
//--
}
//---------//
//+------------------------------------------------------------------+
Comments