rsi_ma_trade_sist_chart
Download scriptThis script is a specialized trading indicator designed for the MetaTrader 4 platform. It provides visual guidance on price charts by combining three core technical analysis components: two Moving Averages (EMAs) and the Relative Strength Index (RSI). Its primary purpose is to identify trend reversals and momentum shifts, providing clear "Buy" and "Sell" signals directly on the chart.
Core Trading Logic
The indicator monitors the relationship between fast-moving price trends and overall market momentum to determine entry points:
1. Trend Identification (Moving Averages) The script tracks two Exponential Moving Averages (EMAs)—a "Fast" and a "Slow" version.
- When the Fast EMA crosses above the Slow EMA, it suggests upward momentum.
- When the Fast EMA crosses below the Slow EMA, it suggests downward momentum.
2. Momentum Confirmation (RSI) To filter out "fake" signals caused by minor price fluctuations, the script uses the Relative Strength Index (RSI). It looks for specific momentum thresholds:
- For a Buy Signal, the RSI must be above the 50 level (indicating bullish strength).
- For a Sell Signal, the RSI must be below the 50 level (indicating bearish weakness).
Signal Execution
The script generates a visual signal only when specific conditions are met simultaneously:
- Buy Signal: Triggered when the Fast EMA crosses above the Slow EMA while the RSI is already above 50, or if the RSI crosses above 50 at the exact moment of the trend shift.
- Sell Signal: Triggered when the Fast EMA crosses below the Slow EMA while the RSI is already below 50, or if the RSI crosses below 50 at the exact moment of the trend shift.
Visual and Notification Features
Beyond just plotting lines, the script provides several layers of information for the user:
- Visual Markers: It places distinct arrows on the chart to highlight exactly where a Buy or Sell signal occurs.
- Dynamic Labels: It creates text labels on the screen that display the signal type (Buy/Sell) along with the specific opening price at the time of the signal.
- Real-time Alerts: The script is equipped to notify the trader immediately via three different channels (pop-up alerts, emails, or push notifications), provided the user has enabled these options in the settings.
- Clean Interface: It includes an automatic cleanup function that ensures old labels are removed from the chart, keeping the workspace organized.
Summary for the User
Essentially, this tool acts as a "filter." Instead of reacting to every tiny price movement, it waits for a confirmed trend change (the Moving Average cross) backed by significant momentum (the RSI position). This helps traders stay on the right side of the market by ensuring that entries align with both the current direction and the underlying strength of the price movement.
//+------------------------------------------------------------------+
//| RSI_MA_Trade_Sist_Chart.mq4 |
//| Yuriy Tokman (YTG) |
//| http://ytg.com.ua/ |
//+------------------------------------------------------------------+
#property copyright "Yuriy Tokman (YTG)"
#property link "http://ytg.com.ua/"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Blue
#property indicator_color4 Red
#property indicator_color5 Lime
extern int FastEMA = 5;
extern int SlowEMA = 12;
extern int RSIPeriod = 21;
input int shift = 1;
extern bool Alerts = true;
extern string Text_BUY = "BUY signal text";
extern string Text_SELL = "SELL signals text";
extern bool Send_Mail = false;
extern string subject = "subject text";
extern bool Send_Notification = false;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double ExtMapBuffer5[];
bool metka_buy=false;
bool metka_sell=false;
string text="",name="RSI_MA_Trade_Sist_Chart";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
IndicatorShortName(name);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexLabel(0,"Fast EMA ");
SetIndexDrawBegin(0,FastEMA);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexLabel(1,"Slow EMA ");
SetIndexDrawBegin(1,SlowEMA);
SetIndexStyle(2,DRAW_ARROW);
SetIndexArrow(2,217);
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexEmptyValue(2,0.0);
SetIndexLabel(2,"BUY Signal ");
SetIndexStyle(3,DRAW_ARROW);
SetIndexArrow(3,218);
SetIndexBuffer(3,ExtMapBuffer4);
SetIndexEmptyValue(3,0.0);
SetIndexLabel(3,"SELL Signal ");
SetIndexStyle(4,DRAW_LINE);
SetIndexBuffer(4,ExtMapBuffer5);
SetIndexLabel(4,"RSI ");
SetIndexDrawBegin(4,RSIPeriod);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
GetDellName();
//----
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[])
{
//---
double rsi_sig=0,fast_sig=0,slow_sig=0,price_OP=0;
double rsi_sig_prev=0,fast_sig_prev=0,slow_sig_prev=0;
string txt=WindowExpertName()+" "+Symbol()+" "+GetNameTF()+" ";
//---
int limit=rates_total-prev_calculated;
if(prev_calculated==0)limit--;
else limit++;
for(int i=limit; i>=0 && !IsStopped(); i--)
{
ExtMapBuffer1[i] = iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i);
ExtMapBuffer2[i] = iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
ExtMapBuffer5[i] = iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i) - (50 - iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE,i))*Point;
fast_sig = iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i+shift);
slow_sig = iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i+shift);
rsi_sig = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE,i+shift);
fast_sig_prev = iMA(NULL,0,FastEMA,0,MODE_EMA,PRICE_CLOSE,i+shift+1);
slow_sig_prev = iMA(NULL,0,SlowEMA,0,MODE_EMA,PRICE_CLOSE,i+shift+1);
rsi_sig_prev = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE,i+shift+1);
if(((fast_sig>slow_sig && rsi_sig>50 && fast_sig_prev<=slow_sig_prev)
|| (fast_sig>slow_sig && rsi_sig>50 && rsi_sig_prev<=50)) && !metka_buy)
{
metka_sell= false;
metka_buy = true;
ExtMapBuffer3[i]=slow_sig-iATR(Symbol(),0,10,i)/2;
price_OP=Bid;
text=" Price Open = "+DoubleToStr(price_OP,Digits);
Label("ytg_name_label","Buy,"+text,1,3,15,10,"Arial",Green,name);
if(i==0 && NewBar())
{
if(Alerts)Alert(txt+Text_BUY+text);
if(Send_Mail)SendMail(txt+subject,Text_BUY+text);
if(Send_Notification)SendNotification(txt+Text_BUY+text);
}
}
if(((fast_sig<slow_sig && rsi_sig<50 && fast_sig_prev>=slow_sig_prev)
|| (fast_sig<slow_sig && rsi_sig<50 && rsi_sig_prev>=50)) && !metka_sell)
{
metka_sell= true;
metka_buy = false;
ExtMapBuffer4[i]=slow_sig+iATR(Symbol(),0,10,i)/2;
price_OP=Ask;
text=" Price Open = "+DoubleToStr(price_OP,Digits);
Label("ytg_name_label","Sell,"+text,3,3,15,10,"Arial",Red,name);
if(i==0 && NewBar())
{
if(Alerts)Alert(txt+Text_SELL+text);
if(Send_Mail)SendMail(txt+subject,Text_SELL+text);
if(Send_Notification)SendNotification(txt+Text_SELL+text);
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
bool NewBar(int TF=0)
{
static datetime NewTime=0;
if(NewTime!=iTime(Symbol(),TF,0))
{
NewTime=iTime(Symbol(),TF,0);
return(true);
}
return(false);
}
//----
string GetNameTF(int TimeFrame=0)
{
if(TimeFrame==0) TimeFrame=Period();
switch(TimeFrame)
{
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("Daily");
case PERIOD_W1: return("Weekly");
case PERIOD_MN1: return("Monthly");
default: return("UnknownPeriod");
}
}
//+----------------------------------------------------------------------+
//| Îïèñàíèå: Ñîçäàíèå òåêñòîâîé ìåòêè |
//| Àâòîð: Þðèé Òîêìàíü |
//| e-mail: yuriytokman@gmail.com |
//+----------------------------------------------------------------------+
void Label(string name_label,//Èìÿ îáúåêòà.
string text_label, //Òåêñò îáüåêòà.
int corner = 2, //Hîìåð óãëà ïðèâÿçêè
int x = 3, //Pàññòîÿíèå X-êîîðäèíàòû â ïèêñåëÿõ
int y=15,//Pàññòîÿíèå Y-êîîðäèíàòû â ïèêñåëÿõ
int font_size = 10, //Ðàçìåð øðèôòà â ïóíêòàõ.
string font_name = "Arial", //Íàèìåíîâàíèå øðèôòà.
color text_color = LimeGreen,//Öâåò òåêñòà.
string Window_Find="NULL"
)
{
if(ObjectFind(name_label)!=-1) ObjectDelete(name_label);
ObjectCreate(name_label,OBJ_LABEL,0/*WindowFind(Window_Find)*/,0,0,0,0);
ObjectSet(name_label,OBJPROP_CORNER,corner);
ObjectSet(name_label,OBJPROP_XDISTANCE,x);
ObjectSet(name_label,OBJPROP_YDISTANCE,y);
ObjectSetText(name_label,text_label,font_size,font_name,text_color);
}
//----
void GetDellName(string name_n="ytg_")
{
string vName;
for(int i=ObjectsTotal()-1; i>=0;i--)
{
vName=ObjectName(i);
if(StringFind(vName,name_n)!=-1) ObjectDelete(vName);
}
}
//----
Comments