Files
xMQL5/BKPS/14031218/Documents/BKP/x-saherelm.x121.xwz.mq5
T
2025-03-08 22:04:05 +03:30

3438 lines
82 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XWZ
// Description: XWZ ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121 XWZ Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121_XWZ"
//
// Includes Common Library ...
#include "../Classes/x-saherelm.x-alert.class.mq5"
#include "../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../Classes/x-saherelm.x-poi.drawer.class.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
//
input group "Calculation";
input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Detect Price Type
//
input group "MA Detection";
input int maLength = 20; // MA Length
input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method
//
input group "ATR StopLoss";
input int atrLength = 14; // ATR Length
input double atrMultiplier = 2; // ATR Multiplier
//
input group "ADX Detection";
input int adxLength = 14; // ADX Length
input double adxThreshold = 25; // ADX Threshold for Strong Trends
//
input group "Alert";
input bool mXWZEnableAlerts = true; // Enable Alerts
input bool mXWZPushAlerts = false; // Push Alerts
input bool mXWZMailAlerts = false; // Mail Alerts
input bool mXWZTerminalAlerts = false; // Terminal Alerts
//
// Presentation ...
input group "Presentation";
//
input group "Buffer Presentation";
input bool showMA = true; // Show Moving Average
input bool showPin = true; // Show Pin Bars
input bool showSwing = true; // Show Swing Bars
input bool showTrend = true; // Show Trend
input bool showEngulf = true; // Show Engulf Bars
input bool showLongSL = true; // Show Long SL
input bool showShortSL = true; // Show Short SL
input bool showMomentum = true; // Show Momentum Bars
input bool showRejection = true; // Show Rejection Bars
//
input group "POI Presentation";
input bool showPOIs = false; // Show POI(s)
input bool showActivatedPOIs = true; // Show Activated POI(s)
input bool showOrderBlocks = true; // Show Order Blocks
input bool showFairValueGaps = true; // Show Fair Value Gaps
input bool showSupportZones = false; // Show Support Zones
input bool showResistanceZones = false; // Show Resistance Zones
//
input group "Presentation Config";
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
input int upTrendArrowCode = 236; // Up Trend Arrow Code
input int downTrendArrowCode = 238; // Down Trend Arrow Code
input int swingLowArrowCode = 108; // Swing Low Arrow Code
input int swingHighArrowCode = 108; // Swing High Arrow Code
input int bullishPinArrowCode = 246; // Bullish Pin Arrow Code
input int bearishPinArrowCode = 248; // Bearish Pin Arrow Code
input int bullishEngulfArrowCode = 200; // Bullish Engulf Arrow Code
input int bearishEngulfArrowCode = 202; // Bearish Engulf Arrow Code
input int bullishMomentumArrowCode = 233; // Bullish Momentum Arrow Code
input int bearishMomentumArrowCode = 234; // Bearish Momentum Arrow Code
input int bullishRejectionArrowCode = 241; // Bullish Rejection Arrow Code
input int bearishRejectionArrowCode = 242; // Bearish Rejection Arrow Code
//
#property indicator_chart_window
//
#property indicator_buffers 17
#property indicator_plots 15
//
// Plot Buffers ...
//
#define maBufferIndex 0
double maBuffer[];
//
#property indicator_label1 "X121-XWZ MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSkyBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//
#define longSLBufferIndex 1
double longSLBuffer[];
//
#property indicator_label2 "X121-XWZ Long SL"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrOrange
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//
#define shortSLBufferIndex 2
double shortSLBuffer[];
//
#property indicator_label3 "X121-XWZ Short SL"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrOrange
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//
#define upTrendBufferIndex 3
double upTrendBuffer[];
//
#property indicator_label4 "X121-XWZ Trend Up"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrAqua
#property indicator_width4 3
//
#define downTrendBufferIndex 4
double downTrendBuffer[];
//
#property indicator_label5 "X121-XWZ Trend Down"
#property indicator_type5 DRAW_ARROW
#property indicator_color5 clrMagenta
#property indicator_width5 3
//
#define bullishMomentumBufferIndex 5
double bullishMomentumBuffer[];
//
#property indicator_label6 "X121-XWZ Bull Momentum"
#property indicator_type6 DRAW_ARROW
#property indicator_color6 clrAqua
#property indicator_width6 3
//
#define bearishMomentumBufferIndex 6
double bearishMomentumBuffer[];
//
#property indicator_label7 "X121-XWZ Bear Momentum"
#property indicator_type7 DRAW_ARROW
#property indicator_color7 clrMagenta
#property indicator_width7 3
//
#define bullishRejectionBufferIndex 7
double bullishRejectionBuffer[];
//
#property indicator_label8 "X121-XWZ Bull Rejection"
#property indicator_type8 DRAW_ARROW
#property indicator_color8 clrAqua
#property indicator_width8 3
//
#define bearishRejectionBufferIndex 8
double bearishRejectionBuffer[];
//
#property indicator_label9 "X121-XWZ Bear Rejection"
#property indicator_type9 DRAW_ARROW
#property indicator_color9 clrMagenta
#property indicator_width9 3
//
#define bullishPinBufferIndex 9
double bullishPinBuffer[];
//
#property indicator_label10 "X121-XWZ Bull Pin"
#property indicator_type10 DRAW_ARROW
#property indicator_color10 clrAqua
#property indicator_width10 3
//
#define bearishPinBufferIndex 10
double bearishPinBuffer[];
//
#property indicator_label11 "X121-XWZ Bear Pin"
#property indicator_type11 DRAW_ARROW
#property indicator_color11 clrMagenta
#property indicator_width11 3
//
#define bullishEngulfBufferIndex 11
double bullishEngulfBuffer[];
//
#property indicator_label12 "X121-XWZ Bull Engulf"
#property indicator_type12 DRAW_ARROW
#property indicator_color12 clrAqua
#property indicator_width12 3
//
#define bearishEngulfBufferIndex 12
double bearishEngulfBuffer[];
//
#property indicator_label13 "X121-XWZ Bear Engulf"
#property indicator_type13 DRAW_ARROW
#property indicator_color13 clrMagenta
#property indicator_width13 3
//
#define swingLowBufferIndex 13
double swingLowBuffer[];
//
#property indicator_label14 "X121-XWZ Swing Low"
#property indicator_type14 DRAW_ARROW
#property indicator_color14 clrAqua
#property indicator_width14 3
//
#define swingHighBufferIndex 14
double swingHighBuffer[];
//
#property indicator_label15 "X121-XWZ Swing High"
#property indicator_type15 DRAW_ARROW
#property indicator_color15 clrMagenta
#property indicator_width15 3
//
// Data Buffers ...
//
int mLastBufferIndex = 14;
//
#define atrBufferIndex mLastBufferIndex + 1
double atrBuffer[];
//
#define adxBufferIndex mLastBufferIndex + 2
double adxBuffer[];
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
// MA Handler ...
int maHandler = INVALID_HANDLE;
//
// ATR Handler ...
int atrHandler = INVALID_HANDLE;
//
// ADX Handler ...
int adxHandler = INVALID_HANDLE;
//
XCAlert *mXWZAlert;
CArrayObj mXWZDrawnObjects;
XCPOIDrawer *mXWZPOIDrawer;
XCBarAnalyser *mXWZBarAnalyser;
//
datetime lastBullishTrend = NULL;
datetime lastBearishTrend = NULL;
//
datetime lastCrossedOverMA = NULL;
datetime lastCrossedUnderMA = NULL;
//
// POI(s) ...
//
bool mXWZDetectOrderBlocks = true;
bool mXWZDetectFairValueGaps = false;
bool mXWZDetectSupportZones = false;
bool mXWZDetectResistanceZones = false;
//
bool filterPOIsUsingMa = false; // Filter POI(s) Using MA
bool filterPOIsUsingZones = false; // Filter POI(s) Using Zones
//
XCFVG *lastBullFVG;
XCFVG *lastBearFVG;
XCOrderBlock *lastBullOB;
XCOrderBlock *lastBearOB;
XCSupportZone *lastSupport;
XCResistanceZone *lastResistance;
//
// Un Activated POI(s) ...
XCFVG *mXWZUnActivatedFVGs[];
XCOrderBlock *mXWZUnActivatedOBs[];
XCSupportZone *mXWZUnActivatedSupportZones[];
XCResistanceZone *mXWZUnActivatedResistanceZones[];
//
// Activated POI(s) ...
XCFVG *mXWZActivatedFVGs[];
XCOrderBlock *mXWZActivatedOBs[];
XCSupportZone *mXWZActivatedSupportZones[];
XCResistanceZone *mXWZActivatedResistanceZones[];
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
mXWZDrawnObjects.Clear();
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize Indicator Handlers ...
//
// MA ...
maHandler = iMA(
_Symbol,
_Period,
maLength,
0,
maMethod,
appliedTo //
);
bool isInited = maHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// ATR ...
atrHandler = iATR(
_Symbol,
_Period,
atrLength //
);
isInited = maHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// ADX ...
adxHandler = iADX(
_Symbol,
_Period,
adxLength //
);
isInited = maHandler != INVALID_HANDLE;
if (!isInited)
{
return INIT_FAILED;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
IndicatorSetInteger(INDICATOR_DIGITS, 2);
//
mXWZPOIDrawer = new XCPOIDrawer();
ConfigurePOIDrawer();
//
mXWZAlert = new XCAlert();
ConfigureAlert();
//
mXWZBarAnalyser = new XCBarAnalyser();
//
// Init Succeed ...
return INIT_SUCCEEDED;
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
IndicatorRelease(maHandler);
IndicatorRelease(atrHandler);
IndicatorRelease(adxHandler);
//
mXWZDrawnObjects.Clear();
//
ZeroMemory(mXWZAlert);
ZeroMemory(mXWZPOIDrawer);
ZeroMemory(mXWZBarAnalyser);
//
Clean(mXWZActivatedOBs);
Clean(mXWZActivatedFVGs);
Clean(mXWZActivatedSupportZones);
Clean(mXWZActivatedResistanceZones);
//
Clean(mXWZUnActivatedOBs);
Clean(mXWZUnActivatedFVGs);
Clean(mXWZUnActivatedSupportZones);
Clean(mXWZUnActivatedResistanceZones);
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
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[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Validate Calculated Bars ...
//
// MA ...
int maCalculatedBars = BarsCalculated(maHandler);
//
// ATR ...
int atrCalculatedBars = BarsCalculated(atrHandler);
//
// ADX ...
int adxCalculatedBars = BarsCalculated(adxHandler);
//
bool isPassedRequiredCalculatedBars =
//
// MA ...
maCalculatedBars >= maxLength &&
//
// ATR ...
atrCalculatedBars >= maxLength &&
//
// ADX ...
adxCalculatedBars >= maxLength
//
;
if (!isPassedRequiredCalculatedBars)
{
return prev_calculated;
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// MA ...
int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer);
//
// ATR ...
int copiedAtr = CopyBuffer(atrHandler, MAIN_LINE, 0, limit, atrBuffer);
//
// ADX ...
int copiedAdxs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer);
//
// Validate Copied Items ...
bool isPassedRequiredCopiedItems =
//
// MA ...
copiedMas > 0 &&
//
// ATR ...
copiedAtr > 0 &&
//
// ADX ...
copiedAdxs > 0
//
;
if (!isPassedRequiredCopiedItems)
{
return prev_calculated;
}
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
//
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Functions ...
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
// MA ...
maLength > 0 &&
//
// ATR ...
atrLength > 0 &&
atrMultiplier > 0 &&
//
// ADX ...
adxLength > 0 &&
adxThreshold > 0
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(maLength, atrLength);
result = MathMax(result, adxLength);
//
return result;
}
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// MA Buffer ...
//
ENUM_DRAW_TYPE maDrawType = showMA ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(maBuffer, true);
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(maBufferIndex, PLOT_SHOW_DATA, showMA);
PlotIndexSetInteger(maBufferIndex, PLOT_DRAW_TYPE, maDrawType);
//
PlotIndexSetDouble(maBufferIndex, PLOT_EMPTY_VALUE, 0);
//
// LONG SL Buffer ...
//
ENUM_DRAW_TYPE longSLDrawType = showLongSL ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(longSLBuffer, true);
SetIndexBuffer(longSLBufferIndex, longSLBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(longSLBufferIndex, PLOT_SHOW_DATA, showLongSL);
PlotIndexSetInteger(longSLBufferIndex, PLOT_DRAW_TYPE, longSLDrawType);
//
PlotIndexSetDouble(longSLBufferIndex, PLOT_EMPTY_VALUE, 0);
//
// SHORT SL Buffer ...
//
ENUM_DRAW_TYPE shortSLDrawType = showShortSL ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(shortSLBuffer, true);
SetIndexBuffer(shortSLBufferIndex, shortSLBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(shortSLBufferIndex, PLOT_SHOW_DATA, showShortSL);
PlotIndexSetInteger(shortSLBufferIndex, PLOT_DRAW_TYPE, shortSLDrawType);
//
PlotIndexSetDouble(shortSLBufferIndex, PLOT_EMPTY_VALUE, 0);
//
// UP Trend ...
//
ENUM_DRAW_TYPE upTrendDrawType = showTrend ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(upTrendBuffer, true);
SetIndexBuffer(upTrendBufferIndex, upTrendBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(upTrendBufferIndex, PLOT_SHOW_DATA, showTrend);
PlotIndexSetInteger(upTrendBufferIndex, PLOT_DRAW_TYPE, upTrendDrawType);
//
PlotIndexSetDouble(upTrendBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(upTrendBufferIndex, PLOT_ARROW, upTrendArrowCode);
//
// DOWN Trend ...
//
ENUM_DRAW_TYPE downTrendDrawType = showTrend ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(downTrendBuffer, true);
SetIndexBuffer(downTrendBufferIndex, downTrendBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(downTrendBufferIndex, PLOT_SHOW_DATA, showTrend);
PlotIndexSetInteger(downTrendBufferIndex, PLOT_DRAW_TYPE, downTrendDrawType);
//
PlotIndexSetDouble(downTrendBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(downTrendBufferIndex, PLOT_ARROW, downTrendArrowCode);
//
// Bullish Momentum ...
//
ENUM_DRAW_TYPE bullishMomentumDrawType = showMomentum ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bullishMomentumBuffer, true);
SetIndexBuffer(bullishMomentumBufferIndex, bullishMomentumBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bullishMomentumBufferIndex, PLOT_SHOW_DATA, showMomentum);
PlotIndexSetInteger(bullishMomentumBufferIndex, PLOT_DRAW_TYPE, bullishMomentumDrawType);
//
PlotIndexSetDouble(bullishMomentumBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bullishMomentumBufferIndex, PLOT_ARROW, bullishMomentumArrowCode);
//
// Bearish Momentum ...
//
ENUM_DRAW_TYPE bearishMomentumDrawType = showMomentum ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bearishMomentumBuffer, true);
SetIndexBuffer(bearishMomentumBufferIndex, bearishMomentumBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bearishMomentumBufferIndex, PLOT_SHOW_DATA, showMomentum);
PlotIndexSetInteger(bearishMomentumBufferIndex, PLOT_DRAW_TYPE, bearishMomentumDrawType);
//
PlotIndexSetDouble(bearishMomentumBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bearishMomentumBufferIndex, PLOT_ARROW, bearishMomentumArrowCode);
//
// Bullish Rejection ...
//
ENUM_DRAW_TYPE bullishRejectionDrawType = showRejection ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bullishRejectionBuffer, true);
SetIndexBuffer(bullishRejectionBufferIndex, bullishRejectionBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bullishRejectionBufferIndex, PLOT_SHOW_DATA, showRejection);
PlotIndexSetInteger(bullishRejectionBufferIndex, PLOT_DRAW_TYPE, bullishRejectionDrawType);
//
PlotIndexSetDouble(bullishRejectionBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bullishRejectionBufferIndex, PLOT_ARROW, bullishRejectionArrowCode);
//
// Bearish Rejection ...
//
ENUM_DRAW_TYPE bearishRejectionDrawType = showRejection ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bearishRejectionBuffer, true);
SetIndexBuffer(bearishRejectionBufferIndex, bearishRejectionBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bearishRejectionBufferIndex, PLOT_SHOW_DATA, showRejection);
PlotIndexSetInteger(bearishRejectionBufferIndex, PLOT_DRAW_TYPE, bearishRejectionDrawType);
//
PlotIndexSetDouble(bearishRejectionBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bearishRejectionBufferIndex, PLOT_ARROW, bearishRejectionArrowCode);
//
// Bullish Pin ...
//
ENUM_DRAW_TYPE bullishPinDrawType = showPin ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bullishPinBuffer, true);
SetIndexBuffer(bullishPinBufferIndex, bullishPinBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bullishPinBufferIndex, PLOT_SHOW_DATA, showPin);
PlotIndexSetInteger(bullishPinBufferIndex, PLOT_DRAW_TYPE, bullishPinDrawType);
//
PlotIndexSetDouble(bullishPinBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bullishPinBufferIndex, PLOT_ARROW, bullishPinArrowCode);
//
// Bearish Pin ...
//
ENUM_DRAW_TYPE bearishPinDrawType = showPin ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bearishPinBuffer, true);
SetIndexBuffer(bearishPinBufferIndex, bearishPinBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bearishPinBufferIndex, PLOT_SHOW_DATA, showPin);
PlotIndexSetInteger(bearishPinBufferIndex, PLOT_DRAW_TYPE, bearishPinDrawType);
//
PlotIndexSetDouble(bearishPinBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bearishPinBufferIndex, PLOT_ARROW, bearishPinArrowCode);
//
// Bullish Engulf ...
//
ENUM_DRAW_TYPE bullishEngulfDrawType = showEngulf ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bullishEngulfBuffer, true);
SetIndexBuffer(bullishEngulfBufferIndex, bullishEngulfBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bullishEngulfBufferIndex, PLOT_SHOW_DATA, showEngulf);
PlotIndexSetInteger(bullishEngulfBufferIndex, PLOT_DRAW_TYPE, bullishEngulfDrawType);
//
PlotIndexSetDouble(bullishEngulfBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bullishEngulfBufferIndex, PLOT_ARROW, bullishEngulfArrowCode);
//
// Bearish Engulf ...
//
ENUM_DRAW_TYPE bearishEngulfDrawType = showEngulf ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bearishEngulfBuffer, true);
SetIndexBuffer(bearishEngulfBufferIndex, bearishEngulfBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bearishEngulfBufferIndex, PLOT_SHOW_DATA, showEngulf);
PlotIndexSetInteger(bearishEngulfBufferIndex, PLOT_DRAW_TYPE, bearishEngulfDrawType);
//
PlotIndexSetDouble(bearishEngulfBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bearishEngulfBufferIndex, PLOT_ARROW, bearishEngulfArrowCode);
//
// Swing Low ...
//
ENUM_DRAW_TYPE swingLowDrawType = showSwing ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(swingLowBuffer, true);
SetIndexBuffer(swingLowBufferIndex, swingLowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(swingLowBufferIndex, PLOT_SHOW_DATA, showSwing);
PlotIndexSetInteger(swingLowBufferIndex, PLOT_DRAW_TYPE, swingLowDrawType);
//
PlotIndexSetDouble(swingLowBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(swingLowBufferIndex, PLOT_ARROW, swingLowArrowCode);
//
// Swing High ...
//
ENUM_DRAW_TYPE swingHighDrawType = showSwing ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(swingHighBuffer, true);
SetIndexBuffer(swingHighBufferIndex, swingHighBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(swingHighBufferIndex, PLOT_SHOW_DATA, showSwing);
PlotIndexSetInteger(swingHighBufferIndex, PLOT_DRAW_TYPE, swingHighDrawType);
//
PlotIndexSetDouble(swingHighBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(swingHighBufferIndex, PLOT_ARROW, swingHighArrowCode);
//
// DATA Buffers ...
//
ArraySetAsSeries(atrBuffer, true);
SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS);
//
ArraySetAsSeries(adxBuffer, true);
SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS);
}
/**
* Calculate Custom Buffers ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
//
// bool canCalculate = true;
bool canCalculate =
barsLimit == 0 ||
bar_index <= barsLimit;
if (canCalculate)
{
//
CalculatedPOIs(
//
bar_index,
prevCalculated,
ratesTotal,
//
open,
high,
close,
low,
tickVolume //
);
//
CalculateValues(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(bar_index);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
maBuffer[barIndex] = 0;
atrBuffer[barIndex] = 0;
adxBuffer[barIndex] = 0;
longSLBuffer[barIndex] = 0;
shortSLBuffer[barIndex] = 0;
upTrendBuffer[barIndex] = 0;
swingLowBuffer[barIndex] = 0;
swingHighBuffer[barIndex] = 0;
downTrendBuffer[barIndex] = 0;
bullishPinBuffer[barIndex] = 0;
bearishPinBuffer[barIndex] = 0;
bullishEngulfBuffer[barIndex] = 0;
bearishEngulfBuffer[barIndex] = 0;
bullishMomentumBuffer[barIndex] = 0;
bearishMomentumBuffer[barIndex] = 0;
bullishRejectionBuffer[barIndex] = 0;
bearishRejectionBuffer[barIndex] = 0;
}
/**
* Calculate Vales ...
*
* @param bar_index: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateValues(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Prepare Requirements ...
//
XOHCL iBar;
bool isInited = iBar.Init(
_Symbol,
_Period,
bar_index //
);
if (!isInited)
{
//
iBar.Clean();
return;
}
//
XOHCL pBar;
isInited = iBar.GetPreviousBar(pBar);
if (!isInited)
{
//
iBar.Clean();
pBar.Clean();
return;
}
int pIndex = pBar.Index();
//
// Calculate Applied Price ...
double iPrice = GetAppliedPrice(
appliedTo,
open,
high,
low,
close,
bar_index //
);
//
double iMa = maBuffer[bar_index];
double iMaPrev = maBuffer[pIndex];
double iAtr = atrBuffer[bar_index];
double iAdx = adxBuffer[bar_index];
double iAppliedAtr = iAtr * atrMultiplier;
//
double points = GetPoints(_Symbol);
double points10 = 10 * points;
//
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
bool hasLastBullOB = lastBullOB != NULL &&
lastBullOB.IsValid();
bool hasLastBearOB = lastBearOB != NULL &&
lastBearOB.IsValid();
//
bool hasLastBullFVG = lastBullFVG != NULL &&
lastBullFVG.IsValid();
bool hasLastBearFVG = lastBearFVG != NULL &&
lastBearFVG.IsValid();
//
bool hasLastSupport = lastSupport != NULL &&
lastSupport.IsValid();
//
bool hasLastResistance = lastResistance != NULL &&
lastResistance.IsValid();
//
// Calculate Crossing Over / Under Ma ...
bool isCrossedOverMA =
//
iBar.low > iMa &&
(pBar.low <= iMaPrev &&
(pBar.GetUp() <= iMaPrev ||
pBar.GetDown() <= iMaPrev))
//
;
bool isCrossedUnderMA =
//
iBar.high < iMa &&
(pBar.high >= iMaPrev &&
(pBar.GetUp() >= iMaPrev ||
pBar.GetDown() >= iMaPrev))
//
;
lastCrossedOverMA =
isCrossedOverMA
? iBar.time
: lastCrossedOverMA;
lastCrossedUnderMA =
isCrossedUnderMA
? iBar.time
: lastCrossedUnderMA;
//
// SL Buffers ...
//
double iLongSL = iPrice - iAppliedAtr;
double iShortSL = iPrice + iAppliedAtr;
//
longSLBuffer[bar_index] = iLongSL;
shortSLBuffer[bar_index] = iShortSL;
//
// Trend Buffers ...
//
bool isUpTrend =
//
iPrice > iMa &&
iBar.low < iMa &&
iAdx > adxThreshold
//
;
//
bool isDownTrend =
//
iPrice < iMa &&
iBar.high > iMa &&
iAdx > adxThreshold
//
;
//
double upTrendValue = 0;
double downTrendValue = 0;
if (isUpTrend)
{
//
lastBullishTrend = iBar.time;
upTrendValue = iBar.low;
}
if (isDownTrend)
{
//
lastBearishTrend = iBar.time;
downTrendValue = iBar.high;
}
//
upTrendBuffer[bar_index] = upTrendValue;
downTrendBuffer[bar_index] = downTrendValue;
//
// Momentum Buffers ...
//
bool isMomentum = mXWZBarAnalyser
.IsMomentumBar(
iBar,
iDir,
1, // Extends ...
70 // Body Percent ...
);
bool isBullishMomentum =
isMomentum &&
IsBullish(iDir);
bool isBearishMomentum =
isMomentum &&
IsBearish(iDir);
if (isMomentum)
{
//
double iBullMomentumValue = 0;
double iBearMomentumValue = 0;
//
if (isBullishMomentum)
{
//
double selectedValue = iBar.low;
//
iBullMomentumValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBullOB
? 0
: IsInside(
selectedValue,
lastBullOB //
)
? selectedValue
: 0;
//
iBullMomentumValue =
!filterPOIsUsingMa
? iBullMomentumValue
: iBullMomentumValue < iMa
? iBullMomentumValue
: 0;
}
//
if (isBearishMomentum)
{
//
double selectedValue = iBar.high;
//
iBearMomentumValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBearOB
? 0
: IsInside(
selectedValue,
lastBearOB //
)
? selectedValue
: 0;
//
iBearMomentumValue =
!filterPOIsUsingMa
? iBearMomentumValue
: iBearMomentumValue > iMa
? iBearMomentumValue
: 0;
}
//
bullishMomentumBuffer[bar_index] = iBullMomentumValue;
bearishMomentumBuffer[bar_index] = iBearMomentumValue;
}
//
// Rejection Buffers ...
//
bool isRejection = mXWZBarAnalyser
.IsRejectionBar(
iBar,
iDir,
1, // Extends ...
70 // Body Percent ...
);
bool isBullishRejection =
isRejection &&
IsBullish(iDir);
bool isBearishRejection =
isRejection &&
IsBearish(iDir);
if (isRejection)
{
//
double iBullRejectionValue = 0;
double iBearRejectionValue = 0;
//
if (isBullishRejection)
{
//
double selectedValue = iBar.low;
//
iBullRejectionValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBullOB
? 0
: IsInside(
selectedValue,
lastBullOB //
)
? selectedValue
: 0;
//
iBullRejectionValue =
!filterPOIsUsingMa
? iBullRejectionValue
: iBullRejectionValue < iMa
? iBullRejectionValue
: 0;
}
//
if (isBearishRejection)
{
//
double selectedValue = iBar.high;
//
iBearRejectionValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBearOB
? 0
: IsInside(
selectedValue,
lastBearOB //
)
? selectedValue
: 0;
//
iBearRejectionValue =
!filterPOIsUsingMa
? iBearRejectionValue
: iBearRejectionValue > iMa
? iBearRejectionValue
: 0;
}
//
bullishRejectionBuffer[bar_index] = iBullRejectionValue;
bearishRejectionBuffer[bar_index] = iBearRejectionValue;
}
//
// Pin Buffers ...
//
bool isPin = mXWZBarAnalyser
.IsPinBar(
iBar,
iDir,
0, // Extends ...
50, // Shadow Percent ...
25 // Body Percent ...
);
bool isBullishPin =
isPin &&
IsBullish(iDir);
bool isBearishPin =
isPin &&
IsBearish(iDir);
if (isPin)
{
//
double iBullPinValue = 0;
double iBearPinValue = 0;
//
if (isBullishPin)
{
//
double selectedValue = iBar.low;
//
iBullPinValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBullOB
? 0
: IsInside(
selectedValue,
lastBullOB //
)
? selectedValue
: 0;
//
iBullPinValue =
!filterPOIsUsingMa
? iBullPinValue
: iBullPinValue < iMa
? iBullPinValue
: 0;
}
//
if (isBearishPin)
{
//
double selectedValue = iBar.high;
//
iBearPinValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBearOB
? 0
: IsInside(
selectedValue,
lastBearOB //
)
? selectedValue
: 0;
//
iBearPinValue =
!filterPOIsUsingMa
? iBearPinValue
: iBearPinValue > iMa
? iBearPinValue
: 0;
}
//
bullishPinBuffer[bar_index] = iBullPinValue;
bearishPinBuffer[bar_index] = iBearPinValue;
}
//
// Engulf Buffers ...
//
bool isEngulf = mXWZBarAnalyser
.IsEngulfBar(
iBar,
iDir,
1, // Extends ...
70 // Body Percent ...
);
bool isBullishEngulf =
isEngulf &&
IsBullish(iDir);
bool isBearishEngulf =
isEngulf &&
IsBearish(iDir);
if (isEngulf)
{
//
double iBullEngulfValue = 0;
double iBearEngulfValue = 0;
//
if (isBullishEngulf)
{
//
double selectedValue = iBar.low;
//
iBullEngulfValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBullOB
? 0
: IsInside(
selectedValue,
lastBullOB //
)
? selectedValue
: 0;
//
iBullEngulfValue =
!filterPOIsUsingMa
? iBullEngulfValue
: iBullEngulfValue < iMa
? iBullEngulfValue
: 0;
}
//
if (isBearishEngulf)
{
//
double selectedValue = iBar.high;
//
iBearEngulfValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBearOB
? 0
: IsInside(
selectedValue,
lastBearOB //
)
? selectedValue
: 0;
//
iBearEngulfValue =
!filterPOIsUsingMa
? iBearEngulfValue
: iBearEngulfValue > iMa
? iBearEngulfValue
: 0;
}
//
bullishEngulfBuffer[bar_index] = iBullEngulfValue;
bearishEngulfBuffer[bar_index] = iBearEngulfValue;
}
//
// Swing Buffers ...
//
bool isSwing = mXWZBarAnalyser
.IsSwing(
iBar,
iDir,
2 // Range ...
);
bool isSwingLow =
isSwing &&
IsBullish(iDir);
bool isSwingHigh =
isSwing &&
IsBearish(iDir);
if (isSwing)
{
//
double iSwingLowValue = 0;
double iSwingHighValue = 0;
//
if (isSwingLow)
{
//
double selectedValue = iBar.low;
//
iSwingLowValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBullOB
? 0
: IsBelow(
selectedValue,
lastBullOB //
)
? selectedValue
: 0;
//
iSwingLowValue =
!filterPOIsUsingMa
? iSwingLowValue
: iSwingLowValue < iMa
? iSwingLowValue
: 0;
}
//
if (isSwingHigh)
{
//
double selectedValue = iBar.high;
//
iSwingHighValue =
!filterPOIsUsingZones
? selectedValue
: !hasLastBearOB
? 0
: IsAbove(
selectedValue,
lastBearOB //
)
? selectedValue
: 0;
//
iSwingHighValue =
!filterPOIsUsingMa
? iSwingHighValue
: iSwingHighValue > iMa
? iSwingHighValue
: 0;
}
//
swingLowBuffer[bar_index] = iSwingLowValue;
swingHighBuffer[bar_index] = iSwingHighValue;
}
//
//
//
//
DetectSignals(
bar_index,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
//
// Cleanup Resources ...
//
iBar.Clean();
pBar.Clean();
}
//
void ConfigureAlert()
{
//
mXWZAlert.SetPrefix(ShortName);
//
mXWZAlert.SetPushAlerts(mXWZPushAlerts);
mXWZAlert.SetMailAlerts(mXWZMailAlerts);
mXWZAlert.SetEnableAlerts(mXWZEnableAlerts);
mXWZAlert.SetTerminalAlerts(mXWZTerminalAlerts);
}
//
void DetectSignals(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Calculate Signals ...
//
XOHCL bar;
XOHCL pBar;
XOHCL ppBar;
bool isInited = bar.Init(
_Symbol,
_Period,
barIndex //
);
if (!isInited)
{
return;
}
//
isInited = bar.GetPreviousBar(pBar);
if (!isInited)
{
return;
}
//
isInited = pBar.GetPreviousBar(ppBar);
if (!isInited)
{
return;
}
//
int pIDX = pBar.Index();
int ppIDX = ppBar.Index();
//
// Reading Buffers ...
//
double ma = maBuffer[barIndex];
double maPrev = maBuffer[pIDX];
double maPPrev = maBuffer[ppIDX];
//
// Pin Bar ...
bool isBullisPinned = bullishPinBuffer[pIDX] > 0;
bool isBearisPinned = bearishPinBuffer[pIDX] > 0;
//
// Engulf Bar ...
bool isBullisEngulfed = bullishEngulfBuffer[pIDX] > 0;
bool isBearisEngulfed = bearishEngulfBuffer[pIDX] > 0;
//
// Rejection Bar ...
bool isBullishRejected = bullishRejectionBuffer[pIDX] > 0;
bool isBearishRejected = bearishRejectionBuffer[pIDX] > 0;
//
// Momentum Bar ...
bool isBullishMomentum = bullishMomentumBuffer[pIDX] > 0;
bool isBearishMomentum = bearishMomentumBuffer[pIDX] > 0;
//
// Checking Pullback ...
ENUM_X_DIRECTION pullbackDir;
bool hasPullback = mXWZBarAnalyser.HasPullBack(
pullbackDir,
bar //
);
bool hasBullishPullback =
hasPullback &&
IsBullish(pullbackDir);
bool hasBearishPullback =
hasPullback &&
IsBearish(pullbackDir);
//
// Order Block Parsing ...
// //
// bool isMACrossedOverBullishOB =
// //
// lastBullOB != NULL &&
// lastBullOB.IsValid() &&
// //
// IsInside(
// maPPrev,
// lastBullOB //
// ) &&
// //
// IsAbove(
// maPrev,
// lastBullOB //
// )
// //
// ;
// //
// bool isMACrossedUnderBearishOB =
// //
// lastBearOB != NULL &&
// lastBearOB.IsValid() &&
// //
// IsInside(
// maPPrev,
// lastBearOB //
// ) &&
// //
// IsBelow(
// maPrev,
// lastBearOB //
// )
// //
// ;
//
// Bullish ...
// --------------
// -[] a Bullish Wave Which Crossed Over MA ...
// -[] Trend is Bullish ...
// -[] PullBack to MA ...
// -[] Has a Bllish Rejection ...
bool hasBullishSignal =
//
pBar.IsBullish() &&
pBar.low < maPrev &&
pBar.GetDown() >= maPrev &&
//
bar.open >= ma &&
//
hasBearishPullback &&
//
false
//
;
//
// Bearish ...
// --------------
// -[] a Bearish Wave Which Crossed Under MA ...
// -[] Trend is Bearish ...
// -[] PullBack to MA ...
// -[] Has a Bearish Rejection ...
bool hasBearishSignal =
//
false
// pBar.IsBearish() &&
// pBar.high > maPrev &&
// pBar.GetUp() <= maPrev &&
// //
// bar.open <= ma &&
// //
// true
//
;
//
// Draw ...
//
//
long chartID = mXWZPOIDrawer.ChartIdentification();
int window = mXWZPOIDrawer.SubWindowIdentification();
// //
// if (isMACrossedOverBullishOB)
// {
// //
// string name =
// "Bullish_" +
// ToMD5(ToFormatString(pBar.time));
// //
// CChartObjectVLine *iLine;
// iLine = new CChartObjectVLine();
// bool isCreated = iLine.Create(
// chartID,
// name,
// window,
// pBar.time //
// );
// if (isCreated)
// {
// //
// iLine.Color(clrAqua);
// //
// mXWZDrawnObjects.Add(iLine);
// }
// }
// //
// if (isMACrossedUnderBearishOB)
// {
// //
// string name =
// "Bearish_" +
// ToMD5(ToFormatString(pBar.time));
// //
// CChartObjectVLine *iLine;
// iLine = new CChartObjectVLine();
// bool isCreated = iLine.Create(
// chartID,
// name,
// window,
// pBar.time //
// );
// if (isCreated)
// {
// //
// iLine.Color(clrMagenta);
// //
// mXWZDrawnObjects.Add(iLine);
// }
// }
//
bool hasSignal =
(hasBullishSignal ||
hasBearishSignal);
if (hasSignal)
{
//
long chartID = mXWZPOIDrawer.ChartIdentification();
int window = mXWZPOIDrawer.SubWindowIdentification();
string name =
(hasBullishSignal
? "Bullish_"
: "Bearish_") +
"Signal_" + ToMD5(ToFormatString(bar.time));
color signalColor =
hasBullishSignal
? clrYellow
: clrOrange;
//
CChartObjectVLine *iSignal;
iSignal = new CChartObjectVLine();
bool isCreated = iSignal.Create(
chartID,
name,
window,
bar.time //
);
if (isCreated)
{
//
iSignal.Color(signalColor);
//
mXWZDrawnObjects.Add(iSignal);
}
//
bool drawRR = false;
if (drawRR)
{
//
XRR iSigRR;
ENUM_X_POSITION_TYPES type =
hasBullishSignal
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
double sl = hasBullishSignal
? longSLBuffer[barIndex]
: shortSLBuffer[barIndex];
//
isCreated = iSigRR.Init(
_Symbol,
_Period,
sl,
bar.open,
type,
ShortName //
);
if (!isCreated)
{
return;
}
//
iSigRR.time = pBar.NextAt();
//
XCRRObject *iObj;
isCreated = mXWZPOIDrawer.CreateRR(
iSigRR,
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
//
iSigRR.Clean();
}
}
//
bar.Clean();
pBar.Clean();
}
//
// POIS Functions ...
//
void ConfigurePOIDrawer()
{
//
if (mXWZPOIDrawer == NULL)
{
return;
}
//
mXWZPOIDrawer.Prefix(ShortName);
mXWZPOIDrawer.ChartIdentification(ChartID());
mXWZPOIDrawer.SubWindowIdentification(0);
//
mXWZPOIDrawer.BullishFVGWidth(1);
mXWZPOIDrawer.BullishFVGStyle(STYLE_DOT);
mXWZPOIDrawer.BullishFVGColor(clrAqua);
//
mXWZPOIDrawer.BearishFVGWidth(1);
mXWZPOIDrawer.BearishFVGStyle(STYLE_DOT);
mXWZPOIDrawer.BearishFVGColor(clrMagenta);
//
mXWZPOIDrawer.SupportZoneWidth(1);
mXWZPOIDrawer.SupportZoneStyle(STYLE_DASHDOTDOT);
mXWZPOIDrawer.SupportZoneColor(clrLime);
//
mXWZPOIDrawer.ResistanceZoneWidth(1);
mXWZPOIDrawer.ResistanceZoneStyle(STYLE_DASHDOTDOT);
mXWZPOIDrawer.ResistanceZoneColor(clrRed);
//
mXWZPOIDrawer.BullishOrderBlockWidth(4);
mXWZPOIDrawer.BullishOrderBlockStyle(STYLE_DASH);
mXWZPOIDrawer.BullishOrderBlockColor(clrAqua);
//
mXWZPOIDrawer.BearishOrderBlockWidth(4);
mXWZPOIDrawer.BearishOrderBlockStyle(STYLE_DASH);
mXWZPOIDrawer.BearishOrderBlockColor(clrMagenta);
}
//
void CalculatedPOIs(
int bar_index, // Selected Bar Index
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
XOHCL iBar;
bool isInited = iBar.Init(
_Symbol,
_Period,
bar_index //
);
if (!isInited)
{
//
iBar.Clean();
return;
}
//
XOHCL pBar;
isInited = iBar.GetPreviousBar(pBar);
if (!isInited)
{
//
iBar.Clean();
pBar.Clean();
return;
}
//
// POI ...
DetectPOIs(iBar);
UpdatePOIs(iBar);
DrawPOIs();
//
iBar.Clean();
pBar.Clean();
}
//
bool CanDetectPOIs()
{
//
bool result = false;
//
result =
//
mXWZDetectOrderBlocks ||
mXWZDetectFairValueGaps ||
mXWZDetectSupportZones ||
mXWZDetectResistanceZones
//
;
//
return result;
}
//
void DetectPOIs(
XOHCL &bar //
)
{
//
if (!CanDetectPOIs())
{
return;
}
//
int idx = -1;
int range = 21;
//
// Detect Order Block ...
//
if (mXWZDetectOrderBlocks)
{
//
XOHCL obBar;
XCOrderBlock *ob;
ENUM_X_DIRECTION obDir;
bool hasOB = mXWZBarAnalyser.HasOrderBlock(
bar,
obBar,
obDir //
);
bool hasBullishOB =
hasOB &&
IsBullish(obDir);
bool hasBearishOB =
hasOB &&
IsBearish(obDir);
if (hasOB)
{
//
ob = new XCOrderBlock();
bool isInited = ob.Init(obBar, obDir);
if (isInited)
{
//
ENUM_X_DIRECTION iForDir = ob.GetDirection();
bool isBullish = IsBullish(iForDir);
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = ob.IsActivated(
iForDir,
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
if (!isActivated)
{
//
idx = FindIndex(
ob,
mXWZUnActivatedOBs //
);
if (!IsValidIndex(idx))
{
//
if (isBullish)
{
lastBullOB = ob;
}
else
{
lastBearOB = ob;
}
//
Add(
ob,
mXWZUnActivatedOBs //
);
}
}
else
{
//
idx = FindIndex(
ob,
mXWZActivatedOBs //
);
if (!IsValidIndex(idx))
{
//
ob.To(activationBar.time);
//
Add(
ob,
mXWZActivatedOBs //
);
}
}
//
activationBar.Clean();
}
}
//
obBar.Clean();
}
//
// Detect Fair Value Gap ...
//
if (mXWZDetectFairValueGaps)
{
//
XOHCL fvgStartBar;
XOHCL fvgEndBar;
XCFVG *fvg;
ENUM_X_DIRECTION fvgDir;
bool hasFVG = mXWZBarAnalyser.HasFairValueGap(
bar,
fvgStartBar,
fvgEndBar,
fvgDir //
);
bool hasBullishFVG =
hasFVG &&
IsBullish(fvgDir);
bool hasBearishFVG =
hasFVG &&
IsBearish(fvgDir);
if (hasFVG)
{
//
fvg = new XCFVG();
bool isInited = fvg.Init(
fvgStartBar,
fvgEndBar,
fvgDir //
);
if (isInited)
{
//
ENUM_X_DIRECTION iForDir = fvg.GetDirection();
bool isBullish = IsBullish(iForDir);
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = fvg.IsActivated(
iForDir,
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
if (!isActivated)
{
//
idx = FindIndex(
fvg,
mXWZUnActivatedFVGs //
);
if (!IsValidIndex(idx))
{
//
if (isBullish)
{
lastBullFVG = fvg;
}
else
{
lastBearFVG = fvg;
}
//
Add(
fvg,
mXWZUnActivatedFVGs //
);
}
}
else
{
//
idx = FindIndex(
fvg,
mXWZActivatedFVGs //
);
if (!IsValidIndex(idx))
{
//
fvg.To(activationBar.time);
//
Add(
fvg,
mXWZActivatedFVGs //
);
}
}
//
activationBar.Clean();
}
}
//
fvgEndBar.Clean();
fvgStartBar.Clean();
}
//
// Detect Support Zone ...
//
if (mXWZDetectSupportZones)
{
//
XOHCL supportBar;
XCSupportZone *supportZone;
bool hasSupport = mXWZBarAnalyser
.HasSupport(
bar,
supportBar,
range //
);
if (hasSupport)
{
//
supportZone = new XCSupportZone();
hasSupport = supportZone.Init(
supportBar,
range,
true // Use Range As Start ...
);
//
if (hasSupport)
{
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = supportZone.IsActivated(
X_DIRECTION_BULLISH,
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
if (!isActivated)
{
//
idx = FindIndex(
supportZone,
mXWZUnActivatedSupportZones //
);
hasSupport = !IsValidIndex(idx);
if (hasSupport)
{
//
lastSupport = supportZone;
//
Add(
supportZone,
mXWZUnActivatedSupportZones //
);
}
}
else
{
//
idx = FindIndex(
supportZone,
mXWZActivatedSupportZones //
);
hasSupport = !IsValidIndex(idx);
if (hasSupport)
{
//
supportZone.To(activationBar.time);
//
Add(
supportZone,
mXWZActivatedSupportZones //
);
}
}
//
activationBar.Clean();
}
}
//
supportBar.Clean();
}
//
// Detect Resistance Zone ...
//
if (mXWZDetectResistanceZones)
{
//
XOHCL resistaneBar;
XCResistanceZone *resistanceZone;
bool hasResistance = mXWZBarAnalyser
.HasResistance(
bar,
resistaneBar,
range //
);
if (hasResistance)
{
//
resistanceZone = new XCResistanceZone();
hasResistance = resistanceZone.Init(
resistaneBar,
range,
true // Use Range As Start ...
);
//
if (hasResistance)
{
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = resistanceZone.IsActivated(
X_DIRECTION_BULLISH,
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
if (!isActivated)
{
//
idx = FindIndex(
resistanceZone,
mXWZUnActivatedResistanceZones //
);
hasResistance = !IsValidIndex(idx);
if (hasResistance)
{
//
lastResistance = resistanceZone;
//
Add(
resistanceZone,
mXWZUnActivatedResistanceZones //
);
}
}
else
{
//
idx = FindIndex(
resistanceZone,
mXWZActivatedResistanceZones //
);
hasResistance = !IsValidIndex(idx);
if (hasResistance)
{
//
resistanceZone.To(activationBar.time);
//
Add(
resistanceZone,
mXWZActivatedResistanceZones //
);
}
}
//
activationBar.Clean();
}
}
//
resistaneBar.Clean();
}
//
}
//
void UpdatePOIs(
XOHCL &bar //
)
{
//
int count = -1;
bool has = false;
bool resetDraws = false;
//
if (!bar.IsValid())
{
return;
}
//
datetime to = bar.time;
//
// Order Blocks ...
//
count = ArraySize(mXWZUnActivatedOBs);
has = IsValidSize(count);
if (has)
{
//
XCOrderBlock *tmps[];
for (int i = 0; i < count; i++)
{
//
// Update To ...
mXWZUnActivatedOBs[i].To(to);
//
// Check Activation ...
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = mXWZUnActivatedOBs[i]
.IsActivated(
mXWZUnActivatedOBs[i].GetDirection(),
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
activationBar.Clean();
//
if (!isActivated)
{
//
Add(
mXWZUnActivatedOBs[i],
tmps //
);
}
else
{
//
Add(
mXWZUnActivatedOBs[i],
mXWZActivatedOBs //
);
}
}
//
Copy(
tmps,
mXWZUnActivatedOBs //
);
}
//
count = ArraySize(mXWZActivatedOBs);
has = IsValidSize(count);
if (has)
{
//
// Remove UnWorks / Breaked Zones ...
int removeIDX[];
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iZone = mXWZActivatedOBs[i];
//
XOHCL passedBar;
bool isBodyOut = false;
ENUM_X_DIRECTION iForDir = iZone.GetDirection();
//
// Check Works ...
bool isWorked = iZone.IsWorked(
iForDir,
passedBar,
isBodyOut,
true,
false,
false,
_Period //
);
if (!isWorked)
{
//
Add(
i,
removeIDX //
);
//
passedBar.Clean();
break;
}
//
passedBar.Clean();
}
//
if (HasChild(removeIDX))
{
//
resetDraws = true;
//
count = ArraySize(removeIDX);
for (int i = 0; i < count; i++)
{
//
ArrayRemove(
mXWZActivatedOBs,
removeIDX[i],
1 //
);
}
}
//
Clean(removeIDX);
}
//
// Fair Value Gaps ...
//
count = ArraySize(mXWZUnActivatedFVGs);
has = IsValidSize(count);
if (has)
{
//
XCFVG *tmps[];
for (int i = 0; i < count; i++)
{
//
// Update To ...
mXWZUnActivatedFVGs[i].To(to);
//
// Check Activation ...
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = mXWZUnActivatedFVGs[i]
.IsActivated(
mXWZUnActivatedFVGs[i].GetDirection(),
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
activationBar.Clean();
//
if (!isActivated)
{
//
Add(
mXWZUnActivatedFVGs[i],
tmps //
);
}
else
{
//
Add(
mXWZUnActivatedFVGs[i],
mXWZActivatedFVGs //
);
}
}
//
Copy(
tmps,
mXWZUnActivatedFVGs //
);
}
//
count = ArraySize(mXWZActivatedFVGs);
has = IsValidSize(count);
if (has)
{
//
// Remove UnWorks / Breaked Zones ...
int removeIDX[];
for (int i = 0; i < count; i++)
{
//
XCFVG *iZone = mXWZActivatedFVGs[i];
//
XOHCL passedBar;
bool isBodyOut = false;
ENUM_X_DIRECTION iForDir = iZone.GetDirection();
//
// Check Works ...
bool isWorked = iZone.IsWorked(
iForDir,
passedBar,
isBodyOut,
true,
false,
false,
_Period //
);
if (!isWorked)
{
//
Add(
i,
removeIDX //
);
//
passedBar.Clean();
break;
}
//
passedBar.Clean();
}
//
if (HasChild(removeIDX))
{
//
resetDraws = true;
//
count = ArraySize(removeIDX);
for (int i = 0; i < count; i++)
{
//
ArrayRemove(
mXWZActivatedFVGs,
removeIDX[i],
1 //
);
}
}
//
Clean(removeIDX);
}
//
// Support Zones ...
//
count = ArraySize(mXWZUnActivatedSupportZones);
has = IsValidSize(count);
if (has)
{
//
XCSupportZone *tmps[];
for (int i = 0; i < count; i++)
{
//
// Update To ...
mXWZUnActivatedSupportZones[i].To(to);
//
// Check Activation ...
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = mXWZUnActivatedSupportZones[i]
.IsActivated(
X_DIRECTION_BULLISH,
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
if (!isActivated)
{
//
Add(
mXWZUnActivatedSupportZones[i],
tmps //
);
}
else
{
//
mXWZUnActivatedSupportZones[i].To(activationBar.time);
//
Add(
mXWZUnActivatedSupportZones[i],
mXWZActivatedSupportZones //
);
}
//
activationBar.Clean();
}
//
Copy(
tmps,
mXWZUnActivatedSupportZones //
);
}
//
count = ArraySize(mXWZActivatedSupportZones);
has = IsValidSize(count);
if (has)
{
//
// Remove UnWorks / Breaked Zones ...
int removeIDX[];
ENUM_X_DIRECTION iForDir = X_DIRECTION_BULLISH;
for (int i = 0; i < count; i++)
{
//
XCSupportZone *iZone = mXWZActivatedSupportZones[i];
//
XOHCL passedBar;
bool isBodyOut = false;
//
// Check Works ...
bool isWorked = iZone.IsWorked(
iForDir,
passedBar,
isBodyOut,
true,
false,
false,
_Period //
);
if (!isWorked)
{
//
Add(
i,
removeIDX //
);
//
passedBar.Clean();
break;
}
//
passedBar.Clean();
}
//
if (HasChild(removeIDX))
{
//
resetDraws = true;
//
count = ArraySize(removeIDX);
for (int i = 0; i < count; i++)
{
//
ArrayRemove(
mXWZActivatedSupportZones,
removeIDX[i],
1 //
);
}
}
//
Clean(removeIDX);
}
//
// Resistance Zones ...
//
count = ArraySize(mXWZUnActivatedResistanceZones);
has = IsValidSize(count);
if (has)
{
//
XCResistanceZone *tmps[];
for (int i = 0; i < count; i++)
{
//
// Update To ...
mXWZUnActivatedResistanceZones[i].To(to);
//
// Check Activation ...
//
// Check OB Not Activated ...
XOHCL activationBar;
bool isActivationBarBodyIn = false;
bool isActivated = mXWZUnActivatedResistanceZones[i]
.IsActivated(
X_DIRECTION_BULLISH,
activationBar,
isActivationBarBodyIn,
false,
_Period //
);
//
if (!isActivated)
{
//
Add(
mXWZUnActivatedResistanceZones[i],
tmps //
);
}
else
{
//
mXWZUnActivatedResistanceZones[i].To(activationBar.time);
//
Add(
mXWZUnActivatedResistanceZones[i],
mXWZActivatedResistanceZones //
);
}
//
activationBar.Clean();
}
//
Copy(
tmps,
mXWZUnActivatedResistanceZones //
);
}
//
count = ArraySize(mXWZActivatedResistanceZones);
has = IsValidSize(count);
if (has)
{
//
// Remove UnWorks / Breaked Zones ...
int removeIDX[];
ENUM_X_DIRECTION iForDir = X_DIRECTION_BEARISH;
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *iZone = mXWZActivatedResistanceZones[i];
//
XOHCL passedBar;
bool isBodyOut = false;
//
// Check Breake ...
bool isBreaked = iZone.IsBreaked(
iForDir,
passedBar,
isBodyOut,
true,
false,
_Period //
);
if (isBreaked)
{
//
Add(
i,
removeIDX //
);
//
passedBar.Clean();
break;
}
//
// Check Works ...
bool isWorked = iZone.IsWorked(
iForDir,
passedBar,
isBodyOut,
true,
false,
false,
_Period //
);
if (!isWorked)
{
//
Add(
i,
removeIDX //
);
//
passedBar.Clean();
break;
}
//
passedBar.Clean();
}
//
if (HasChild(removeIDX))
{
//
resetDraws = true;
//
count = ArraySize(removeIDX);
for (int i = 0; i < count; i++)
{
//
ArrayRemove(
mXWZActivatedResistanceZones,
removeIDX[i],
1 //
);
}
}
//
Clean(removeIDX);
}
//
//
//
//
// Clean Draws if has to ...
if (resetDraws)
{
mXWZDrawnObjects.Clear();
}
//
}
//
void DrawPOIs()
{
//
int count = 0;
bool has = false;
bool isCreated = false;
//
if (!showPOIs)
{
return;
}
//
// Order Blocks ...
if (showOrderBlocks)
{
//
bool showBullishOrderBlocks = true;
bool showBearishOrderBlocks = true;
//
// UnActivated ...
count = ArraySize(mXWZUnActivatedOBs);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
bool isBullish = mXWZUnActivatedOBs[i].IsBullish();
//
if ((isBullish &&
showBullishOrderBlocks) ||
(!isBullish &&
showBearishOrderBlocks))
{
//
XCBaseObject *iObj;
isCreated = mXWZPOIDrawer
.CreateOrderBlock(
mXWZUnActivatedOBs[i],
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
}
}
//
// Activated ...
count = ArraySize(mXWZActivatedOBs);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCOrderBlock *iOB = mXWZActivatedOBs[i];
//
bool isBullish = iOB.IsBullish();
//
if (showActivatedPOIs &&
((isBullish &&
showBullishOrderBlocks) ||
(!isBullish &&
showBearishOrderBlocks)))
{
//
XCBaseObject *iObj;
isCreated = mXWZPOIDrawer
.CreateOrderBlock(
iOB,
iObj //
);
if (isCreated)
{
//
// if (isBullish)
// {
// ((XCBullishOrderBlockObject *)iObj).ZoneFill(true);
// }
// else
// {
// ((XCBearishOrderBlockObject *)iObj).ZoneFill(true);
// }
//
mXWZDrawnObjects.Add(iObj);
}
}
}
}
}
//
// Fair Value Gaps ...
if (showFairValueGaps)
{
//
bool showBullishFairValueGaps = true;
bool showBearishFairValueGaps = true;
//
// UnActivated ...
count = ArraySize(mXWZUnActivatedFVGs);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
bool isBullish = mXWZUnActivatedFVGs[i].IsBullish();
//
if ((isBullish &&
showBullishFairValueGaps) ||
(!isBullish &&
showBearishFairValueGaps))
{
//
XCBaseObject *iObj;
isCreated = mXWZPOIDrawer
.CreateFairValueGap(
mXWZUnActivatedFVGs[i],
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
}
}
//
// Activated ...
count = ArraySize(mXWZActivatedFVGs);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCFVG *iFVG = mXWZActivatedFVGs[i];
//
bool isBullish = iFVG.IsBullish();
//
if (showActivatedPOIs &&
((isBullish &&
showBullishFairValueGaps) ||
(!isBullish &&
showBearishFairValueGaps)))
{
XCBaseObject *iObj;
isCreated = mXWZPOIDrawer
.CreateFairValueGap(
iFVG,
iObj //
);
if (isCreated)
{
//
// if (isBullish)
// {
// ((XCBullishOrderBlockObject *)iObj).ZoneFill(true);
// }
// else
// {
// ((XCBearishOrderBlockObject *)iObj).ZoneFill(true);
// }
//
mXWZDrawnObjects.Add(iObj);
}
}
}
}
}
//
// Support Zones ...
if (showSupportZones)
{
//
// UnActivated ...
count = ArraySize(mXWZUnActivatedSupportZones);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCSupportZoneObject *iObj;
isCreated = mXWZPOIDrawer
.CreateSupportZone(
mXWZUnActivatedSupportZones[i],
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
}
//
// Activated ...
if (showActivatedPOIs)
{
//
count = ArraySize(mXWZActivatedSupportZones);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCSupportZoneObject *iObj;
isCreated = mXWZPOIDrawer
.CreateSupportZone(
mXWZActivatedSupportZones[i],
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
}
}
}
//
// Resistance Zones ...
if (showResistanceZones)
{
//
// UnActivated ...
count = ArraySize(mXWZUnActivatedResistanceZones);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCResistanceZoneObject *iObj;
isCreated = mXWZPOIDrawer
.CreateResistanceZone(
mXWZUnActivatedResistanceZones[i],
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
}
//
// Activated ...
if (showActivatedPOIs)
{
//
count = ArraySize(mXWZActivatedResistanceZones);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
XCResistanceZoneObject *iObj;
isCreated = mXWZPOIDrawer
.CreateResistanceZone(
mXWZActivatedResistanceZones[i],
iObj //
);
if (isCreated)
{
mXWZDrawnObjects.Add(iObj);
}
}
}
}
}
//
}
//