Author: Roberto Jacobs (3rjfx)
Discover the MA Heiken Ashi Indicator for MT5. Smooth trend analysis, momentum detection, and MQL5 trading alerts for a superior Forex strategy.
Introduction
Welcome back to Forex Home Expert. As active MQL5 programmers and dedicated market analysts since 2012, we continuously strive to develop solutions that simplify the complexities of the financial markets.
Today, we are thrilled to introduce and thoroughly explain one of our most refined custom creations: the MA Heiken Ashi Indicator for MT5. We designed this advanced tool to merge the trend-smoothing capabilities of the traditional Heiken Ashi candlestick methodology with the predictive stability of Moving Averages.
Whether you are a seasoned institutional trader or a retail newcomer seeking reliable Trading Tools, this indicator is engineered to elevate your Forex Analysis and provide unparalleled clarity in your daily market evaluation.
1. What is the MA Heiken Ashi Indicator?
The MA Heiken Ashi Indicator is a sophisticated, custom technical analysis tool developed exclusively for the MetaTrader 5 (MT5) platform. To understand its true value, we must first look at its foundational components.
Traditional Heiken Ashi charts already smooth out price action by averaging the open, high, low, and close prices, which helps traders filter out market noise and identify the dominant trend.
However, in highly volatile markets, even standard Heiken Ashi candles can produce misleading wicks or temporary color flips.
To solve this, we took the concept a step further. Our MA Heiken Ashi Indicator first applies a Moving Average (MA) to the raw Open, High, Low, and Close prices of the asset. Only after this initial smoothing process do we apply the classic Heiken Ashi mathematical formula to these averaged values.
This "dual-smoothing" technique results in an exceptionally clean chart representation. It provides superior Momentum Detection by virtually eliminating the erratic price spikes that often trigger false trading signals.
When the calculated Heiken Ashi close is higher than its open, we paint the candlestick in a bullish color (defaulted to WhiteSmoke).
Conversely, when the close is lower than the open, it is painted in a bearish color (defaulted to Red).
This visual simplicity makes it an invaluable cornerstone for any robust Forex Strategy, allowing you to gauge market direction with absolute confidence.
2. Key Features and Benefits
- Dual-Layer Smoothing: By combining Moving Averages with Heiken Ashi calculations, we deliver a noise-free chart environment that makes long-term and short-term Forex Analysis significantly more accurate.
- Highly Customizable Parameters: We have built in flexible input settings, empowering you to adjust the MA period and the MA method (including Simple, Exponential, Smoothed, or Linear Weighted) to perfectly align with your unique Trading strategy.
- Comprehensive Alert System: We understand that traders cannot monitor charts every single second. Therefore, we integrated a versatile alert mechanism. You can easily enable on-screen pop-ups, MT5 Email Alerts, and mobile Trading Notifications to ensure you are instantly informed of critical market shifts.
- Clear Buy Sell Signals: The distinct color transitions of the MA Heiken Ashi bars serve as a foundational element for generating high-probability trading signals, giving you the conviction needed to execute your trades effectively.
3. A Deep Dive into the MQL5 Source Code
At Forex Home Expert, we believe in transparency and continuous education. Understanding the architecture of a tool empowers you to utilize it to its maximum potential. Below, we break down the core logic of the MA Heiken Ashi.mq5 source code, explaining the precise programming decisions we made to ensure optimal performance, memory efficiency, and reliability.
1. Global Scope and Input Properties
At the very beginning of the source code, we define the global properties and user-adjustable input parameters. This section dictates the indicator's behavior and its interaction with the MT5 terminal. We use the #property directives to specify that the indicator draws directly in the main chart window, utilizes five data buffers, and creates four distinct visual plots. The primary plot utilizes the DRAW_COLOR_CANDLES style, which allows us to dynamically assign colors to the candlesticks based on the calculated trend direction.
We also define a custom enumeration (enum YN) for simple "Yes" or "No" selections, ensuring the user interface remains clean and intuitive. The core input parameters include inpMaPeriod (defaulting to 5) and inpMethod (defaulting to MODE_LWMA, or Linear Weighted Moving Average), which control the initial smoothing calculation. Furthermore, we have dedicated inputs for our MQL5 Alerts system: alerts for on-screen pop-ups, UseEmailAlert for MT5 Email Alerts, and UseSendnotify for push Trading Notifications. This modular input design ensures that every trader can tailor the indicator to their specific workflow.
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 4
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrWhiteSmoke,clrRed
#property indicator_label1 "MAHA-Op;MAHA-Hi;MAHA-Lo;MAHA-Cl"
//---
//-- Enumeration
enum YN
{
No,
Yes
};
//--
//---Input parameters for MA
input int inpMaPeriod = 5; // Input MA Period
input ENUM_MA_METHOD inpMethod = MODE_LWMA; // Input MA Method
//--- Input parameters for alerts
input YN alerts = Yes; // Display Alerts Pop-up on Chart (Yes) or (No)
input YN UseEmailAlert = No; // Email Alert (Yes) or (No)
input YN UseSendnotify = No; // Send Notification (Yes) or (No)
input int AlertOnBar = 1; // Input Alert On Bar (default bar 1)
//---
//-- buffers
double
HASOp[],
HASHi[],
HASLo[],
HASCl[],
HASCo[];
double
MAOPEN[],
MAHIGH[],
MALOW[],
MACLOSE[];
int
hMAO,
hMAH,
hMAL,
hMAC;
int BRC;
int aob;
//--
//--- variable for storing alert
datetime
altime;
int posalert,
prevalert;
string Albase,AlSubj;
//--- name of the indicator on a chart
string _pname;
string indiname;
//--- we will keep the number of values in the ATR indicator
int calculated,
bars_calculated=0;
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
2. The OnInit() Function
The OnInit() function serves as the initialization engine of our indicator. When you attach the MA Heiken Ashi to your MT5 chart, this function executes first to prepare the environment. Here, we meticulously map the indicator buffers to their respective dynamic arrays using the SetIndexBuffer function. We assign specific roles to each buffer: HASOp, HASHi, HASLo, and HASCl hold the calculated Heiken Ashi Open, High, Low, and Close values, while HASCo manages the color indexing.
Following the buffer mapping, we call two critical custom helper functions: SetIndicatorHandle() and ResizeArrays(). The SetIndicatorHandle() function is particularly elegant; it uses a switch statement to request the actual Moving Average data from the MT5 terminal based on the user's selected inpMethod. It calls the iMA() function four separate times—once for PRICE_OPEN, PRICE_HIGH, PRICE_LOW, and PRICE_CLOSE. Storing these handles allows us to efficiently retrieve the smoothed data later without redundant calculations. Finally, we dynamically set the indicator's short name, which appears in the top-left corner of the chart, displaying the current timeframe, MA period, and MA method for quick, at-a-glance reference.
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,HASOp,INDICATOR_DATA);
SetIndexBuffer(1,HASHi,INDICATOR_DATA);
SetIndexBuffer(2,HASLo,INDICATOR_DATA);
SetIndexBuffer(3,HASCl,INDICATOR_DATA);
SetIndexBuffer(4,HASCo,INDICATOR_COLOR_INDEX);
//--
SetIndicatorHandle();
ResizeArrays();
aob=AlertOnBar;
//--
_pname=MQLInfoString(MQL_PROGRAM_NAME);
indiname="MAHA"+"("+strTF(Period())+","+string(inpMaPeriod)+","+EnumToString(inpMethod)+")";
IndicatorSetString(INDICATOR_SHORTNAME,indiname);
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--
return(INIT_SUCCEEDED);
//---
} //-end OnInit()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
3. The OnCalculate() Function and Core Mathematical Logic
The OnCalculate() function is the beating heart of the MA Heiken Ashi indicator, executing every time a new tick arrives or a new bar forms. Our first step inside this function is to ensure that the Moving Average handles have calculated sufficient data bars by utilizing the CalculatedHandle() and CountCopyBurrefs() helper functions. If the data is not yet ready, the function safely exits to prevent runtime errors or array out-of-range exceptions.
Once the data integrity is verified, we use FillArrayFromBuffer() to copy the latest Moving Average values into our local arrays (MAOPEN, MAHIGH, MALOW, MACLOSE). The main calculation loop then iterates through the available bars. For each bar, we apply the classic Heiken Ashi formula, but crucially, we apply it to the Moving Average values, not the raw price. The mathematics are as follows:
maha_open = (MAOPEN[i-1] + MACLOSE[i-1]) / 2.0maha_close = (MAOPEN[i] + MAHIGH[i] + MALOW[i] + MACLOSE[i]) / 4.0maha_high = fmax(MAHIGH[i], fmax(MAOPEN[i], MACLOSE[i]))maha_low = fmin(MALOW[i], fmin(MAOPEN[i], MACLOSE[i]))
After calculating these values, we assign them to the respective indicator buffers. We then determine the candle color: if <code>HASOp[i] <HASCl[i]</code>, we set the color index to 0.0 (WhiteSmoke, indicating bullish momentum). Otherwise, we set it to 1.0 (Red, indicating bearish momentum). This logical comparison is the exact mechanism that generates the clear, visual Buy Sell Signals on your chart.
//+------------------------------------------------------------------+
//| 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[])
{
//---
CalculatedHandle(rates_total);
//--
int values_to_copy=CountCopyBurrefs(rates_total,prev_calculated);
//--
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation
if(!FillArrayFromBuffer(MAOPEN,hMAO,values_to_copy)) return(0);
if(!FillArrayFromBuffer(MAHIGH,hMAH,values_to_copy)) return(0);
if(!FillArrayFromBuffer(MALOW,hMAL,values_to_copy)) return(0);
if(!FillArrayFromBuffer(MACLOSE,hMAC,values_to_copy)) return(0);
//--
int start;
int min_start = 1 + aob;
//--- preliminary calculations
if(prev_calculated==0)
{
HASOp[0]=MAOPEN[0];
HASHi[0]=MAHIGH[0];
HASLo[0]=MALOW[0];
HASCl[0]=MACLOSE[0];
start=2;
start = fmax(2, min_start);
}
else
start=prev_calculated;
//--
//---
//--- the main loop of calculations
for(int i=start; i<BRC && !IsStopped(); i++)
{
double maha_open = (MAOPEN[i-1]+MACLOSE[i-1])/2.0;
double maha_close = (MAOPEN[i]+MAHIGH[i]+MALOW[i]+MACLOSE[i])/4.0;
double maha_high = fmax(MAHIGH[i],fmax(MAOPEN[i],MACLOSE[i]));
double maha_low = fmin(MALOW[i],fmin(MAOPEN[i],MACLOSE[i]));
//--
HASLo[i]=maha_low;
HASHi[i]=maha_high;
HASOp[i]=maha_open;
HASCl[i]=maha_close;
//--- set candle color
if(HASOp[i]<HASCl[i])
HASCo[i]=0.0; // set color to WhiteSmoke default
else
HASCo[i]=1.0; // set color to Red default
//--- set alert
if(HASCo[i-aob]==0.0 && HASCo[i-(1+aob)]==1.0) { posalert = 1; altime=time[i-aob]; }
if(HASCo[i-aob]==1.0 && HASCo[i-(1+aob)]==0.0) { posalert =-1; altime=time[i-aob]; }
//---
}
//--
PosAlerts(posalert,altime);
//--- memorize the number of values in the Average True Range indicator
bars_calculated=calculated;
//---
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
***Copyright © 2026 3rjfx ~ For educational purposes only.***
4. Alert and Helper Functions
A standout feature of our development philosophy is the robust, multi-channel alert mechanism. Within the main calculation loop, we continuously monitor for color transitions. If the current bar's color index differs from the previous bar's color index (for example, shifting from Red to WhiteSmoke), we flag a posalert state. This state is then passed to the PosAlerts() function.
The PosAlerts() function evaluates the alert state and constructs a highly descriptive message, such as "MA Heiken Ashi bar was Up ~ Open Buy". It then passes this message to the Do_Alerts() function. Based on your initial input preferences, Do_Alerts() will execute a combination of actions: printing the event to the MT5 Experts tab, triggering a desktop pop-up, sending an email via MT5 Email Alerts, or dispatching a mobile push message via Trading Notifications. This comprehensive approach to MQL5 trading alerts ensures you are always informed of potential trend reversals, regardless of your physical location.
void Do_Alerts(string msgText,datetime altpos)
{
//---
//--
Print(" --- "+Symbol()+": "+msgText+
"\n --- at: ",TimeToString(altpos,TIME_DATE|TIME_MINUTES));
//--
if(alerts==Yes)
{
Alert(" --- "+Symbol()+": "+msgText+
" --- at: ",TimeToString(altpos,TIME_DATE|TIME_MINUTES));
}
//--
if(UseEmailAlert==Yes)
SendMail(_pname," --- "+Symbol()+" "+strTF(Period())+": "+msgText+
"\n --- at: "+TimeToString(altpos,TIME_DATE|TIME_MINUTES));
//--
if(UseSendnotify==Yes)
SendNotification(_pname+" --- "+Symbol()+" "+strTF(Period())+": "+msgText+
"\n --- at: "+TimeToString(altpos,TIME_DATE|TIME_MINUTES));
//--
return;
//--
//---
} //-end Do_Alerts()
//---------//
void PosAlerts(int curalerts,datetime altpos)
{
//---
//---
if((curalerts!=prevalert)&&(curalerts==1))
{
Albase=indiname;
AlSubj=Albase+" MA Heiken Ashi bar was Up ~ Open Buy";
Do_Alerts(AlSubj,altpos);
prevalert=curalerts;
}
//---
if((curalerts!=prevalert)&&(curalerts==-1))
{
Albase=indiname;
AlSubj=" MA Heiken Ashi bar was Down ~ Open Sell";
Do_Alerts(AlSubj,altpos);
prevalert=curalerts;
}
//---
return;
//---
} //-end PosAlerts()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
4. How to Use the MA Heiken Ashi Indicator in Your Trading Strategy
Integrating the MA Heiken Ashi Indicator into your daily routine is remarkably straightforward, yet its impact on your trading performance can be profound.
We strongly recommend using it primarily as a trend-filtering and confirmation tool rather than a standalone entry mechanism. For instance, if you are employing a breakout Forex Strategy, you can use the MA Heiken Ashi to confirm the overall market direction.
If the indicator is painting consecutive WhiteSmoke bars, you might choose to only take long (buy) breakouts, deliberately ignoring short (sell) signals that move against the smoothed momentum.
Additionally, the indicator excels in helping traders stay in winning trades longer. Because of the dual-smoothing effect, minor pullbacks that would normally cause a standard candlestick chart to look bearish are often absorbed and displayed as neutral or slightly bullish MA Heiken Ashi candles.
This prevents premature exits and helps you capture the full meat of a market move.
By combining this indicator with other complementary Trading Tools, such as support and resistance levels or volume oscillators, you can build a highly robust, rules-based Trading strategy that consistently yields high-probability trading signals.
FAQ: Common Questions About the ECN Integration
Q: Does the MA Heiken Ashi Indicator repaint historical bars?
A: No, it does not repaint historical bars. The calculations are based on finalized Moving Average values, and the color of a completed bar is permanently fixed. While the current, forming bar may change color as new ticks arrive (which is normal for all real-time indicators), the historical data remains stable, ensuring the absolute integrity of your backtesting and live Forex Analysis.
Q: Can I use this indicator on any timeframe and currency pair?
A: Absolutely. The MA Heiken Ashi Indicator is designed to be completely timeframe-agnostic and pair-agnostic. Whether you are scalping the EURUSD on the M5 chart or swing trading the XAUUSD on the H4 chart, the underlying Moving Average logic adapts seamlessly. We encourage you to experiment with different inpMaPeriod settings to find the optimal balance of responsiveness and smoothness for your specific trading style.
Conclusion
At Forex Home Expert, our mission is to equip traders with sophisticated, reliable, and easy-to-use software that provides a genuine edge in the markets.
The MA Heiken Ashi Indicator for MT5 is a shining testament to that commitment. By transforming raw, noisy price data into ultra-smooth, Moving Average-based Heiken Ashi candlesticks, we provide you with a crystal-clear perspective on market momentum.
Combined with our highly customizable MQL5 Alerts, including MT5 Email Alerts and Trading Notifications, this indicator ensures you stay ahead of market shifts without being chained to your screen.
We invite you to take, test, and integrate this powerful tool into your trading arsenal, and we look forward to supporting your journey toward consistent, confident market success.
Vital Records
We hope that this article and the MA Heiken Ashi - Indicator for MT5 program will be useful for traders in learning and generating new ideas, thereby will be able improving your trading performance.
We hope you find our content useful and thank you for visiting the Forex Home Expert.
See you in the next article on Expert Advisor programs or indicators for MetaTrader 4, MetaTrader 5 or Python program and trading psychology.
Explore more algorithmic trading resources:
Note: This program is shared under a Copyleft/Creative Commons License (CCL) for educational purposes. There is no direct download link available. Before obtaining the source code, if you wish to support our algorithmic trading operations, you can check out something interesting for you. Then, please follow the detailed steps below to manually install it in your MQL4/MQL5 MetaEditor.
π How to Install This Program (Manual Copy-Paste Guide)
Step-by-Step Instructions:
- Open your MQL5 MetaEditor (press F4 in MT5).
- Click "New" (or File > New) to create a new document.
- Select the program type:
- Choose Expert Advisor (template) if this is an EA.
- Choose Custom Indicator if this is an indicator.
- Enter the Name (e.g., ECN) and click "Next" twice.
- Click "Finish". A blank template page will be created.
- Scroll down and click the "Full Source Code Preview (CCL)" button below.
- Highlight the entire code in the preview box, right-click, and select Copy.
- Return to the blank MetaEditor page, Paste the code (Ctrl+V), replacing any default text.
- Click "Compile" (F7). Check the Toolbox panel: if there are 0 errors, your program is ready!
Summary: This section provides a manual copy-paste installation guide for MQL4/MQL5 Expert Advisors and Custom Indicators shared under CCL license. Users must open MetaEditor, create a new file, copy the source code from the preview section below, paste it into the editor, and compile the program to use it on MetaTrader 4/5 charts.
☕ Support the Developer: Click here to view something interesting for you..
//+------------------------------------------------------------------+
//| MA_Heiken_Ashi.mq5 |
//| Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-09-19 |
//| https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-09-19"
#property link "https://www.mql5.com/en/users/3rjfx"
#property version "1.00"
#property description "Moving Average-based Heiken Ashi indicator with alerts for MT5"
//--
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 4
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrWhiteSmoke,clrRed
#property indicator_label1 "MAHA-Op;MAHA-Hi;MAHA-Lo;MAHA-Cl"
//---
//-- Enumeration
enum YN
{
No,
Yes
};
//--
//---Input parameters for MA
input int inpMaPeriod = 5; // Input MA Period
input ENUM_MA_METHOD inpMethod = MODE_LWMA; // Input MA Method
//--- Input parameters for alerts
input YN alerts = Yes; // Display Alerts Pop-up on Chart (Yes) or (No)
input YN UseEmailAlert = No; // Email Alert (Yes) or (No)
input YN UseSendnotify = No; // Send Notification (Yes) or (No)
input int AlertOnBar = 1; // Input Alert On Bar (default bar 1)
//---
//-- buffers
double
HASOp[],
HASHi[],
HASLo[],
HASCl[],
HASCo[];
double
MAOPEN[],
MAHIGH[],
MALOW[],
MACLOSE[];
int
hMAO,
hMAH,
hMAL,
hMAC;
int BRC;
int aob;
//--
//--- variable for storing alert
datetime
altime;
int posalert,
prevalert;
string Albase,AlSubj;
//--- name of the indicator on a chart
string _pname;
string indiname;
//--- we will keep the number of values in the ATR indicator
int calculated,
bars_calculated=0;
//---------//
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,HASOp,INDICATOR_DATA);
SetIndexBuffer(1,HASHi,INDICATOR_DATA);
SetIndexBuffer(2,HASLo,INDICATOR_DATA);
SetIndexBuffer(3,HASCl,INDICATOR_DATA);
SetIndexBuffer(4,HASCo,INDICATOR_COLOR_INDEX);
//--
SetIndicatorHandle();
ResizeArrays();
aob=AlertOnBar;
//--
_pname=MQLInfoString(MQL_PROGRAM_NAME);
indiname="MAHA"+"("+strTF(Period())+","+string(inpMaPeriod)+","+EnumToString(inpMethod)+")";
IndicatorSetString(INDICATOR_SHORTNAME,indiname);
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--
return(INIT_SUCCEEDED);
//---
} //-end OnInit()
//---------//
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
Print(getUninitReasonText(reason));
if(hMAO!=INVALID_HANDLE) IndicatorRelease(hMAO);
if(hMAH!=INVALID_HANDLE) IndicatorRelease(hMAH);
if(hMAL!=INVALID_HANDLE) IndicatorRelease(hMAL);
if(hMAC!=INVALID_HANDLE) IndicatorRelease(hMAC);
//--
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[])
{
//---
CalculatedHandle(rates_total);
//--
int values_to_copy=CountCopyBurrefs(rates_total,prev_calculated);
//--
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation
if(!FillArrayFromBuffer(MAOPEN,hMAO,values_to_copy)) return(0);
if(!FillArrayFromBuffer(MAHIGH,hMAH,values_to_copy)) return(0);
if(!FillArrayFromBuffer(MALOW,hMAL,values_to_copy)) return(0);
if(!FillArrayFromBuffer(MACLOSE,hMAC,values_to_copy)) return(0);
//--
int start;
int min_start = 1 + aob;
//--- preliminary calculations
if(prev_calculated==0)
{
HASOp[0]=MAOPEN[0];
HASHi[0]=MAHIGH[0];
HASLo[0]=MALOW[0];
HASCl[0]=MACLOSE[0];
start=2;
start = fmax(2, min_start);
}
else
start=prev_calculated;
//--
//---
//--- the main loop of calculations
for(int i=start; i<BRC && !IsStopped(); i++)
{
double maha_open = (MAOPEN[i-1]+MACLOSE[i-1])/2.0;
double maha_close = (MAOPEN[i]+MAHIGH[i]+MALOW[i]+MACLOSE[i])/4.0;
double maha_high = fmax(MAHIGH[i],fmax(MAOPEN[i],MACLOSE[i]));
double maha_low = fmin(MALOW[i],fmin(MAOPEN[i],MACLOSE[i]));
//--
HASLo[i]=maha_low;
HASHi[i]=maha_high;
HASOp[i]=maha_open;
HASCl[i]=maha_close;
//--- set candle color
if(HASOp[i]<HASCl[i])
HASCo[i]=0.0; // set color to WhiteSmoke default
else
HASCo[i]=1.0; // set color to Red default
//--- set alert
if(HASCo[i-aob]==0.0 && HASCo[i-(1+aob)]==1.0) { posalert = 1; altime=time[i-aob]; }
if(HASCo[i-aob]==1.0 && HASCo[i-(1+aob)]==0.0) { posalert =-1; altime=time[i-aob]; }
//---
}
//--
PosAlerts(posalert,altime);
//--- memorize the number of values in the Average True Range indicator
bars_calculated=calculated;
//---
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
void SetIndicatorHandle(void)
{
//---
hMAO=iMA(Symbol(),0,inpMaPeriod,0,inpMethod,PRICE_OPEN);
hMAH=iMA(Symbol(),0,inpMaPeriod,0,inpMethod,PRICE_HIGH);
hMAL=iMA(Symbol(),0,inpMaPeriod,0,inpMethod,PRICE_LOW);
hMAC=iMA(Symbol(),0,inpMaPeriod,0,inpMethod,PRICE_CLOSE);
//--
return;
//---
} //-end SetIndicatorHandle()
//---------//
void ResizeArrays(void)
{
//---
BRC=iBars(Symbol(),Period());
ArrayResize(HASOp,BRC,BRC);
ArrayResize(HASHi,BRC,BRC);
ArrayResize(HASLo,BRC,BRC);
ArrayResize(HASCl,BRC,BRC);
ArrayResize(HASCo,BRC,BRC);
//--
ArrayResize(MAOPEN,BRC,BRC);
ArrayResize(MAHIGH,BRC,BRC);
ArrayResize(MALOW,BRC,BRC);
ArrayResize(MACLOSE,BRC,BRC);
//--
return;
//---
} //-end ResizeArrays()
//---------//
int CalculatedHandle(int bars)
{
//---
calculated=BarsCalculated(hMAO);
//--
if(calculated<bars)
{
Print("Not all data of MAHandle Price Open is calculated (",calculated," bars). Error ",GetLastError());
return(0);
}
calculated=BarsCalculated(hMAH);
if(calculated<bars)
{
Print("Not all data of MAHandle Price High is calculated (",calculated," bars). Error ",GetLastError());
return(0);
}
calculated=BarsCalculated(hMAL);
if(calculated<bars)
{
Print("Not all data of MAHandle Price Low is calculated (",calculated," bars). Error ",GetLastError());
return(0);
}
calculated=BarsCalculated(hMAC);
if(calculated<bars)
{
Print("Not all data of MAHandle Price Close is calculated (",calculated," bars). Error ",GetLastError());
return(0);
}
//--
return(calculated);
//---
} //-end CalculatedHandle()
//---------//
int CountCopyBurrefs(int barstotal,int prevc)
{
//---
int to_copy;
if(prevc==0 || calculated!=bars_calculated || barstotal>prevc+1)
{
//--- if the iMA Buffer array is greater than the number of values in the iMA indicator for symbol/period, then we don't copy everything
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>barstotal) to_copy=barstotal;
else 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
to_copy=(barstotal-prevc)+1;
}
//--
return(to_copy);
//---
} //-end CountCopyBurrefs()
//---------//
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iMA indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer for MA values
int ind_handle, // handle of the iMA indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iMA Buffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
//---
} //-end FillArrayFromBuffer()
//---------//
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()
//---------//
void Do_Alerts(string msgText,datetime altpos)
{
//---
//--
Print(" --- "+Symbol()+": "+msgText+
"\n --- at: ",TimeToString(altpos,TIME_DATE|TIME_MINUTES));
//--
if(alerts==Yes)
{
Alert(" --- "+Symbol()+": "+msgText+
" --- at: ",TimeToString(altpos,TIME_DATE|TIME_MINUTES));
}
//--
if(UseEmailAlert==Yes)
SendMail(_pname," --- "+Symbol()+" "+strTF(Period())+": "+msgText+
"\n --- at: "+TimeToString(altpos,TIME_DATE|TIME_MINUTES));
//--
if(UseSendnotify==Yes)
SendNotification(_pname+" --- "+Symbol()+" "+strTF(Period())+": "+msgText+
"\n --- at: "+TimeToString(altpos,TIME_DATE|TIME_MINUTES));
//--
return;
//--
//---
} //-end Do_Alerts()
//---------//
void PosAlerts(int curalerts,datetime altpos)
{
//---
//---
if((curalerts!=prevalert)&&(curalerts==1))
{
Albase=indiname;
AlSubj=Albase+" MA Heiken Ashi bar was Up ~ Open Buy";
Do_Alerts(AlSubj,altpos);
prevalert=curalerts;
}
//---
if((curalerts!=prevalert)&&(curalerts==-1))
{
Albase=indiname;
AlSubj=" MA Heiken Ashi bar was Down ~ Open Sell";
Do_Alerts(AlSubj,altpos);
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.***

No comments :
Post a Comment
Leave A Comment...