0% found this document useful (0 votes)
36 views7 pages

Multi-Timeframe Stochastic RSI Indicator

The document is a code for a custom MetaTrader 4 indicator called MultiTimeframe_StochasticRSI, which combines Stochastic and RSI indicators across multiple timeframes. It includes various customizable parameters for signal detection, alert settings, and visual representation of buy and sell signals. The indicator is designed to provide both repainting and non-repainting signals, with options for alerts and notifications.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views7 pages

Multi-Timeframe Stochastic RSI Indicator

The document is a code for a custom MetaTrader 4 indicator called MultiTimeframe_StochasticRSI, which combines Stochastic and RSI indicators across multiple timeframes. It includes various customizable parameters for signal detection, alert settings, and visual representation of buy and sell signals. The indicator is designed to provide both repainting and non-repainting signals, with options for alerts and notifications.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

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

//| MultiTimeframe_StochasticRSI.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property link ""
#property version "1.23"
#property strict
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 7 // Increased to accommodate new signal buffers
#property indicator_color1 DodgerBlue // Stochastic Main Line (K)
#property indicator_color2 Red // Stochastic Signal Line (D)
#property indicator_color3 Aqua // RSI Line
#property indicator_color4 Lime // Buy Signal (Non-Repainting)
#property indicator_color5 Red // Sell Signal (Non-Repainting)
#property indicator_color6 Green // Buy Signal (Repainting)
#property indicator_color7 Crimson // Sell Signal (Repainting)
#property indicator_width1 2
#property indicator_width2 1
#property indicator_width3 2
#property indicator_width4 1
#property indicator_width5 1
#property indicator_width6 1
#property indicator_width7 1
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_SOLID
#property indicator_style3 STYLE_SOLID

// Input parameters
input ENUM_TIMEFRAMES Signal_Timeframe = PERIOD_CURRENT; // Timeframe for signals
input int K_Period = 5; // Stochastic %K period
input int D_Period = 54; // Stochastic %D period
input int Slowing = 1; // Stochastic slowing
input int RSI_Period = 8; // RSI period
input int Signal_Shift = 0; // Signal shift (0 = no shift)
input bool Non_Repainting = true; // Enable non-repainting mode
input int Max_History_Bars = 1000; // Maximum history bars for signals

// Arrow settings
input double Arrow_Vertical_Shift = 5; // Vertical shift for arrows (positive =
up, negative = down)
input int Buy_Arrow_Code = 233; // Buy signal arrow code (233 = Up arrow)
input int Sell_Arrow_Code = 234; // Sell signal arrow code (234 = Down
arrow)
input int RepaintBuy_Arrow_Code = 159; // Repainting buy signal arrow code (159
= Hollow circle)
input int RepaintSell_Arrow_Code = 159; // Repainting sell signal arrow code
(159 = Hollow circle)
input double Repainting_Vertical_Gap = 3.0; // Gap between repainting and non-
repainting signals

input ENUM_APPLIED_PRICE RSI_Price = PRICE_CLOSE; // RSI price


input ENUM_MA_METHOD MA_Method = MODE_SMA; // Moving average method
input bool Show_MTF_Info = true; // Show timeframe information in indicator
name
input bool Show_Repainting_Signals = true; // Show repainting signals
// Alert settings
input bool Enable_Alerts = false; // Enable alerts
input bool Alert_NonRepainting = true; // Alert on non-repainting signals only
input bool Alert_Repainting = false; // Alert on repainting signals
input bool Enable_Push_Notifications = false; // Enable push notifications
input bool Enable_Email_Alerts = false; // Enable email alerts
input int Alert_Cooldown = 300; // Cooldown between alerts (seconds)
input string Email_Subject = "StochRSI Alert"; // Email subject

// Indicator buffers
double StochMainBuffer[]; // Stochastic Main (K)
double StochSignalBuffer[]; // Stochastic Signal (D)
double RSIBuffer[]; // RSI line
double BuySignalBuffer[]; // Buy signals (Non-Repainting)
double SellSignalBuffer[]; // Sell signals (Non-Repainting)
double BuySignalRepaintBuffer[]; // Buy signals (Repainting)
double SellSignalRepaintBuffer[]; // Sell signals (Repainting)

// Variables for non-repainting logic


datetime LastSignalTime = 0;
datetime LastAlertTime = 0; // Track last alert time for cooldown

// Variables for storing crossover detection


bool PreviousCrossBuy[1000];
string TimeframeStr = "";

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set indicator buffers
SetIndexBuffer(0, StochMainBuffer);
SetIndexBuffer(1, StochSignalBuffer);
SetIndexBuffer(2, RSIBuffer);
SetIndexBuffer(3, BuySignalBuffer);
SetIndexBuffer(4, SellSignalBuffer);
SetIndexBuffer(5, BuySignalRepaintBuffer);
SetIndexBuffer(6, SellSignalRepaintBuffer);

// Set indicator labels


