FMIC/Indicators/Dōteki Heikin Ashi (Dynamic Average Foot∕Bar)/Doteki Heikin Ashi.mq4

334 lines
12 KiB
MQL4
Raw Permalink Normal View History

2025-05-30 14:55:26 +02:00
//+---------------------------------------------------------------------------------------+
#define _NAME_ "Dōteki Heikin Ashi"
//+---------------------------------------------------------------------------------------+
#property version "1.001"
#property description _NAME_
#property description "MetaTrader 4/5 Indicator (Build 2018-10-16 08:51)"
#property copyright "Copyright \x00A9 2018, Fernando M. I. Carreiro, All rights reserved"
#property link "https://www.mql5.com/en/users/FMIC"
#property strict
//+---------------------------------------------------------------------------------------+
// Indicator Setup
//+---------------------------------------------------------------------------------------+
#property indicator_chart_window
#ifdef __MQL5__
#property indicator_buffers 8
#property indicator_plots 1
#property indicator_label1 "dhaOpen;dhaHigh;dhaLow;dhaClose"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrLimeGreen, clrFireBrick, clrGold
#else
#property indicator_buffers 4
#property indicator_label1 "dhaOpen"
#property indicator_label2 "dhaClose"
#property indicator_label3 "dhaLowHigh"
#property indicator_label4 "dhaHighLow"
#property indicator_color1 clrFireBrick
#property indicator_color2 clrLimeGreen
#property indicator_color3 clrFireBrick
#property indicator_color4 clrLimeGreen
#property indicator_width1 3
#property indicator_width2 3
#property indicator_width3 1
#property indicator_width4 1
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_SOLID
#property indicator_style3 STYLE_SOLID
#property indicator_style4 STYLE_SOLID
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_type3 DRAW_HISTOGRAM
#property indicator_type4 DRAW_HISTOGRAM
#endif
//+---------------------------------------------------------------------------------------+
// Special Macro Definitions & Enumerations
//+---------------------------------------------------------------------------------------+
#ifdef __MQL4__ // for Compatibility with MQL5
#define ENUM_DRAW_TYPE int
#endif
//+---------------------------------------------------------------------------------------+
// Indicator Settings
//+---------------------------------------------------------------------------------------+
//--- Indicator Settings
//---- Define Averaging Parameters
input double
dblPeriod = 3.0; // Averaging Period for Heikin Ashi (Original = 3.0)
input bool
boolZeroLag = false, // Use a Zero-Lag Exponential Averaging
boolLineGraph = true, // Set Chart Mode to Line Graph
boolHideLine = false; // Hide Close Line in Line Graph mode
//--- Define Global Variables
ENUM_CHART_MODE
enumChartMode = WRONG_VALUE; // Save the Initial Chart Mode for Deinitialisation
color
clrChartLine = WRONG_VALUE; // Save Colour of Line Graph for Deinitialisation
double
dblEMAWeight, // Weight to be used for EMA
dblEMAComplement; // Complement of the Weight to be used for EMA
//---- Define Indicator Buffers
double
dblBufferOpen[], // Buffer Array for Opening Price
dblBufferHigh[], // Buffer Array for High Price (or Low)
dblBufferLow[], // Buffer Array for Low Price (or High)
dblBufferClose[], // Buffer Array for Closing Price
dblBufferEMA[], // Buffer Array for Exponential Moving Average of Total Price
dblBufferDEMA[], // Buffer Array for Double Exponential Moving Average
dblBufferZEMA[]; // Buffer Array for Zero-Lag Exponential Moving Average
#ifdef __MQL5__
double dblBufferColour[]; // Buffer Array for Candle Colour
#endif
//+---------------------------------------------------------------------------------------+
// Indicator Functions
//+---------------------------------------------------------------------------------------+
//--- Initialise Buffer Index and other Properties
int intInvalidParameter( string strText )
{
Print( "Error: ", strText );
return( INIT_PARAMETERS_INCORRECT );
}
int OnInit(void)
{
// Validate Input Parameters
if( dblPeriod <= 1.0 ) return( intInvalidParameter( "Invalid Averaging Period!" ) );
dblEMAWeight = 2.0 / ( dblPeriod + 1.0 );
dblEMAComplement = 1.0 - dblEMAWeight;
// Set Chart Mode
enumChartMode = WRONG_VALUE;
clrChartLine = WRONG_VALUE;
if( boolLineGraph )
{
enumChartMode = (ENUM_CHART_MODE) ChartGetInteger( 0, CHART_MODE );
ChartSetInteger( 0, CHART_MODE, CHART_LINE );
if( boolHideLine )
{
clrChartLine = (color) ChartGetInteger( 0, CHART_COLOR_CHART_LINE );
ChartSetInteger( 0, CHART_COLOR_CHART_LINE, clrNONE );
}
}
// Set Number of Significant Digits (Precision)
IndicatorSetInteger( INDICATOR_DIGITS, _Digits );
// Set Buffers
#ifdef __MQL5__
SetIndexBuffer( 0, dblBufferOpen , INDICATOR_DATA );
SetIndexBuffer( 1, dblBufferHigh , INDICATOR_DATA );
SetIndexBuffer( 2, dblBufferLow , INDICATOR_DATA );
SetIndexBuffer( 3, dblBufferClose , INDICATOR_DATA );
SetIndexBuffer( 4, dblBufferColour, INDICATOR_COLOR_INDEX );
SetIndexBuffer( 5, dblBufferEMA , INDICATOR_CALCULATIONS );
if( boolZeroLag )
{
SetIndexBuffer( 6, dblBufferDEMA, INDICATOR_CALCULATIONS );
SetIndexBuffer( 7, dblBufferZEMA, INDICATOR_CALCULATIONS );
}
ArraySetAsSeries( dblBufferColour, true );
#else
IndicatorBuffers( 5 );
SetIndexBuffer( 0, dblBufferOpen , INDICATOR_DATA );
SetIndexBuffer( 1, dblBufferClose , INDICATOR_DATA );
SetIndexBuffer( 2, dblBufferLow , INDICATOR_DATA );
SetIndexBuffer( 3, dblBufferHigh , INDICATOR_DATA );
SetIndexBuffer( 4, dblBufferEMA , INDICATOR_CALCULATIONS );
if( boolZeroLag )
{
IndicatorBuffers( 7 );
SetIndexBuffer( 5, dblBufferDEMA, INDICATOR_CALCULATIONS );
SetIndexBuffer( 6, dblBufferZEMA, INDICATOR_CALCULATIONS );
}
else
SetIndexStyle( 0, DRAW_HISTOGRAM, STYLE_SOLID );
SetIndexStyle( 1, DRAW_HISTOGRAM, STYLE_SOLID );
SetIndexStyle( 2, DRAW_HISTOGRAM, STYLE_SOLID );
SetIndexStyle( 3, DRAW_HISTOGRAM, STYLE_SOLID );
#endif
// Set Buffers as Series
ArraySetAsSeries( dblBufferOpen, true );
ArraySetAsSeries( dblBufferHigh, true );
ArraySetAsSeries( dblBufferLow, true );
ArraySetAsSeries( dblBufferClose, true );
ArraySetAsSeries( dblBufferEMA, true );
if( boolZeroLag )
{
ArraySetAsSeries( dblBufferDEMA, true );
ArraySetAsSeries( dblBufferZEMA, true );
}
// Set Indicator Name
IndicatorSetString( INDICATOR_SHORTNAME,
_NAME_ + ( boolZeroLag ? "(Z" : "(" ) + DoubleToString( dblPeriod, 3 ) + ")" );
// Successful Initialisation of Indicator
return( INIT_SUCCEEDED );
}
//--- Deinitialise Procedure
void OnDeinit(const int reason)
{
if( boolLineGraph && ( (int) enumChartMode != WRONG_VALUE ) )
ChartSetInteger( 0, CHART_MODE, enumChartMode );
if( boolHideLine && ( (int) clrChartLine != WRONG_VALUE ) )
ChartSetInteger( 0, CHART_COLOR_CHART_LINE, clrChartLine );
}
//--- Calculate Indicator Values
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 intPrevCalc = prev_calculated;
ArraySetAsSeries( open, true );
ArraySetAsSeries( high, true );
ArraySetAsSeries( low, true );
ArraySetAsSeries( close, true );
// Define Local Variables
bool
boolUpCandle, boolDownCandle;
double
dblClose, dblEMA, dblDEMA = 0, dblZEMA = 0,
dblClosePrevious, dblEMAPrevious, dblDEMAPrevious,
dblOpen = EMPTY_VALUE, dblLow, dblHigh;
int
intMax = rates_total - 1,
intLimit = rates_total - ( ( intPrevCalc < 1 ) ? 1 : intPrevCalc ),
intIndex = intLimit,
intIndexPrev = intIndex + 1;
// Main Loop, Fill in the arrays with data values
for( ; intIndex >= 0; intIndex--, intIndexPrev-- )
{
// Calculate Total Price for Close
dblLow = low[ intIndex ];
dblHigh = high[ intIndex ];
dblBufferClose[ intIndex ] =
dblClose = NormalizeDouble(
( open[ intIndex ]
+ dblHigh
+ dblLow
+ close[ intIndex ]
) * 0.25,
_Digits );
// Calculate other Buffer Values
if( intIndex < intMax )
{
// Get Previous Total Price
dblClosePrevious = dblBufferClose[ intIndexPrev ];
// Update EMA Values
dblEMAPrevious = dblBufferEMA[ intIndexPrev ];
dblOpen =
dblEMA = dblEMAPrevious
+ ( dblClosePrevious - dblEMAPrevious )
* dblEMAWeight;
// Update DEMA and ZEMA
if( boolZeroLag )
{
dblDEMAPrevious = dblBufferDEMA[ intIndexPrev ];
dblBufferDEMA[ intIndex ] =
dblDEMA = dblDEMAPrevious
+ ( dblEMA - dblDEMAPrevious )
* dblEMAWeight;
dblBufferZEMA[ intIndex ] =
dblOpen =
dblZEMA = dblEMA * 2 - dblDEMA;
}
dblLow = fmin( fmin( dblLow, dblOpen ), dblClose );
dblHigh = fmax( fmax( dblHigh, dblOpen ), dblClose );
}
else
{
// Define Initial Values
dblClosePrevious =
dblOpen =
dblZEMA =
dblDEMA =
dblEMA = open[ intIndex ]
+ ( close[ intIndex ] - open[ intIndex ] )
* dblEMAWeight;
}
// Set Buffer Values
dblBufferEMA[ intIndex ] = dblEMA;
if( boolZeroLag )
{
dblBufferDEMA[ intIndex ] = dblDEMA;
dblBufferZEMA[ intIndex ] = dblZEMA;
}
dblBufferOpen[ intIndex ] =
dblOpen = NormalizeDouble( dblOpen, _Digits );
boolUpCandle = dblOpen < dblClose;
boolDownCandle = dblOpen > dblClose;
#ifdef __MQL5__
dblBufferLow[ intIndex ] = dblLow;
dblBufferHigh[ intIndex ] = dblHigh;
dblBufferColour[ intIndex ] = boolUpCandle ? 0 : ( boolDownCandle ? 1 : 2 );
#else
if( !boolUpCandle && !boolDownCandle )
boolUpCandle = dblClosePrevious < dblClose;
if( boolUpCandle )
{
dblBufferLow[ intIndex ] = dblLow;
dblBufferHigh[ intIndex ] = dblHigh;
}
else
{
dblBufferLow[ intIndex ] = dblHigh;
dblBufferHigh[ intIndex ] = dblLow;
}
#endif
}
// Return value of prev_calculated for next call
return( rates_total );
}
//+---------------------------------------------------------------------------------------+