Author: Roberto Jacobs (3rjfx) | Featured on Forex Home Expert
Introduction
Following the release of StochDegree in the previous article, many traders ask: "How do we know exactly when to enter the market?" To answer this, I developed StochasticTrends.mq5. Created on March 31, 2026, this indicator is designed to simplify market noise and provide clear, actionable signals for both "Buy" and Sell" opportunities.
The StochasticTrends.mq5 indicator builds on the classic Stochastic Oscillator to provide clear signals of bullish and bearish momentum. By plotting arrows and triggering alerts, it helps traders identify when to open buy or sell positions with confidence.
Concept - The Logic Behind the Arrows
While StochDegree focuses on momentum strength, StochasticTrends focuses on the structural shift of the Stochastic Oscillator.
- Signal Generation: The indicator monitors the crossover and direction of the Stochastic Main Line. The StochasticTrends indicator detects shifts in momentum by comparing recent Stochastic values. When conditions align, it plots arrows above or below price bars and issues alerts:
- Up Trend → Signals potential buy opportunities.
- Down Trend → Signals potential sell opportunities.
- Smart Alert System: Visual arrows and alerts make trend changes easy to spot in real time. It doesn't just show arrows; it is equipped with a
PosAlertsfunction that can send notifications directly to your phone or email the moment a new trend is confirmed
//+------------------------------------------------------------------+
//| StochasticTrends.mq5 |
//| Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-03-31 |
//| https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-03-31"
#property link "https://www.mql5.com/en/users/3rjfx"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 4
#property indicator_color2 clrWhite
#property indicator_color3 clrRed
#property indicator_color4 clrWhite,clrRed
#property indicator_type1 DRAW_NONE
#property indicator_type2 DRAW_ARROW
#property indicator_type3 DRAW_ARROW
#property indicator_type4 DRAW_COLOR_ARROW
#property indicator_type5 DRAW_NONE
#property indicator_type6 DRAW_NONE
#property indicator_style2 STYLE_SOLID
#property indicator_style3 STYLE_SOLID
//--
enum YN
{
No,
Yes
};
//--- input parameters
input int Kperiod = 5; // The iStochastic K period (the number of bars for calculation)
input int Dperiod = 3; // The iStochastic D period (the period of primary smoothing)
input int slowing = 3; // Period of final smoothing
input ENUM_MA_METHOD ma_method = MODE_EMA; // Type of smoothing
input ENUM_STO_PRICE price_field = STO_LOWHIGH; // Method of calculation of the Stochastic
input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No)
input YN UseEmailAlert = No; // Email Alert (Yes) or (No)
input YN UseSendnotify = No; // Send Notification (Yes) or (No)
//---
//--- indicator buffers
double StoUpBuffer[];
double StoDnBuffer[];
double StoArrowTrend[];
double StoTrend[];
double StoMainBuffer[];
double StoSignBuffer[];
//--
double tile=3.5;
//--- variable for storing the handle of the iStochastic indicator
int Stohandle;
//--- variable for storing
string name;
int posalert,
prevalert;
//--- name of the indicator on a chart
string short_name;
string indiname="StochasticTrends";
string Albase,AlSubj;
//--- we will keep the number of values in the Stochastic Oscillator indicator
int bars_calculated=0;
#define minbars 99
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Initialization (OnInit())
The OnInit() function prepares the indicator:
- Buffer Mapping: Sets up arrays for trend signals, arrows, and Stochastic values.
- Arrow Setup: Defines arrow codes (233 for rise, 234 for fall).
- Indicator Labeling: Names plots as “StocTrend,” “StocRise,” and “StocDown.”
- Stochastic Handle: Connects to the built-in
iStochasticfunction with user inputs (K period, D period, slowing, method, price field). - Short Name: Displays settings like StocTrends(EURUSD, 5, 3, 3, EMA, Low/High).
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//--- indicator buffers mapping
SetIndexBuffer(0,StoTrend,INDICATOR_DATA);
SetIndexBuffer(1,StoUpBuffer,INDICATOR_DATA);
SetIndexBuffer(2,StoDnBuffer,INDICATOR_DATA);
SetIndexBuffer(3,StoArrowTrend,INDICATOR_COLOR_INDEX);
SetIndexBuffer(4,StoMainBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(5,StoSignBuffer,INDICATOR_CALCULATIONS);
//--
PlotIndexSetInteger(1,PLOT_ARROW,233);
PlotIndexSetInteger(2,PLOT_ARROW,234);
//--
PlotIndexSetString(0,PLOT_LABEL,"StocTrend");
PlotIndexSetString(1,PLOT_LABEL,"StocRise");
PlotIndexSetString(2,PLOT_LABEL,"StocDown");
//--
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
//--- determine the symbol the indicator is drawn for
name=Symbol();
//---
Stohandle=iStochastic(name,PERIOD_CURRENT,Kperiod,Dperiod,slowing,ma_method,price_field);
//--- if the handle is not created
if(Stohandle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iStochastic indicator for the symbol %s/%s, error code %d",
name,
EnumToString(PERIOD_CURRENT),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--
string mameth="";
string stoprc="";
switch(ma_method)
{
case MODE_SMA: mameth="SMA"; break;
case MODE_EMA: mameth="EMA"; break;
case MODE_SMMA: mameth="SMMA"; break;
case MODE_LWMA: mameth="LWMA"; break;
}
//--
switch(price_field)
{
case STO_LOWHIGH: stoprc="Low/High"; break;
case STO_CLOSECLOSE: stoprc="Close/Close"; break;
}
//--
//--- show the symbol/timeframe the Stochastic Oscillator indicator is calculated for
short_name=StringFormat("StocTrends(%s, %d, %d, %d, %s, %s)",name,
Kperiod,Dperiod,slowing,mameth,stoprc);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//---
return(INIT_SUCCEEDED);
}
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Deinitialization (OnDeinit())
When removed or the chart changes:
- Clears chart comments.
- Releases the Stochastic handle.
- Prints the reason for deinitialization using
getUninitReasonText().
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
Print(getUninitReasonText(reason));
if(Stohandle!=INVALID_HANDLE) IndicatorRelease(Stohandle);
//--
return;
//---
} //-end OnDeinit()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Core Logic (OnCalculate())
This is the main function that runs on each tick:
- Data Preparation: Ensures arrays are series-based and copies Stochastic values.
- Trend Detection: Compares current and previous Stochastic values:
- If values suggest weakening momentum, a buy signal is plotted.
- If values suggest strengthening downward momentum, a sell signal is plotted.
- Arrow Placement:
- Buy arrows appear below price bars.
- Sell arrows appear above price bars.
- Alerts: Calls
PosAlerts()to notify traders of new signals.
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t rates_total,
const int32_t 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 int32_t &spread[])
{
//---
if(rates_total<minbars) return(0);
int x;
//--
ArraySetAsSeries(open,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(time,true);
ArraySetAsSeries(tick_volume,true);
ArraySetAsSeries(StoUpBuffer,true);
ArraySetAsSeries(StoDnBuffer,true);
ArraySetAsSeries(StoTrend,true);
ArraySetAsSeries(StoMainBuffer,true);
ArraySetAsSeries(StoSignBuffer,true);
//--
//--- number of values copied from the iStochastic indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(Stohandle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iStochastic indicator changed
//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history)
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the StochasticBuffer array is greater than the number of values in the iStochastic indicator for symbol/period, then we don't copy everything
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate()
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//---
if(IsStopped()) return(0); //Checking for stop flag
//-- get iStochastic indicator buffers
if(CopyBuffer(Stohandle,MAIN_LINE,0,values_to_copy,StoMainBuffer)<0)
{
Print("Getting the iStochastic indicator Main Line buffers is failed! Error",GetLastError());
return(0);
}
if(CopyBuffer(Stohandle,SIGNAL_LINE,0,values_to_copy,StoSignBuffer)<0)
{
Print("Getting the iStochastic indicator Signal Line buffers is failed! Error",GetLastError());
return(0);
}
//--
//---
double stcdif=2.5;
int xsu=0,xsd=0;
//--- main loop
for(x=calculated-3; x>=0; x--)
{
StoUpBuffer[x]=0.0;
StoDnBuffer[x]=0.0;
//--
double Stosig0 = StoSignBuffer[x];
double Stosig1 = StoSignBuffer[x+1];
double Stocur = StoMainBuffer[x];
double Stoprv = StoMainBuffer[x+1];
double Stoprv1 = StoMainBuffer[x+2];
//--
if((Stoprv>Stoprv1 && Stocur<Stoprv-stcdif)||(Stosig1<=Stoprv && Stosig0>Stocur)) xsu=x+1;
if((Stoprv<Stoprv1 && Stocur>Stoprv+stcdif)||(Stosig1>=Stoprv && Stosig0<Stocur)) xsd=x+1;
//--
if(xsd<xsu)
{
StoTrend[xsd]=1.0;
StoDnBuffer[x]=0.0;
StoUpBuffer[xsd]=low[xsd]-(tile*Point());
StoArrowTrend[xsd]=0.0;
posalert=1;
}
if(xsu<xsd)
{
StoTrend[xsu]=-1.0;
StoUpBuffer[x]=0.0;
StoDnBuffer[xsu]=high[xsu]+(tile*Point());
StoArrowTrend[xsu]=1.0;
posalert=-1;
}
}
//--
PosAlerts(posalert);
//--
//--- memorize the number of values in the Stochastic Oscillator indicator
bars_calculated=calculated;
//--- return value of prev_calculated for next call
return(rates_total);
//---
}
//+------------------------------------------------------------------+
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Supporting Functions
strTF()– Converts timeframe enums into readable strings (e.g., H1, D1).MqlReturnDateTime()– Extracts specific parts of datetime (year, month, day, etc.).Do_Alerts()– Prints messages, shows pop-up alerts, and can send emails or push notifications.PosAlerts()– Defines alert messages:- “Trend was Up, Open Buy”
- “Trend was Down, Open Sell”
getUninitReasonText()– Explains why the indicator stopped (chart closed, parameters changed, etc.).
Practical Application
Traders can use StochasticTrends to:
- Spot buy and sell opportunities with clear arrows.
- Receive alerts for momentum shifts without constantly watching the chart.
- Combine with other indicators for confirmation of entry and exit points.
Why It Complements StochDegree
In my personal trading setup, I use these two as a "Double-Filter" system:
- 1. StochasticTrends gives the initial signal (The Arrow).
- 2. StochDegree confirms if the move has enough "angle" or "power" to be followed.
By combining them, I have successfully "tamed" other aggressive indicators like StepUpDown, resulting in a much cleaner and more successful experience in forex trading.
Trading Insight: In recent tests on XAGUSD and GBPUSD, this combination helped filter out dozens of "fake" crossovers that usually happen during low-volatility sessions.
Conclusion
The StochasticTrends.mq5 indicator enhances the classic Stochastic Oscillator by adding visual arrows and alerts. It simplifies decision-making by clearly signaling when to buy or sell. For traders seeking straightforward momentum detection, this tool is a valuable addition to their MetaTrader 5 toolkit.
Trading shouldn't be complicated. It’s about bringing technical precision and long-term research into the art of trading. With StochasticTrends, you get a clear visual map of where the market wants to go next.
⚠️ Important: Risk Disclaimer
Trading foreign exchange on margin carries a high level of risk and may not be suitable for all investors. The high degree of leverage can work against you as well as for you. Before deciding to invest in foreign exchange, you should carefully consider your investment objectives, level of experience, and risk appetite. The StochasticTrends indicators provided in this article are for educational purposes and do not guarantee profits. Past performance is not indicative of future results.
Vital Records
If you think the StochasticTrends is worthy of being used for automated trading as an Expert Advisor, please leave a comment below this article.
If at least 25 people agree that this indicator is worthy of being used as an Expert Advisor, I will create an Expert Advisor based on its signals and share it on this blog.
We hope that this article and the StochasticTrends indicator program will be useful for traders in learning and generating new ideas, which is ultimately expected to be successful in forex trading.
See you in the next article on Expert Advisor programs or indicators for MetaTrader 4 and MetaTrader 5.
If you have any ideas for developing this indicator program or have a new ideas, please leave your comments below this article.
Thanks for reading this article.
See a complete list of other Indicators, Multi-Timeframe indicators, Multi-Currency Expert Advisors, MQL4/MQL5 tutorials and Python program, and algorithmic trading tools at:
Note: Please see the source program and download at the bottom of this article.
Risk Warning: Trading Forex and CFDs involves significant risk and may not be suitable for all investors. All content provided is for educational purposes only.
//+------------------------------------------------------------------+
//| StochasticTrends.mq5 |
//| Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-03-31 |
//| https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-03-31"
#property link "https://www.mql5.com/en/users/3rjfx"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 4
#property indicator_color2 clrWhite
#property indicator_color3 clrRed
#property indicator_color4 clrWhite,clrRed
#property indicator_type1 DRAW_NONE
#property indicator_type2 DRAW_ARROW
#property indicator_type3 DRAW_ARROW
#property indicator_type4 DRAW_COLOR_ARROW
#property indicator_type5 DRAW_NONE
#property indicator_type6 DRAW_NONE
#property indicator_style2 STYLE_SOLID
#property indicator_style3 STYLE_SOLID
//--
enum YN
{
No,
Yes
};
//--- input parameters
input int Kperiod = 5; // The iStochastic K period (the number of bars for calculation)
input int Dperiod = 3; // The iStochastic D period (the period of primary smoothing)
input int slowing = 3; // Period of final smoothing
input ENUM_MA_METHOD ma_method = MODE_EMA; // Type of smoothing
input ENUM_STO_PRICE price_field = STO_LOWHIGH; // Method of calculation of the Stochastic
input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No)
input YN UseEmailAlert = No; // Email Alert (Yes) or (No)
input YN UseSendnotify = No; // Send Notification (Yes) or (No)
//---
//--- indicator buffers
double StoUpBuffer[];
double StoDnBuffer[];
double StoArrowTrend[];
double StoTrend[];
double StoMainBuffer[];
double StoSignBuffer[];
//--
double tile=3.5;
//--- variable for storing the handle of the iStochastic indicator
int Stohandle;
//--- variable for storing
string name;
int posalert,
prevalert;
//--- name of the indicator on a chart
string short_name;
string indiname="StochasticTrends";
string Albase,AlSubj;
//--- we will keep the number of values in the Stochastic Oscillator indicator
int bars_calculated=0;
#define minbars 99
//---------//
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//--- indicator buffers mapping
SetIndexBuffer(0,StoTrend,INDICATOR_DATA);
SetIndexBuffer(1,StoUpBuffer,INDICATOR_DATA);
SetIndexBuffer(2,StoDnBuffer,INDICATOR_DATA);
SetIndexBuffer(3,StoArrowTrend,INDICATOR_COLOR_INDEX);
SetIndexBuffer(4,StoMainBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(5,StoSignBuffer,INDICATOR_CALCULATIONS);
//--
PlotIndexSetInteger(1,PLOT_ARROW,233);
PlotIndexSetInteger(2,PLOT_ARROW,234);
//--
PlotIndexSetString(0,PLOT_LABEL,"StocTrend");
PlotIndexSetString(1,PLOT_LABEL,"StocRise");
PlotIndexSetString(2,PLOT_LABEL,"StocDown");
//--
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
//--- determine the symbol the indicator is drawn for
name=Symbol();
//---
Stohandle=iStochastic(name,PERIOD_CURRENT,Kperiod,Dperiod,slowing,ma_method,price_field);
//--- if the handle is not created
if(Stohandle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iStochastic indicator for the symbol %s/%s, error code %d",
name,
EnumToString(PERIOD_CURRENT),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--
string mameth="";
string stoprc="";
switch(ma_method)
{
case MODE_SMA: mameth="SMA"; break;
case MODE_EMA: mameth="EMA"; break;
case MODE_SMMA: mameth="SMMA"; break;
case MODE_LWMA: mameth="LWMA"; break;
}
//--
switch(price_field)
{
case STO_LOWHIGH: stoprc="Low/High"; break;
case STO_CLOSECLOSE: stoprc="Close/Close"; break;
}
//--
//--- show the symbol/timeframe the Stochastic Oscillator indicator is calculated for
short_name=StringFormat("StocTrends(%s, %d, %d, %d, %s, %s)",name,
Kperiod,Dperiod,slowing,mameth,stoprc);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//---
return(INIT_SUCCEEDED);
}
//---------//
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
Print(getUninitReasonText(reason));
if(Stohandle!=INVALID_HANDLE) IndicatorRelease(Stohandle);
//--
return;
//---
} //-end OnDeinit()
//---------//
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int32_t rates_total,
const int32_t 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 int32_t &spread[])
{
//---
if(rates_total<minbars) return(0);
int x;
//--
ArraySetAsSeries(open,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(time,true);
ArraySetAsSeries(tick_volume,true);
ArraySetAsSeries(StoUpBuffer,true);
ArraySetAsSeries(StoDnBuffer,true);
ArraySetAsSeries(StoTrend,true);
ArraySetAsSeries(StoMainBuffer,true);
ArraySetAsSeries(StoSignBuffer,true);
//--
//--- number of values copied from the iStochastic indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(Stohandle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iStochastic indicator changed
//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history)
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the StochasticBuffer array is greater than the number of values in the iStochastic indicator for symbol/period, then we don't copy everything
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate()
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//---
if(IsStopped()) return(0); //Checking for stop flag
//-- get iStochastic indicator buffers
if(CopyBuffer(Stohandle,MAIN_LINE,0,values_to_copy,StoMainBuffer)<0)
{
Print("Getting the iStochastic indicator Main Line buffers is failed! Error",GetLastError());
return(0);
}
if(CopyBuffer(Stohandle,SIGNAL_LINE,0,values_to_copy,StoSignBuffer)<0)
{
Print("Getting the iStochastic indicator Signal Line buffers is failed! Error",GetLastError());
return(0);
}
//--
//---
double stcdif=2.5;
int xsu=0,xsd=0;
//--- main loop
for(x=calculated-3; x>=0; x--)
{
StoUpBuffer[x]=0.0;
StoDnBuffer[x]=0.0;
//--
double Stosig0 = StoSignBuffer[x];
double Stosig1 = StoSignBuffer[x+1];
double Stocur = StoMainBuffer[x];
double Stoprv = StoMainBuffer[x+1];
double Stoprv1 = StoMainBuffer[x+2];
//--
if((Stoprv>Stoprv1 && Stocur<Stoprv-stcdif)||(Stosig1<=Stoprv && Stosig0>Stocur)) xsu=x+1;
if((Stoprv<Stoprv1 && Stocur>Stoprv+stcdif)||(Stosig1>=Stoprv && Stosig0<Stocur)) xsd=x+1;
//--
if(xsd<xsu)
{
StoTrend[xsd]=1.0;
StoDnBuffer[x]=0.0;
StoUpBuffer[xsd]=low[xsd]-(tile*Point());
StoArrowTrend[xsd]=0.0;
posalert=1;
}
if(xsu<xsd)
{
StoTrend[xsu]=-1.0;
StoUpBuffer[x]=0.0;
StoDnBuffer[xsu]=high[xsu]+(tile*Point());
StoArrowTrend[xsu]=1.0;
posalert=-1;
}
}
//--
PosAlerts(posalert);
//--
//--- memorize the number of values in the Stochastic Oscillator indicator
bars_calculated=calculated;
//--- return value of prev_calculated for next call
return(rates_total);
//---
}
//+------------------------------------------------------------------+
string strTF(ENUM_TIMEFRAMES period)
{
//---
switch(period)
{
//--
case PERIOD_M1: return("M1");
case PERIOD_M2: return("M2");
case PERIOD_M3: return("M3");
case PERIOD_M4: return("M4");
case PERIOD_M5: return("M5");
case PERIOD_M6: return("M6");
case PERIOD_M10: return("M10");
case PERIOD_M12: return("M12");
case PERIOD_M15: return("M15");
case PERIOD_M20: return("M20");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H2: return("H2");
case PERIOD_H3: return("H3");
case PERIOD_H4: return("H4");
case PERIOD_H6: return("H6");
case PERIOD_H8: return("H8");
case PERIOD_H12: return("H12");
case PERIOD_D1: return("D1");
case PERIOD_W1: return("W1");
case PERIOD_MN1: return("MN1");
//--
}
//--
return(string(period));
//---
} //-end strTF()
//---------//
enum TimeReturn
{
year = 0, // Year
mon = 1, // Month
day = 2, // Day
hour = 3, // Hour
min = 4, // Minutes
sec = 5, // Seconds
day_of_week = 6, // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday)
day_of_year = 7 // Day number of the year (January 1st is assigned the number value of zero)
};
//---------//
int MqlReturnDateTime(datetime reqtime,
const int mode)
{
//---
MqlDateTime mqltm;
TimeToStruct(reqtime,mqltm);
int valdate=0;
//--
switch(mode)
{
case 0: valdate=mqltm.year; break; // Return Year
case 1: valdate=mqltm.mon; break; // Return Month
case 2: valdate=mqltm.day; break; // Return Day
case 3: valdate=mqltm.hour; break; // Return Hour
case 4: valdate=mqltm.min; break; // Return Minutes
case 5: valdate=mqltm.sec; break; // Return Seconds
case 6: valdate=mqltm.day_of_week; break; // Return Day of week (0-Sunday, 1-Monday, ... ,6-Saturday)
case 7: valdate=mqltm.day_of_year; break; // Return Day number of the year (January 1st is assigned the number value of zero)
}
return(valdate);
//---
} //-end MqlReturnDateTime()
//---------//
void Do_Alerts(string msgText)
{
//---
//--
Print("--- "+Symbol()+": "+msgText+
"\n--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
//--
if(alerts==Yes)
{
Alert("--- "+Symbol()+": "+msgText+
"--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
}
//--
if(UseEmailAlert==Yes)
SendMail(MQLInfoString(MQL_PROGRAM_NAME),"--- "+Symbol()+" "+strTF(Period())+": "+msgText+
"\n--- at: "+TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
//--
if(UseSendnotify==Yes)
SendNotification(MQLInfoString(MQL_PROGRAM_NAME)+"--- "+Symbol()+" "+strTF(Period())+": "+msgText+
"\n--- at: "+TimeToString(iTime(Symbol(),0,0),TIME_DATE|TIME_MINUTES));
//--
return;
//--
//---
} //-end Do_Alerts()
//---------//
void PosAlerts(int curalerts)
{
//---
//---
if((curalerts!=prevalert)&&(curalerts==1))
{
Albase=indiname;
AlSubj=Albase+" Trend was Up, Open Buy";
Do_Alerts(AlSubj);
prevalert=curalerts;
}
//---
if((curalerts!=prevalert)&&(curalerts==-1))
{
Albase=indiname;
AlSubj=" Trend was Down, Open Sell";
Do_Alerts(AlSubj);
prevalert=curalerts;
}
//---
return;
//----
} //-end PosAlerts()
//---------//
string getUninitReasonText(int reasonCode)
{
//---
string text="";
//---
switch(reasonCode)
{
case REASON_PROGRAM:
text="The EA has stopped working calling by remove function."; break;
case REASON_REMOVE:
text="Program "+__FILE__+" was removed from chart"; break;
case REASON_RECOMPILE:
text="Program recompiled."; break;
case REASON_CHARTCHANGE:
text="Symbol or timeframe was changed"; break;
case REASON_CHARTCLOSE:
text="Chart was closed"; break;
case REASON_PARAMETERS:
text="Input-parameter was changed"; break;
case REASON_ACCOUNT:
text="Account was changed"; break;
case REASON_TEMPLATE:
text="New template was applied to chart"; break;
case REASON_INITFAILED:
text="The OnInit() handler returned a non-zero value."; break;
case REASON_CLOSE:
text="Terminal closed."; break;
default: text="Another reason"; break;
}
//--
return text;
//---
} //-end getUninitReasonText()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Please download the StochasticTrends indicator: StochasticTrends
If you want to get the source code of the program, please send your request via the Contact page by mentioning the article and program you want.




0 comments:
Post a Comment