SetIndexLabel(0, "Stoch Main");
SetIndexLabel(1, "Stoch Signal");
SetIndexLabel(2, "RSI");
SetIndexLabel(3, "Buy Signal (Confirmed)");
SetIndexLabel(4, "Sell Signal (Confirmed)");
SetIndexLabel(5, "Buy Signal (Real-time)");
SetIndexLabel(6, "Sell Signal (Real-time)");

// Set drawing settings


SetIndexStyle(0, DRAW_LINE);
SetIndexStyle(1, DRAW_LINE);
SetIndexStyle(2, DRAW_LINE);
SetIndexStyle(3, DRAW_ARROW); // Use arrows for buy signals (non-repainting)
SetIndexStyle(4, DRAW_ARROW); // Use arrows for sell signals (non-repainting)
SetIndexStyle(5, DRAW_ARROW); // Use arrows for buy signals (repainting)
SetIndexStyle(6, DRAW_ARROW); // Use arrows for sell signals (repainting)
SetIndexArrow(3, Buy_Arrow_Code); // Customizable arrow for non-
repainting buy signals
SetIndexArrow(4, Sell_Arrow_Code); // Customizable arrow for non-
repainting sell signals
SetIndexArrow(5, RepaintBuy_Arrow_Code); // Customizable arrow for repainting
buy signals
SetIndexArrow(6, RepaintSell_Arrow_Code); // Customizable arrow for repainting
sell signals

// Set draw begin for each buffer (to ensure history is displayed)
SetIndexDrawBegin(0, K_Period + D_Period + Slowing);
SetIndexDrawBegin(1, K_Period + D_Period + Slowing);
SetIndexDrawBegin(2, RSI_Period);

// Set empty values for signal buffers to prevent connecting lines


SetIndexEmptyValue(3, 0.0);
SetIndexEmptyValue(4, 0.0);
SetIndexEmptyValue(5, 0.0);
SetIndexEmptyValue(6, 0.0);

// Initialize signal tracking array


ArrayInitialize(PreviousCrossBuy, false);

// Get timeframe string for display


TimeframeStr = GetTimeframeStr(Signal_Timeframe);

// Set indicator name


string indicatorName = "StochasticRSI Cross ("
+ IntegerToString(K_Period) + ","
+ IntegerToString(D_Period) + ","
+ IntegerToString(Slowing) + ","
+ IntegerToString(RSI_Period) + ")";

// Add timeframe info if enabled


if(Show_MTF_Info && Signal_Timeframe != PERIOD_CURRENT) {
indicatorName += " [" + TimeframeStr + "]";
}

IndicatorShortName(indicatorName);

// Check email alerts configuration


