Files
MQL5Data/Documents/BKP/1/x-saherelm.x121.xpoi.mq5
T
2025-02-03 14:33:13 +03:30

2063 lines
59 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121 XPOI
// Description: XPOI ...
//
//
// 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 XPOI Indicator"
#property strict
//
// Definitions ...
//
#define ShortName "X121 XPOI"
//
// Includes Common Library ...
#include "../Classes/x-saherelm.x-poi.class.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
#include "../Libraries/x-saherelm.draw.lib.mq5"
//
// Inputs ...
//
// Market ...
input group "Market";
input int maxNumberOfPOIs = 50; // Max Number Of Holding POI(s)
input int maxNumberOfRequiredPOIs = 50; // Max Number of Required POI(s)
input int swingRange = 7; // Swing Detection Range
input int orderBlocksSameBars = 3; // Order Block Same Bars
input int ticksRangeZoneLevel = 10; // Number of Ticks Zone's Levels
input int ticksRangeZoneRange = 144; // Lenght of Tick Zones Calculation
input int fairValueGapsSameBars = 3; // Fair Value Gaps Same Bars
input int momentumBarExtendRange = 2; // Momentum Bars Extends Range
input int supplyAndDemandRange = 144; // Supply and Demand Range
input int rejectionBarExtendRange = 2; // Rejection Bars Extends Range
input int supportAndResistanceRange = 7; // Support and Resistance Range
input double momentumBarBodyPercent = 70; // Momentum Bars Body Range
input double rejectionBarShadowPercent = 70; // Rejection Bars Body Range
//
// Presentation ...
input group "Presentation";
//
input int startCalculationForLastBars = 2000; // Calculate Last n Bars
//
input int swingLowsArrowCode = 159; // Swing Lows Arrow Code
input int swingHighsArrowCode = 159; // Swing Highs Arrow Code
input int bullishMomentumBarsArrowCode = 233; // Bullish Momentum Bars Arrow Code
input int bearishMomentumBarsArrowCode = 234; // Bearish Momentum Bars Arrow Code
input int bullishRejectionBarsArrowCode = 241; // Bullish Rejection Bars Arrow Code
input int bearishRejectionBarsArrowCode = 242; // Bearish Rejection Bars Arrow Code
//
input color bullishColor = clrAqua; // Bullish Color
input color bearishColor = clrMagenta; // Bearish Color
//
input ENUM_LINE_STYLE orderBlockStyle = STYLE_SOLID; // Order Block Style
input ENUM_LINE_STYLE fairValueGapStyle = STYLE_DASH; // Fair Value Gap Style
input ENUM_LINE_STYLE supResStyle = STYLE_DASHDOT; // Support and Resistance Style
input ENUM_LINE_STYLE supDemStyle = STYLE_DASHDOTDOT; // Supply and Demand Style
//
input bool drawSwingLows = false; // Draw Swing Lows
input bool drawSwingHighs = false; // Draw Swing Highs
input bool drawSupplyZones = false; // Draw Supply Zones
input bool drawDemandZones = false; // Draw Demand Zones
input bool drawSupportZones = false; // Draw Support Zones
input bool drawResistanceZones = false; // Draw Resistance Zones
input bool drawBullishOrderBlocks = true; // Draw Bullish Order Blocks
input bool drawBearishOrderBlocks = true; // Draw Bearish Order Blocks
input bool drawBullishFairValueGaps = true; // Draw Bullish Fair Vlue Gaps
input bool drawBearishFairValueGaps = true; // Draw Bearish Fair Vlue Gaps
input bool drawBullishMomentumBars = true; // Draw Bullish Momentum Bars
input bool drawBearishMomentumBars = true; // Draw Bearish Momentum Bars
input bool drawBullishRejectionBars = true; // Draw Bullish Rejection Bars
input bool drawBearishRejectionBars = true; // Draw Bearish Rejection Bars
//
#property indicator_chart_window
//
#property indicator_buffers 6
#property indicator_plots 6
//
// Plot Buffers ...
//
// XSWING ...
//
// HIGH ...
#define swingHighsBufferIndex 0
double swingHighsBuffer[];
//
#property indicator_label1 "X121 XPOI SWH"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrMagenta
#property indicator_width1 3
//
// LOW ...
#define swingLowsBufferIndex 1
double swingLowsBuffer[];
//
#property indicator_label2 "X121 XPOI SWL"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrAqua
#property indicator_width2 3
//
// MOMENTUM ...
//
// BULLISH ...
#define bullishMomentumBarsBufferIndex 2
double bullishMomentumBarsBuffer[];
//
#property indicator_label3 "X121 XPOI BULLMNTM"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrAqua
#property indicator_width3 3
//
// BEARISH ...
#define bearishMomentumBarsBufferIndex 3
double bearishMomentumBarsBuffer[];
//
#property indicator_label4 "X121 XPOI BEARNTM"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrMagenta
#property indicator_width4 3
//
// REJECTION ...
//
// BULLISH ...
#define bullishRejectionBarsBufferIndex 4
double bullishRejectionBarsBuffer[];
//
#property indicator_label5 "X121 XPOI BULLMRJCT"
#property indicator_type5 DRAW_ARROW
#property indicator_color5 clrAqua
#property indicator_width5 3
//
// BEARISH ...
#define bearishRejectionBarsBufferIndex 5
double bearishRejectionBarsBuffer[];
//
#property indicator_label6 "X121 XPOI BEARRJCT"
#property indicator_type6 DRAW_ARROW
#property indicator_color6 clrMagenta
#property indicator_width6 3
//
// Data Buffers ...
//
// Variables, Properties and etc ...
//
// this counts Available Bars ...
int limit;
//
int maxLength;
//
bool isPOIRequested = false;
string iPrefix = ShortName + "_" + ToString(_Period);
//
XCPOIDrawer *mPOIDrawer;
XCPOIDetector *mPOIDetector;
//
// Supported POIS ...
//
// Swings ...
XCSwing *mSwingHighs[];
XCSwing *mSwingLows[];
//
// Rejections ...
XCRejectionBar *mBullishRejectionBars[];
XCRejectionBar *mBearishRejectionBars[];
//
// Momentums ...
XCMomentumBar *mBullishMomentumBars[];
XCMomentumBar *mBearishMomentumBars[];
//
// Order Block ...
XCOrderBlock *mBullishOrderBlocks[];
XCOrderBlock *mBearishOrderBlocks[];
//
// Fair Value Gap ...
XCFVG *mBullishFairValueGaps[];
XCFVG *mBearishFairValueGaps[];
//
// Support and Resistances ...
XCSupportZone *mSupportZones[];
XCResistanceZone *mResistanceZones[];
//
// Supply and Demand ...
XCSupplyZone *mSupplyZones[];
XCDemandZone *mDemandZones[];
//
XCBaseObject *mPOIObjects[];
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize POI Detector ...
InitialiDetector();
//
// 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);
//
// 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
//
Clean(mSupplyZones);
Clean(mDemandZones);
Clean(mSupportZones);
Clean(mResistanceZones);
Clean(mBullishOrderBlocks);
Clean(mBearishOrderBlocks);
Clean(mBullishFairValueGaps);
Clean(mBearishFairValueGaps);
//
Clean(mSwingLows);
Clean(mSwingHighs);
Clean(mBullishMomentumBars);
Clean(mBearishMomentumBars);
Clean(mBullishRejectionBars);
Clean(mBearishRejectionBars);
//
CleanChart();
//
mPOIDetector.Destroy();
//
ZeroMemory(mPOIDrawer);
ZeroMemory(mPOIDetector);
}
/**
* 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);
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// 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 =
//
true
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(result, result);
//
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 ...
//
// SWING ...
//
// LOW ...
ENUM_DRAW_TYPE swingLowsDrawType = drawSwingLows ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(swingLowsBuffer, true);
SetIndexBuffer(swingLowsBufferIndex, swingLowsBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(swingLowsBufferIndex, PLOT_SHOW_DATA, drawSwingLows);
PlotIndexSetInteger(swingLowsBufferIndex, PLOT_DRAW_TYPE, swingLowsDrawType);
//
PlotIndexSetDouble(swingLowsBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(swingLowsBufferIndex, PLOT_ARROW, swingLowsArrowCode);
//
// LOW ...
ENUM_DRAW_TYPE swingHighsDrawType = drawSwingLows ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(swingHighsBuffer, true);
SetIndexBuffer(swingHighsBufferIndex, swingHighsBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(swingHighsBufferIndex, PLOT_SHOW_DATA, drawSwingLows);
PlotIndexSetInteger(swingHighsBufferIndex, PLOT_DRAW_TYPE, swingHighsDrawType);
//
PlotIndexSetDouble(swingHighsBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(swingHighsBufferIndex, PLOT_ARROW, swingHighsArrowCode);
//
// REJECTION ...
//
// BULLISH ...
ENUM_DRAW_TYPE bullishRejectionBarsDrawType = drawSwingLows ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bullishRejectionBarsBuffer, true);
SetIndexBuffer(bullishRejectionBarsBufferIndex, bullishRejectionBarsBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bullishRejectionBarsBufferIndex, PLOT_SHOW_DATA, drawSwingLows);
PlotIndexSetInteger(bullishRejectionBarsBufferIndex, PLOT_DRAW_TYPE, bullishRejectionBarsDrawType);
//
PlotIndexSetDouble(bullishRejectionBarsBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bullishRejectionBarsBufferIndex, PLOT_ARROW, bullishRejectionBarsArrowCode);
//
// BEARISH ...
ENUM_DRAW_TYPE bearishRejectionBarsDrawType = drawSwingLows ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bearishRejectionBarsBuffer, true);
SetIndexBuffer(bearishRejectionBarsBufferIndex, bearishRejectionBarsBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bearishRejectionBarsBufferIndex, PLOT_SHOW_DATA, drawSwingLows);
PlotIndexSetInteger(bearishRejectionBarsBufferIndex, PLOT_DRAW_TYPE, bearishRejectionBarsDrawType);
//
PlotIndexSetDouble(bearishRejectionBarsBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bearishRejectionBarsBufferIndex, PLOT_ARROW, bearishRejectionBarsArrowCode);
//
// MOMENTUM ...
//
// BULLISH ...
ENUM_DRAW_TYPE bullishMomentumBarsDrawType = drawSwingLows ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bullishMomentumBarsBuffer, true);
SetIndexBuffer(bullishMomentumBarsBufferIndex, bullishMomentumBarsBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bullishMomentumBarsBufferIndex, PLOT_SHOW_DATA, drawSwingLows);
PlotIndexSetInteger(bullishMomentumBarsBufferIndex, PLOT_DRAW_TYPE, bullishMomentumBarsDrawType);
//
PlotIndexSetDouble(bullishMomentumBarsBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bullishMomentumBarsBufferIndex, PLOT_ARROW, bullishMomentumBarsArrowCode);
//
// BEARISH ...
ENUM_DRAW_TYPE bearishMomentumBarsDrawType = drawSwingLows ? DRAW_ARROW : DRAW_NONE;
//
ArraySetAsSeries(bearishMomentumBarsBuffer, true);
SetIndexBuffer(bearishMomentumBarsBufferIndex, bearishMomentumBarsBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(bearishMomentumBarsBufferIndex, PLOT_SHOW_DATA, drawSwingLows);
PlotIndexSetInteger(bearishMomentumBarsBufferIndex, PLOT_DRAW_TYPE, bearishMomentumBarsDrawType);
//
PlotIndexSetDouble(bearishMomentumBarsBufferIndex, PLOT_EMPTY_VALUE, 0);
PlotIndexSetInteger(bearishMomentumBarsBufferIndex, PLOT_ARROW, bearishMomentumBarsArrowCode);
//
// Data Buffers ...
}
/**
* Initialize POI Detector ...
*/
void InitialiDetector()
{
//
ArraySetAsSeries(mSwingLows, true);
ArraySetAsSeries(mSwingHighs, true);
ArraySetAsSeries(mBullishMomentumBars, true);
ArraySetAsSeries(mBearishMomentumBars, true);
ArraySetAsSeries(mBullishRejectionBars, true);
ArraySetAsSeries(mBearishRejectionBars, true);
//
ArraySetAsSeries(mSupplyZones, true);
ArraySetAsSeries(mDemandZones, true);
ArraySetAsSeries(mSupportZones, true);
ArraySetAsSeries(mResistanceZones, true);
ArraySetAsSeries(mBullishOrderBlocks, true);
ArraySetAsSeries(mBearishOrderBlocks, true);
ArraySetAsSeries(mBullishFairValueGaps, true);
ArraySetAsSeries(mBearishFairValueGaps, true);
//
mPOIDetector = new XCPOIDetector(
_Symbol,
_Period //
);
//
// Configure POI Detector ...
mPOIDetector.SwingRange(swingRange);
mPOIDetector.MaxNumberOfPOIs(maxNumberOfPOIs);
mPOIDetector.OrderBlocksSameBars(orderBlocksSameBars);
mPOIDetector.TicksRangeZoneLevel(ticksRangeZoneLevel);
mPOIDetector.TicksRangeZoneRange(ticksRangeZoneRange);
mPOIDetector.SupplyAndDemandRange(supplyAndDemandRange);
mPOIDetector.FairValueGapsSameBars(fairValueGapsSameBars);
mPOIDetector.MomentumBarExtendRange(momentumBarExtendRange);
mPOIDetector.MomentumBarBodyPercent(momentumBarBodyPercent);
mPOIDetector.MaxNumberOfRequiredPOIs(maxNumberOfRequiredPOIs);
mPOIDetector.RejectionBarExtendRange(rejectionBarExtendRange);
mPOIDetector.RejectionBarShadowPercent(rejectionBarShadowPercent);
mPOIDetector.SupportAndResistanceRange(supportAndResistanceRange);
//
mPOIDrawer = new XCPOIDrawer();
//
// Configure Drawer ...
mPOIDrawer.Prefix(iPrefix);
//
mPOIDrawer.BarBullishColor(bullishColor);
mPOIDrawer.BarBearishColor(bearishColor);
//
mPOIDrawer.DemandZoneColor(bullishColor);
mPOIDrawer.BullishFVGColor(bullishColor);
mPOIDrawer.SupportZoneColor(bullishColor);
mPOIDrawer.BullishOrderBlockColor(bullishColor);
//
mPOIDrawer.SupplyZoneColor(bearishColor);
mPOIDrawer.BearishFVGColor(bearishColor);
mPOIDrawer.ResistanceZoneColor(bearishColor);
mPOIDrawer.BearishOrderBlockColor(bearishColor);
//
mPOIDrawer.SupplyZoneStyle(supDemStyle);
mPOIDrawer.DemandZoneStyle(supDemStyle);
mPOIDrawer.SupportZoneStyle(supResStyle);
mPOIDrawer.ResistanceZoneStyle(supResStyle);
mPOIDrawer.BullishFVGStyle(fairValueGapStyle);
mPOIDrawer.BearishFVGStyle(fairValueGapStyle);
mPOIDrawer.BullishOrderBlockStyle(orderBlockStyle);
mPOIDrawer.BearishOrderBlockStyle(orderBlockStyle);
//
}
/**
* 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 =
barsLimit == 0 ||
bar_index <= barsLimit;
if (canCalculate)
{
//
if (bar_index == 0)
{
//
XPOIState state;
ENUM_XPOI_EVENTS events[];
int numberOfEvents = mPOIDetector.Update(events);
bool hasEvents = IsValidSize(numberOfEvents);
if (hasEvents)
{
//
mPOIDetector.GetState(state);
bool isStateValid = state.IsValid() &&
state.HasChild();
if (isStateValid)
{
//
// Order Blocks ...
//
// Bullish ...
bool hasBullOB = Contains(
X_BULLISH_ORDERBLOCK_DETECTED,
events //
);
if (hasBullOB)
{
//
int count = state.CountBullishOrderBlocks();
if (IsValidSize(count))
{
//
Add(
state.bullishOrderBlocks[count - 1],
mBullishOrderBlocks //
);
}
}
//
// Bearish ...
bool hasBearOB = Contains(
X_BEARISH_ORDERBLOCK_DETECTED,
events //
);
if (hasBearOB)
{
//
int count = state.CountBearishOrderBlocks();
if (IsValidSize(count))
{
//
Add(
state.bearishOrderBlocks[count - 1],
mBearishOrderBlocks //
);
}
}
//
// Fair Value Gaps ...
//
// Bullish ...
bool hasBullFVG = Contains(
X_BULLISH_FVG_DETECTED,
events //
);
if (hasBullFVG)
{
//
int count = state.CountBullishFairValueGaps();
if (IsValidSize(count))
{
//
Add(
state.bullishFairValueGaps[count - 1],
mBullishFairValueGaps //
);
}
}
//
// Bearish ...
bool hasBearFVG = Contains(
X_BEARISH_FVG_DETECTED,
events //
);
if (hasBearFVG)
{
//
int count = state.CountBearishFairValueGaps();
if (IsValidSize(count))
{
//
Add(
state.bearishFairValueGaps[count - 1],
mBearishFairValueGaps //
);
}
}
//
// Support and Resistance ...
//
// Support ...
bool hasSupportZone = Contains(
X_SUPPORT_ZONE_DETECTED,
events //
);
if (hasSupportZone)
{
//
int count = state.CountSupportZones();
if (IsValidSize(count))
{
//
Add(
state.supportZones[count - 1],
mSupportZones //
);
}
}
//
// Resistance ...
bool hasResistanceZone = Contains(
X_RESISTANCE_ZONE_DETECTED,
events //
);
if (hasResistanceZone)
{
//
int count = state.CountResistanceZones();
if (IsValidSize(count))
{
//
Add(
state.resistanceZones[count - 1],
mResistanceZones //
);
}
}
//
// Supply and Demand ...
//
// Supply ...
bool hasSupplyZone = Contains(
X_SUPPLY_ZONE_DETECTED,
events //
);
if (hasSupplyZone)
{
//
int count = state.CountSupplyZones();
if (IsValidSize(count))
{
//
Add(
state.supplyZones[count - 1],
mSupplyZones //
);
}
}
//
// Demand ...
bool hasDemandZone = Contains(
X_DEMAND_ZONE_DETECTED,
events //
);
if (hasDemandZone)
{
//
int count = state.CountDemandZones();
if (IsValidSize(count))
{
//
Add(
state.demandZones[count - 1],
mDemandZones //
);
}
}
//
//
//
//
// Swings ...
//
// Low ...
bool hasSwingLow = Contains(
X_SWING_LOW_DETECTED,
events //
);
if (hasSwingLow)
{
//
int count = state.CountSwingLows();
if (IsValidSize(count))
{
//
Add(
state.swingLows[count - 1],
mSwingLows //
);
}
}
//
// High ...
bool hasSwingHigh = Contains(
X_SWING_HIGH_DETECTED,
events //
);
if (hasSwingHigh)
{
//
int count = state.CountSwingHighs();
if (IsValidSize(count))
{
//
Add(
state.swingHighs[count - 1],
mSwingHighs //
);
}
}
//
// Momentum ...
//
// Bullish ...
bool hasBullishMomentumBar = Contains(
X_BULLISH_MOMENTUM_BAR_DETECTED,
events //
);
if (hasBullishMomentumBar)
{
//
int count = state.CountBullishMomentumBars();
if (IsValidSize(count))
{
//
Add(
state.bullishMomentumBars[count - 1],
mBullishMomentumBars //
);
}
}
//
// Bearish ...
bool hasBearishMomentumBar = Contains(
X_BEARISH_MOMENTUM_BAR_DETECTED,
events //
);
if (hasBearishMomentumBar)
{
//
int count = state.CountBearishMomentumBars();
if (IsValidSize(count))
{
//
Add(
state.bearishMomentumBars[count - 1],
mBearishMomentumBars //
);
}
}
//
// Rejection ...
//
// Bullish ...
bool hasBullishRejectionBar = Contains(
X_BULLISH_REJECTION_BAR_DETECTED,
events //
);
if (hasBullishRejectionBar)
{
//
int count = state.CountBullishRejectionBars();
if (IsValidSize(count))
{
//
Add(
state.bullishRejectionBars[count - 1],
mBullishRejectionBars //
);
}
}
//
// Bearish ...
bool hasBearishRejectionBar = Contains(
X_BEARISH_REJECTION_BAR_DETECTED,
events //
);
if (hasBearishRejectionBar)
{
//
int count = state.CountBearishRejectionBars();
if (IsValidSize(count))
{
//
Add(
state.bearishRejectionBars[count - 1],
mBearishRejectionBars //
);
}
}
//
}
}
//
if (bar_index == 0 && !isPOIRequested)
{
//
mPOIDetector.Init();
isPOIRequested = true;
}
//
if (isPOIRequested &&
bar_index == 0 &&
!mPOIDetector.IsLocked())
{
//
mPOIDetector.GetState(state);
bool isStateValid = state.IsValid() &&
state.HasChild();
if (isStateValid)
{
//
// Order Blocks ...
//
// Bullish ...
int bullishOBsCount = state.CountBullishOrderBlocks();
bool hasBullishOBs = IsValidSize(bullishOBsCount);
if (hasBullishOBs)
{
//
for (int i = 0; i < bullishOBsCount; i++)
{
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = state.bullishOrderBlocks[i].IsActivated(
activatedBar,
activatedDir //
);
if (!isActivated)
{
//
Add(
state.bullishOrderBlocks[i],
mBullishOrderBlocks //
);
}
}
}
//
// Bearish ...
int bearishOBsCount = state.CountBearishOrderBlocks();
bool hasBearishOBs = IsValidSize(bearishOBsCount);
if (hasBearishOBs)
{
//
for (int i = 0; i < bearishOBsCount; i++)
{
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = state.bearishOrderBlocks[i].IsActivated(
activatedBar,
activatedDir //
);
if (!isActivated)
{
//
Add(
state.bearishOrderBlocks[i],
mBearishOrderBlocks //
);
}
}
}
//
// Fair Value Gaps ...
//
// Bullish ...
int bullishFVGsCount = state.CountBullishFairValueGaps();
bool hasBullishFVGs = IsValidSize(bullishFVGsCount);
if (hasBullishFVGs)
{
//
for (int i = 0; i < bullishFVGsCount; i++)
{
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = state.bullishFairValueGaps[i].IsActivated(
activatedBar,
activatedDir //
);
if (!isActivated)
{
//
Add(
state.bullishFairValueGaps[i],
mBullishFairValueGaps //
);
}
}
}
//
// Bearish ...
int bearishFVGsCount = state.CountBearishFairValueGaps();
bool hasBearishFVGs = IsValidSize(bearishFVGsCount);
if (hasBearishFVGs)
{
//
for (int i = 0; i < bearishFVGsCount; i++)
{
//
XOHCL activatedBar;
ENUM_X_DIRECTION activatedDir;
bool isActivated = state.bearishFairValueGaps[i].IsActivated(
activatedBar,
activatedDir //
);
if (!isActivated)
{
//
Add(
state.bearishFairValueGaps[i],
mBearishFairValueGaps //
);
}
}
}
//
// Support and Resistance ...
//
// Support ...
int supportZonesCount = state.CountSupportZones();
bool hasSupportZones = IsValidSize(supportZonesCount);
if (hasSupportZones)
{
//
for (int i = 0; i < supportZonesCount; i++)
{
//
Add(
state.supportZones[i],
mSupportZones //
);
}
}
//
// Resistance ...
int resistanceZonesCount = state.CountResistanceZones();
bool hasResistanceZones = IsValidSize(resistanceZonesCount);
if (hasResistanceZones)
{
//
for (int i = 0; i < resistanceZonesCount; i++)
{
//
Add(
state.resistanceZones[i],
mResistanceZones //
);
}
}
//
// Supply and Demand ...
//
// Supply ...
int supplyZonesCount = state.CountSupplyZones();
bool hasSupplyZones = IsValidSize(supplyZonesCount);
if (hasSupplyZones)
{
//
for (int i = 0; i < supplyZonesCount; i++)
{
//
Add(
state.supplyZones[i],
mSupplyZones //
);
}
}
//
// Demand ...
int demandZonesCount = state.CountDemandZones();
bool hasDemandZones = IsValidSize(demandZonesCount);
if (hasDemandZones)
{
//
for (int i = 0; i < demandZonesCount; i++)
{
//
Add(
state.demandZones[i],
mDemandZones //
);
}
}
//
//
//
//
// Swings ...
//
// Low ...
int swingLowsCount = state.CountSwingLows();
bool hasSwingLows = IsValidSize(swingLowsCount);
if (hasSwingLows)
{
//
for (int i = 0; i < swingLowsCount; i++)
{
//
Add(
state.swingLows[i],
mSwingLows //
);
}
}
//
// Highs...
int swingHighsCount = state.CountSwingHighs();
bool hasSwingHighs = IsValidSize(swingHighsCount);
if (hasSwingHighs)
{
//
for (int i = 0; i < swingHighsCount; i++)
{
//
Add(
state.swingHighs[i],
mSwingHighs //
);
}
}
//
// Momentum Bars ...
//
// Bullish ...
int bullishMomentumBarsCount = state.CountBullishMomentumBars();
bool hasBullishMomentumBars = IsValidSize(bullishMomentumBarsCount);
if (hasBullishMomentumBars)
{
//
for (int i = 0; i < bullishMomentumBarsCount; i++)
{
//
Add(
state.bullishMomentumBars[i],
mBullishMomentumBars //
);
}
}
//
// Bearish ...
int bearishMomentumBarsCount = state.CountBearishMomentumBars();
bool hasBearishMomentumBars = IsValidSize(bearishMomentumBarsCount);
if (hasBearishMomentumBars)
{
//
for (int i = 0; i < bearishMomentumBarsCount; i++)
{
//
Add(
state.bearishMomentumBars[i],
mBearishMomentumBars //
);
}
}
//
// Rejection Bars ...
//
// Bullish ...
int bullishRejectionBarsCount = state.CountBullishRejectionBars();
bool hasBullishRejectionBars = IsValidSize(bullishRejectionBarsCount);
if (hasBullishRejectionBars)
{
//
for (int i = 0; i < bullishRejectionBarsCount; i++)
{
//
Add(
state.bullishRejectionBars[i],
mBullishRejectionBars //
);
}
}
//
// Bearish ...
int bearishRejectionBarsCount = state.CountBearishRejectionBars();
bool hasBearishRejectionBars = IsValidSize(bearishRejectionBarsCount);
if (hasBearishRejectionBars)
{
//
for (int i = 0; i < bearishRejectionBarsCount; i++)
{
//
Add(
state.bearishRejectionBars[i],
mBearishRejectionBars //
);
}
}
//
}
}
//
UpdatePOIs(
bar_index,
prevCalculated //
);
}
}
else
{
FillBuffersZero(bar_index);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
swingLowsBuffer[barIndex] = 0;
swingHighsBuffer[barIndex] = 0;
bullishMomentumBarsBuffer[barIndex] = 0;
bearishMomentumBarsBuffer[barIndex] = 0;
bullishRejectionBarsBuffer[barIndex] = 0;
bearishRejectionBarsBuffer[barIndex] = 0;
}
/**
* Update nd Validate POIS ...
*/
void UpdatePOIs(
int barIndex,
const int prevCalculated //
)
{
//
// CleanChart();
FillBuffersZero(barIndex);
//
if (prevCalculated <= 0)
{
return;
}
//
// CleanChart();
datetime cTime = TimeCurrent();
//
XOHCL iBar;
bool isInited = iBar.Init(
_Symbol,
_Period,
barIndex //
);
if (!isInited)
{
return;
}
//
XOHCL iPBar;
isInited = iPBar.Init(
_Symbol,
_Period,
barIndex + 1 //
);
if (!isInited)
{
return;
}
//
// Order Blcoks ...
//
// Bullish ...
int bullOBsCount = ArraySize(mBullishOrderBlocks);
if (IsValidSize(bullOBsCount))
{
//
for (int i = 0; i < bullOBsCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mBullishOrderBlocks[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mBullishOrderBlocks[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mBullishOrderBlocks[i].To(cTime);
}
else
{
mBullishOrderBlocks[i].To(breakerBar.time);
}
//
if (drawBullishOrderBlocks)
{
//
XCBullishOrderBlockObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishOrderBlock(
mBullishOrderBlocks[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
// Bearish ...
int bearOBsCount = ArraySize(mBearishOrderBlocks);
if (IsValidSize(bearOBsCount))
{
//
for (int i = 0; i < bearOBsCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mBearishOrderBlocks[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mBearishOrderBlocks[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mBearishOrderBlocks[i].To(cTime);
}
else
{
mBearishOrderBlocks[i].To(breakerBar.time);
}
//
if (drawBearishOrderBlocks)
{
//
XCBearishOrderBlockObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishOrderBlock(
mBearishOrderBlocks[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
// Fair Value Gap ...
//
// Bullish ...
int bullFVGsCount = ArraySize(mBullishFairValueGaps);
if (IsValidSize(bullFVGsCount))
{
//
for (int i = 0; i < bullFVGsCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mBullishFairValueGaps[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mBullishFairValueGaps[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mBullishFairValueGaps[i].To(cTime);
}
else
{
mBullishFairValueGaps[i].To(breakerBar.time);
}
//
if (drawBullishFairValueGaps)
{
//
XCBullishFairValueGapObject *iObj;
bool isCreated = mPOIDrawer.CreateBullishFairValueGap(
mBullishFairValueGaps[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
// Bearish ...
int bearFVGsCount = ArraySize(mBearishFairValueGaps);
if (IsValidSize(bearFVGsCount))
{
//
for (int i = 0; i < bearFVGsCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mBearishFairValueGaps[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mBearishFairValueGaps[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mBearishFairValueGaps[i].To(cTime);
}
else
{
mBearishFairValueGaps[i].To(breakerBar.time);
}
//
if (drawBearishFairValueGaps)
{
//
XCBearishFairValueGapObject *iObj;
bool isCreated = mPOIDrawer.CreateBearishFairValueGap(
mBearishFairValueGaps[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
// Support and Resistance Zones ...
//
// Support Zones ...
int supportZonesCount = ArraySize(mSupportZones);
if (IsValidSize(supportZonesCount))
{
//
for (int i = 0; i < supportZonesCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mSupportZones[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mSupportZones[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mSupportZones[i].To(cTime);
}
else
{
mSupportZones[i].To(breakerBar.time);
}
//
if (drawSupportZones)
{
//
XCSupportZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateSupportZone(
mSupportZones[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
// Resistance Zones ...
int resistanceZonesCount = ArraySize(mResistanceZones);
if (IsValidSize(resistanceZonesCount))
{
//
for (int i = 0; i < resistanceZonesCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mResistanceZones[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mResistanceZones[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mResistanceZones[i].To(cTime);
}
else
{
mResistanceZones[i].To(breakerBar.time);
}
//
if (drawResistanceZones)
{
//
XCResistanceZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateResistanceZone(
mResistanceZones[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
// Supply and Demand Zones ...
//
// Supply Zones ...
int supplyZonesCount = ArraySize(mSupplyZones);
if (IsValidSize(supplyZonesCount))
{
//
for (int i = 0; i < supplyZonesCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mSupplyZones[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mSupplyZones[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mSupplyZones[i].To(cTime);
}
else
{
mSupplyZones[i].To(breakerBar.time);
}
//
if (drawSupplyZones)
{
//
XCSupplyZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateSupplyZone(
mSupplyZones[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
// Demand Zones ...
int demandZonesCount = ArraySize(mDemandZones);
if (IsValidSize(demandZonesCount))
{
//
for (int i = 0; i < demandZonesCount; i++)
{
//
// Check OB Activation ...
// XOHCL activatedBar;
// ENUM_X_DIRECTION activatedDir;
// bool isActivated = mDemandZones[i].IsActivated(
// activatedBar,
// activatedDir //
// );
//
// Check OB Breake ...
XOHCL breakerBar;
ENUM_X_DIRECTION breakerDir;
bool isBreaked = mDemandZones[i].IsBreaked(
breakerBar,
breakerDir //
);
if (!isBreaked)
{
mDemandZones[i].To(cTime);
}
else
{
mDemandZones[i].To(breakerBar.time);
}
//
if (drawDemandZones)
{
//
XCDemandZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateDemandZone(
mDemandZones[i],
iObj //
);
if (isCreated)
{
//
Add(
(XCBaseObject *)iObj,
mPOIObjects //
);
}
}
}
}
//
//
//
//
double swingsDistance = _Point * 5;
double momentumBarsDistance = _Point * 20;
double rejectionBarsDistance = _Point * 40;
//
// Swings ...
//
// Lows ...
int swingLowsCount = ArraySize(mSwingLows);
if (IsValidSize(swingLowsCount))
{
//
for (int i = 0; i < swingLowsCount; i++)
{
//
XCSwing *iSwing = mSwingLows[i];
//
double iValue = iSwing.GetValue() - swingsDistance;
int iIDX = iBarShift(
_Symbol,
_Period,
iSwing.GetTime() //
);
//
swingLowsBuffer[iIDX] = iValue;
}
}
//
// Highs ...
int swingHighsCount = ArraySize(mSwingHighs);
if (IsValidSize(swingHighsCount))
{
//
for (int i = 0; i < swingHighsCount; i++)
{
//
XCSwing *iSwing = mSwingHighs[i];
//
double iValue = iSwing.GetValue() + swingsDistance;
int iIDX = iBarShift(
_Symbol,
_Period,
iSwing.GetTime() //
);
//
swingHighsBuffer[iIDX] = iValue;
}
}
//
// Momentum Bars ...
//
// Bullish ...
int bullishMomentumBarsCount = ArraySize(mBullishMomentumBars);
if (IsValidSize(bullishMomentumBarsCount))
{
//
for (int i = 0; i < bullishMomentumBarsCount; i++)
{
//
XCMomentumBar *iMomentumBar = mBullishMomentumBars[i];
//
XOHCL iBar;
bool isIBarFilled = iMomentumBar.FillBar(iBar);
//
double iValue = iBar.low - momentumBarsDistance;
int iIDX = iBar.Index();
//
bullishMomentumBarsBuffer[iIDX] = iValue;
}
}
//
// Bearish ...
int bearishMomentumBarsCount = ArraySize(mBearishMomentumBars);
if (IsValidSize(bearishMomentumBarsCount))
{
//
for (int i = 0; i < bearishMomentumBarsCount; i++)
{
//
XCMomentumBar *iMomentumBar = mBearishMomentumBars[i];
//
XOHCL iBar;
bool isIBarFilled = iMomentumBar.FillBar(iBar);
//
double iValue = iBar.high + momentumBarsDistance;
int iIDX = iBar.Index();
//
bearishMomentumBarsBuffer[iIDX] = iValue;
}
}
//
// Rejection Bars ...
//
// Bullish ...
int bullishRejectionBarsCount = ArraySize(mBullishRejectionBars);
if (IsValidSize(bullishRejectionBarsCount))
{
//
for (int i = 0; i < bullishRejectionBarsCount; i++)
{
//
XCRejectionBar *iRejectionBar = mBullishRejectionBars[i];
//
XOHCL iBar;
bool isIBarFilled = iRejectionBar.FillBar(iBar);
//
double iValue = iBar.low - rejectionBarsDistance;
int iIDX = iBar.Index();
//
bullishRejectionBarsBuffer[iIDX] = iValue;
}
}
//
// Bearish ...
int bearishRejectionBarsCount = ArraySize(mBearishRejectionBars);
if (IsValidSize(bearishRejectionBarsCount))
{
//
for (int i = 0; i < bearishRejectionBarsCount; i++)
{
//
XCRejectionBar *iRejectionBar = mBearishRejectionBars[i];
//
XOHCL iBar;
bool isIBarFilled = iRejectionBar.FillBar(iBar);
//
double iValue = iBar.high + rejectionBarsDistance;
int iIDX = iBar.Index();
//
bearishRejectionBarsBuffer[iIDX] = iValue;
}
}
}
/**
* Clear all Drawn Objects ...
*/
void CleanChart()
{
//
long chartID = mPOIDrawer.ChartIdentification();
int subWindow = mPOIDrawer.SubWindowIdentification();
string objName = NULL;
//
int count = ArraySize(mPOIObjects);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
objName = mPOIObjects[i].ObjName();
mPOIObjects[i].Delete();
mPOIObjects[i].Detach();
//
RemoveDraw(
objName,
chartID,
subWindow //
);
}
}
//
RemoveDraws(
iPrefix,
chartID,
subWindow //
);
//
Clean(mPOIObjects);
//
ZeroMemory(mPOIObjects);
}