334 lines
12 KiB
MQL4
334 lines
12 KiB
MQL4
|
//+---------------------------------------------------------------------------------------+
|
||
|
#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 );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------------------+
|