if(Enable_Email_Alerts) {
// Display a message about checking email settings
Print("Email alerts enabled. Ensure your MetaTrader email settings are
properly configured.");
}

// Initialize LastAlertTime
LastAlertTime = 0;

return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 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[])
{
int limit, counted_bars = prev_calculated;

// Calculate starting bar


if(counted_bars < 0) return(-1);
if(counted_bars > 0) counted_bars--;

int limit_bars = MathMin(rates_total - counted_bars, Max_History_Bars);

// Clear buffers on first calculation


if(counted_bars == 0) {
ArrayInitialize(BuySignalBuffer, 0);
ArrayInitialize(SellSignalBuffer, 0);
ArrayInitialize(BuySignalRepaintBuffer, 0);
ArrayInitialize(SellSignalRepaintBuffer, 0);

// Initialize signal tracking array


ArrayInitialize(PreviousCrossBuy, false);
}

// Variables for alerts


bool buySignalDetected = false;
bool sellSignalDetected = false;
bool buyRepaintSignalDetected = false;
bool sellRepaintSignalDetected = false;

// First pass: Calculate indicator values


for(int i = MathMin(rates_total - 1, limit_bars); i >= 0; i--)
{
// Get the corresponding time for the selected timeframe
datetime curr_time = time[i];

// Calculate Stochastic and RSI using the selected timeframe


if(Signal_Timeframe == PERIOD_CURRENT) {
// Use current timeframe
StochMainBuffer[i] = iStochastic(NULL, 0, K_Period, D_Period, Slowing,
MA_Method, 0, MODE_MAIN, i);
StochSignalBuffer[i] = iStochastic(NULL, 0, K_Period, D_Period, Slowing,
MA_Method, 0, MODE_SIGNAL, i);
RSIBuffer[i] = iRSI(NULL, 0, RSI_Period, RSI_Price, i);
} else {
// Use multi-timeframe approach
StochMainBuffer[i] = iStochastic(NULL, Signal_Timeframe, K_Period,
D_Period, Slowing, MA_Method, 0, MODE_MAIN, iBarShift(NULL, Signal_Timeframe,
curr_time));
StochSignalBuffer[i] = iStochastic(NULL, Signal_Timeframe, K_Period,
D_Period, Slowing, MA_Method, 0, MODE_SIGNAL, iBarShift(NULL, Signal_Timeframe,
curr_time));
RSIBuffer[i] = iRSI(NULL, Signal_Timeframe, RSI_Period, RSI_Price,
iBarShift(NULL, Signal_Timeframe, curr_time));
}
// Initialize signal buffers for this bar
BuySignalBuffer[i] = 0;
SellSignalBuffer[i] = 0;
BuySignalRepaintBuffer[i] = 0;
SellSignalRepaintBuffer[i] = 0;
}

// Second pass: Process signals separately for repainting and non-repainting


modes
for(int i = MathMin(rates_total - 1, limit_bars); i >= 0; i--)
{
// Skip if not enough bars for calculation
if(i >= rates_total-1 || i < 1) continue;

// Detecting signal conditions


bool buyCondition = RSIBuffer[i+1] >= StochMainBuffer[i+1] && RSIBuffer[i] <
StochMainBuffer[i];
bool sellCondition = RSIBuffer[i+1] <= StochMainBuffer[i+1] && RSIBuffer[i] >
StochMainBuffer[i];

// FIRST: Process repainting signals (real-time)


if(Show_Repainting_Signals) {
// BUY signal: RSI crosses BELOW Stochastic Main
if(buyCondition) {
BuySignalRepaintBuffer[i + Signal_Shift] = 15 + Arrow_Vertical_Shift -
Repainting_Vertical_Gap;

// Set flag for repainting buy signal


if(i == 0) buyRepaintSignalDetected = true;
}

// SELL signal: RSI crosses ABOVE Stochastic Main


if(sellCondition) {
SellSignalRepaintBuffer[i + Signal_Shift] = 85 - Arrow_Vertical_Shift +
Repainting_Vertical_Gap;

// Set flag for repainting sell signal


if(i == 0) sellRepaintSignalDetected = true;
}
}

// SECOND: Process non-repainting signals (confirmed only)


if(i > 0) {
// Historical bars: process normally
if(buyCondition) {
BuySignalBuffer[i + Signal_Shift] = 15 + Arrow_Vertical_Shift;
}
if(sellCondition) {
SellSignalBuffer[i + Signal_Shift] = 85 - Arrow_Vertical_Shift;
}
}
else if(i == 0 && (!Non_Repainting || time[0] != LastSignalTime)) {
// Current bar: check if we should process it
if(buyCondition) {
BuySignalBuffer[i + Signal_Shift] = 15 + Arrow_Vertical_Shift;
buySignalDetected = true;
}
if(sellCondition) {
SellSignalBuffer[i + Signal_Shift] = 85 - Arrow_Vertical_Shift;
sellSignalDetected = true;
}

// Update last signal time if in non-repainting mode


if(Non_Repainting) {
LastSignalTime = time[0];
}
}
}

// Process alerts if enabled and cooldown period has passed


if(Enable_Alerts && (TimeCurrent() - LastAlertTime > Alert_Cooldown)) {
string alertMessage = "";
bool sendAlert = false;

// Check for non-repainting signals


if(Alert_NonRepainting) {
if(buySignalDetected) {
alertMessage = Symbol() + " " + TimeframeToString(Period()) + ":
StochRSI BUY Signal (Confirmed)";
sendAlert = true;
}
else if(sellSignalDetected) {
alertMessage = Symbol() + " " + TimeframeToString(Period()) + ":
StochRSI SELL Signal (Confirmed)";
sendAlert = true;
}
}

// Check for repainting signals if no non-repainting signal was triggered


if(!sendAlert && Alert_Repainting) {
if(buyRepaintSignalDetected) {
alertMessage = Symbol() + " " + TimeframeToString(Period()) + ":
StochRSI BUY Signal (Real-time)";
sendAlert = true;
}
else if(sellRepaintSignalDetected) {
alertMessage = Symbol() + " " + TimeframeToString(Period()) + ":
StochRSI SELL Signal (Real-time)";
sendAlert = true;
}
}

// Send alert if triggered


if(sendAlert) {
// Regular MetaTrader alert
Alert(alertMessage);

// Push notification
if(Enable_Push_Notifications) {
SendNotification(alertMessage);
}

// Email alert
if(Enable_Email_Alerts) {
SendMail(Email_Subject, alertMessage);
}

// Update last alert time


LastAlertTime = TimeCurrent();
}
}

return(rates_total);
}

//+------------------------------------------------------------------+
//| Convert timeframe to readable string |
//+------------------------------------------------------------------+
string GetTimeframeStr(ENUM_TIMEFRAMES timeframe)
{
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 "D1";
case PERIOD_W1: return "W1";
case PERIOD_MN1: return "MN";
default: return "Current";
}
}

//+------------------------------------------------------------------+
//| Convert Period() to readable string |
//+------------------------------------------------------------------+
string TimeframeToString(int timeframe)
{
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 "D1";
case PERIOD_W1: return "W1";
case PERIOD_MN1: return "MN";
default: return "Unknown";
}
}
//+------------------------------------------------------------------+

You might also like