The Rise and Down Trend v1.2 (Non-Repaint) indicator is designed to visually mark shifts in market trends, highlighting potential bullish and bearish conditions on a price chart. By plotting arrows to indicate potential rising or falling trends, it helps traders identify changes in market direction. This indicator does not repaint, meaning once signals appear, they remain fixed, offering a clear view of past market conditions. It utilizes the EMA and distance calculation for its core logic, without recalculating previous values, providing a stable visual reference.
#property strict
#property indicator_chart_window
//--- Indicator buffers and settings
#property indicator_buffers 4
#property indicator_type1 DRAW_NONE
#property indicator_type2 DRAW_NONE
#property indicator_type3 DRAW_ARROW
#property indicator_type4 DRAW_ARROW
#property indicator_width3 1
#property indicator_width4 1
#property indicator_color3 clrAqua
#property indicator_color4 clrOrangeRed
#property indicator_style3 STYLE_SOLID
#property indicator_style4 STYLE_SOLID
#property indicator_label2 "dTrends"
#property indicator_label3 "Rise"
#property indicator_label4 "Down"
//--- Enum for Yes/No settings
enum YN
{
No,
Yes
};
//--- Input parameters
input ENUM_APPLIED_PRICE Trend_price = PRICE_CLOSE; // Select Applied Price
input int ema_period = 13; // EMA Period
input double dist = 2.3; // Distance from Zero in pips
input YN alerts = Yes; // Display Alerts (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
//--- Indicator buffers
double value1[], value2[], Rise[], Down[];
double Bears[], Bulls[], Temp[];
//--- Variables for calculations
int cur, prv;
int cmnt, pmnt;
string posisi, sigpos, iname, msgText;
double pip, devi;
#define minBars 99 // Minimum bars for calculation
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Map indicator buffers
SetIndexBuffer(0,value1);
SetIndexBuffer(1,value2);
SetIndexBuffer(2,Rise);
SetIndexBuffer(3,Down);
//--- Configure arrows for Rise and Down
SetIndexStyle(2,DRAW_ARROW,STYLE_SOLID);
SetIndexArrow(2,172);
SetIndexStyle(3,DRAW_ARROW,STYLE_SOLID);
SetIndexArrow(3,172);
//--- Set indicator name and digits
iname="dTrends";
IndicatorSetString(INDICATOR_SHORTNAME,iname);
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- Calculate pip value based on symbol digits
if(Digits()==3 || Digits()==5)
pip=Point()*10;
else if(Digits()==2 || Digits()==4)
pip=Point();
if(StringSubstr(Symbol(),0,1)=="X" || StringSubstr(Symbol(),0,1)=="#")
pip=Point()*10;
//--- Normalize distance value
devi=NormalizeDouble(dist*pip,Digits());
return(INIT_SUCCEEDED); // Initialization successful
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- Remove comments and all objects from the chart
Comment("");
ObjectsDeleteAll(ChartID(),0,-1);
return;
}
//+------------------------------------------------------------------+
//| 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[])
{
//--- Check if the number of bars is sufficient
if(rates_total<minBars)
return(0);
//--- Determine the calculation limit
int limit = rates_total - prev_calculated;
if(prev_calculated>0)
limit++;
if(prev_calculated<minBars)
limit = 2;
else
limit = prev_calculated - 1;
//--- Resize arrays based on limit
ArrayResize(value1,limit);
ArrayResize(value2,limit);
ArrayResize(Rise,limit);
ArrayResize(Down,limit);
ArrayResize(Bears,limit);
ArrayResize(Bulls,limit);
ArrayResize(Temp,limit);
//--- Set arrays as series
ArraySetAsSeries(value1,true);
ArraySetAsSeries(value2,true);
ArraySetAsSeries(Rise,true);
ArraySetAsSeries(Down,true);
ArraySetAsSeries(open,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(time,true);
ArraySetAsSeries(Bears,true);
ArraySetAsSeries(Bulls,true);
ArraySetAsSeries(Temp,true);
//--- Main loop for calculations
for(int i=limit-1; i>=0; i--)
{
Temp[i]=iMA(Symbol(),0,ema_period,0,MODE_EMA,Trend_price,i);
Bears[i]=low[i] - Temp[i];
Bulls[i]=high[i] - Temp[i];
}
//--- Determine rise and down trends
for(int i=limit-2; i>=0; i--)
{
value1[i] = -(Bears[i] + Bulls[i]);
if(value1[i+1]>=0 && value1[i]<-devi)
{Rise[i]=low[i]; Down[i]=EMPTY_VALUE; cur=1;}
else if(value1[i+1]<=0 && value1[i]>devi)
{Down[i]=high[i]; Rise[i]=EMPTY_VALUE; cur=-1;}
else
{Rise[i]=EMPTY_VALUE; Down[i]=EMPTY_VALUE;}
if(value1[i]<0)
value2[i]=1.0;
else if(value1[i]>0)
value2[i]=-1.0;
}
//--- Call alert functions if necessary
if(alerts==Yes || EmailAlert==Yes || sendnotify==Yes)
Do_Alerts(cur);
//--- Display chart info if enabled
if(displayinfo==Yes)
ChartComm();
return(rates_total); // Return the number of calculated rates
}
//+------------------------------------------------------------------+
//| Alert handling function |
//+------------------------------------------------------------------+
void Do_Alerts(int fcur)
{
cmnt=Minute();
if(cmnt!=pmnt)
{
//--- Determine message and signal based on trend direction
if(fcur==1)
{
msgText=iname+" Start to Up";
posisi="Bullish";
sigpos="Open BUY Order";
}
else if(fcur==-1)
{
msgText=iname+" Start to Down";
posisi="Bearish";
sigpos="Open SELL Order";
}
else
{
msgText=iname+" Trend Not Found!";
posisi="Not Found!";
sigpos="Wait for Confirmation!";
}
//--- Send alerts if trend has changed
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; // Update previous trend state
}
pmnt=cmnt; // Update minute tracker
}
return;
}
//+------------------------------------------------------------------+
//| Convert timeframe period to string |
//+------------------------------------------------------------------+
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));
}
//+------------------------------------------------------------------+
//| Determine account trade mode (Demo/Contest/Real) |
//+------------------------------------------------------------------+
string AccountMode()
{
//--- Get account trade mode
switch(AccountInfoInteger(ACCOUNT_TRADE_MODE))
{
case ACCOUNT_TRADE_MODE_DEMO: return("Demo Account");
case ACCOUNT_TRADE_MODE_CONTEST: return("Contest Account");
case ACCOUNT_TRADE_MODE_REAL: return("Real Account");
}
return("Unknown Account Type");
}
//+------------------------------------------------------------------+
//| Display chart comments |
//+------------------------------------------------------------------+
void ChartComm()
{
string comment;
comment = "Account Type: " + AccountMode() + "\n";
comment += "Symbol: " + Symbol() + " | TimeFrame: " + TF2Str(Period()) + "\n";
comment += "Distance (pips): " + DoubleToString(dist, 1) + "\n";
comment += "EMA Period: " + IntegerToString(ema_period) + "\n";
//--- Current trend direction comment
if(cur == 1)
comment += "Current Trend: Bullish | Suggestion: Open BUY Order\n";
else if(cur == -1)
comment += "Current Trend: Bearish | Suggestion: Open SELL Order\n";
else
comment += "Current Trend: Sideways | Suggestion: Wait for Confirmation\n";
//--- Display comment on the chart
Comment(comment);
}
What Does the Indicator Do?
The Rise and Down Trend Indicator is designed to help identify whether the market is in an upward or downward trend. By analyzing how far price moves away from an internal baseline (EMA), it determines potential shifts in direction. When certain thresholds are breached, the indicator signals a “Rise” or “Down” condition, indicating possible bullish or bearish market movements.
Key Features of the Indicator
- Trend Identification: The main purpose of this indicator is to show the direction of the trend. By focusing on the price distance from an EMA, the indicator distinguishes between rising and falling trends.
- Arrows for Visual Cues: The indicator uses arrows to highlight changes in market trends. An upward arrow appears when the price breaks the threshold to the upside, suggesting a rising trend. A downward arrow shows a bearish trend when the price drops beyond the threshold.
- Alert System: To make things easier, the indicator includes an alert system. It can display on-screen messages, send email alerts, or even notify you via a push notification. This ensures you never miss important trend shifts when you’re not actively monitoring the chart.
Breaking Down the Indicator Logic
The logic behind the Rise and Down Trend Indicator relies heavily on price positioning relative to an Exponential Moving Average (EMA). The indicator works by measuring the distance between the highs and lows of the price and the EMA value. Let’s break down how it does this:
The Role of the EMA
The EMA acts as the core baseline for this indicator. This moving average is set over a specific period (e.g., 13 periods). It gives more weight to recent prices, making it more responsive to current price action than a simple moving average.
When the price moves above or below this EMA by a certain distance (measured in pips), the indicator identifies a potential trend shift. This distance is a key input that determines how sensitive the indicator is to price changes. A smaller distance will make the indicator more responsive to slight price movements, while a larger distance will filter out minor fluctuations.
Bulls and Bears: Measuring the Push and Pull
The indicator calculates two values:
- Bulls: This value measures how much the high price exceeds the EMA.
- Bears: This value measures how much the low price falls below the EMA.
By comparing these two values, the indicator can determine the overall strength of either buyers (bulls) or sellers (bears). When either value breaches a certain threshold, it signals that the market is leaning towards a trend change.
Arrows: Signaling a Trend Shift
The indicator uses arrows as visual markers to represent trend shifts:
- Upward Arrow: Appears when the bearish strength diminishes, and the price begins to rise above a certain level (indicating a bullish trend).
- Downward Arrow: Appears when the bullish strength weakens, and the price falls below a set level (indicating a bearish trend).
The use of these arrows helps traders quickly recognize where potential shifts in the trend may occur, allowing for faster decision-making.
Visual and Alert-Based Feedback
In addition to its graphical representation, the Rise and Down Trend Indicator provides alerts in various forms to help you stay informed:
Alerts and Notifications
You can set the indicator to provide:
- On-screen alerts: Messages that pop up when a trend shift is detected.
- Email alerts: Notifications sent to your email with detailed information about the trend change.
- Push notifications: Alerts sent to your mobile device, allowing you to stay updated even when you’re away from the trading screen.
These alerts are customizable, meaning you can enable or disable them based on your preferences.
Trade Information Display
For traders who want more information at a glance, the indicator offers an on-chart display of trade data. This data includes useful information like:
- Broker and account details: Displays the broker’s name, account balance, leverage, and equity.
- Currency pair and spread: Shows the currency pair you’re trading along with the current spread.
- Indicator signal: Displays whether the current trend is bullish or bearish.
This feature helps traders make more informed decisions by keeping relevant data visible on the chart at all times.
How Does It Handle Market Conditions?
The Rise and Down Trend Indicator is designed to work in various market conditions. However, like most indicators, it performs best in trending markets. In sideways or ranging markets, where price fluctuations are smaller and less predictable, the indicator may provide mixed or false signals due to the nature of the EMA.
Because it relies on the distance from the EMA, the indicator tends to perform slower than real-time price action, leading to slight delays in signaling. This is something to keep in mind when using it for high-frequency or short-term trades.
Conclusion
The Rise and Down Trend Indicator is a helpful tool for recognizing market trends and spotting potential shifts in direction. It is built around the idea of measuring price movement relative to an Exponential Moving Average (EMA), which helps determine when to expect rising or falling trends. With features like visual arrows, alerts, and an on-chart information display, it’s designed to provide a comprehensive view of the market’s movements.
While it’s a reliable tool in trending markets, remember that like all indicators, it has limitations in more volatile or sideways conditions. Therefore, it’s important to use this indicator alongside other forms of analysis to ensure a well-rounded trading strategy.