diff --git a/Indicators/x-saherelm.x121.xczone.mq5 b/Documents/Indicators/x-saherelm.x121.xtb.mq5 similarity index 93% rename from Indicators/x-saherelm.x121.xczone.mq5 rename to Documents/Indicators/x-saherelm.x121.xtb.mq5 index 0e465bc2..f251c25f 100644 --- a/Indicators/x-saherelm.x121.xczone.mq5 +++ b/Documents/Indicators/x-saherelm.x121.xtb.mq5 @@ -16,14 +16,14 @@ #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" -#property description "SaherElm X121 XCZone Indicator" +#property description "SaherElm X121 XTB Indicator" #property strict // // Definitions ... // -#define ShortName "X121 XCZone" +#define ShortName "X121 XTB" // // Includes Common Library ... @@ -204,6 +204,10 @@ input double rsiOBLevel = 70.0; // RSI OB Level input double rsiOSLevel = 30.0; // RSI OS Level input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To input int atrLength = 14; // ATR Length +input double atrMultiplier = 1.5; // ATR Band Multiplier +input ENUM_X_PRICE atrUpperPriceType = X_PRICE_HIGH; // ATR Upper Zone Applied To +input ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // ATR Lower Zone Applied To +input ENUM_X_MA_METHOD atrSignalMethod = X_MA_MODE_SMA; // ATR Signalling Method input int barsSignalLength = 14; // Bars Signal Length input ENUM_X_MA_METHOD barsSignalMethod = X_MA_MODE_EMA; // Bars Signalling Method input int deltaSignalLength = 14; // Delta Signal Length @@ -228,6 +232,7 @@ input group "Filtering"; input bool filterBasedOnSar = false; // Filter Based on Sar input bool filterBasedOnRSI = false; // Filter Based on RSI input bool filterBasedOnADX = false; // Filter Based on ADX +input bool filterBasedOnATR = false; // Filter Based on ATR input bool filterBasedOnTrend = false; // Filter Based on Trend input bool filterBasedOnDelta = false; // Filter Based on Delta input bool filterBasedOnVolume = false; // Filter Based on Volume @@ -251,14 +256,15 @@ input bool showBars = true; // Show Bars input bool showSar = false; // Show Sar input bool showTrend = false; // Show Trend input bool showHKBars = false; // Show Hiken Ashi Bars +input bool showATRBand = false; // Show ATR Band input bool showTrendBars = false; // Show Trend Bars input bool showSignalBars = false; // Show Signal Bars input bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars // // Draws ... -input bool drawZones = true; // Draw Detected Zones -input bool drawSignals = true; // Draw Zone's Signal +input bool drawZones = false; // Draw Detected Zones +input bool drawSignals = false; // Draw Zone's Signal // input int startCalculationForLastBars = 1000; // Calculate Last n Bars @@ -312,8 +318,8 @@ input ENUM_LINE_STYLE fvgStyle = STYLE_SOLID; // FVG Style #property indicator_chart_window // -#property indicator_buffers 32 -#property indicator_plots 5 +#property indicator_buffers 36 +#property indicator_plots 7 // // Plot Buffers ... @@ -447,10 +453,41 @@ double barHKSignalColorBuffer[]; #property indicator_type5 DRAW_COLOR_CANDLES #property indicator_color5 CLR_NONE, clrAqua, clrMagenta +// +// ATR ... + +// +// Upper ... + +// +#define atrUpperBufferIndex 19 +#define atrUpperBufferPlotIndex 5 +double atrUpperBuffer[]; + +#property indicator_label6 "X121 XATRU" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrYellow +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// Lower ... + +// +#define atrLowerBufferIndex 20 +#define atrLowerBufferPlotIndex 6 +double atrLowerBuffer[]; + +#property indicator_label7 "X121 XATRL" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrYellow +#property indicator_style7 STYLE_SOLID +#property indicator_width7 1 + // // Data Buffers ... -#define mLastBufferIndex 18 +#define mLastBufferIndex 20 // // TREND State ... @@ -523,6 +560,12 @@ double bearishVolumeSignalBuffer[]; #define atrBufferIndex mLastBufferIndex + 13 double atrBuffer[]; +#define atrUpperRawBufferIndex mLastBufferIndex + 14 +double atrUpperRawBuffer[]; + +#define atrLowerRawBufferIndex mLastBufferIndex + 15 +double atrLowerRawBuffer[]; + // // Variables, Properties and etc ... @@ -933,6 +976,14 @@ int OnCalculate( ); } + // + if (prev_calculated == 0) + { + // + string message = "History Finished ..."; + Print(message); + } + // return rates_total; } @@ -961,10 +1012,13 @@ bool ValidateInputs() rsiOBLevel > 0 && rsiOSLevel > 0 && sarMax > sarStep && + atrMultiplier > 0 && barsSignalLength > 2 && deltaSignalLength > 2 && hkSignalBarLength > 2 && volumeSignalLength > 2 && + IsValid(atrUpperPriceType) && + IsValid(atrLowerPriceType) && barsSignalMethod != X_MA_MODE_NONE && deltaSignalMethod != X_MA_MODE_NONE && hkSignalBarMethod != X_MA_MODE_NONE && @@ -1140,6 +1194,27 @@ void DefineBuffers() ArraySetAsSeries(lowHKSignalBuffer, true); SetIndexBuffer(lowHKSignalBufferIndex, lowHKSignalBuffer, INDICATOR_DATA); + // + // ATR ... + + // + // UPPER ... + ENUM_DRAW_TYPE atrUpperDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(atrUpperBuffer, true); + SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA); + PlotIndexSetDouble(atrUpperBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_DRAW_TYPE, atrUpperDrawType); + + // + // LOWER ... + ENUM_DRAW_TYPE atrLowerDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + ArraySetAsSeries(atrLowerBuffer, true); + SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA); + PlotIndexSetDouble(atrLowerBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_DRAW_TYPE, atrLowerDrawType); + // // Data Buffers ... @@ -1201,6 +1276,14 @@ void DefineBuffers() // ATR ... ArraySetAsSeries(atrBuffer, true); SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrUpperRawBuffer, true); + SetIndexBuffer(atrUpperRawBufferIndex, atrUpperRawBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrLowerRawBuffer, true); + SetIndexBuffer(atrLowerRawBufferIndex, atrLowerRawBuffer, INDICATOR_CALCULATIONS); } /** @@ -1589,6 +1672,69 @@ void CalculateValues( ? iHKSignalColorValue : hideColorIDX; + // + // Calculate ATR Band ... + double iATR = atrBuffer[bar_index]; + double iAppliedATR = atrMultiplier * iATR; + double iATRUpperPrice = GetAppliedPrice( + atrUpperPriceType, + open, + high, + low, + close, + bar_index // + ); + double iATRLowerPrice = GetAppliedPrice( + atrLowerPriceType, + open, + high, + low, + close, + bar_index // + ); + double iATRUpper = iATRUpperPrice + iAppliedATR; + double iATRLower = iATRLowerPrice - iAppliedATR; + atrUpperRawBuffer[bar_index] = iATRUpper; + atrLowerRawBuffer[bar_index] = iATRLower; + + // + bool canSignalATR = IsValid(atrSignalMethod); + if (canSignalATR) + { + // + // Upper ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + bar_index, + atrLength, + atrUpperRawBuffer, + atrUpperBuffer, + atrSignalMethod // + ); + + // + // Lower ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + bar_index, + atrLength, + atrLowerRawBuffer, + atrLowerBuffer, + atrSignalMethod // + ); + } + else + { + // + atrUpperBuffer[bar_index] = iATRUpper; + atrLowerBuffer[bar_index] = iATRLower; + } + + // + // Trigger Block ... + // DetectTriggerBlock( bar_index, @@ -2113,6 +2259,24 @@ void DetectTriggerBlock( : isHKSignalBarSwitchedToBearish); } + // + // ATR ... + if (has && + filterBasedOnATR) + { + // + fromIDX = tb.FromIndex(); + double iATRUpper = atrUpperBuffer[fromIDX]; + double iATRLower = atrLowerBuffer[fromIDX]; + + // + has = + has && + (isBullish + ? tb.trigger.lower < iATRLower + : tb.trigger.upper > iATRUpper); + } + // // SAR ... if (has && diff --git a/Helpers/x-saherelm.x121.xtb.helper.mq5 b/Helpers/x-saherelm.x121.xtb.helper.mq5 new file mode 100644 index 00000000..2adc0864 --- /dev/null +++ b/Helpers/x-saherelm.x121.xtb.helper.mq5 @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCX121XCTBHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.x-helper.class.mq5" + +// +// Definitions ... + +// +// Buffers ... +enum ENUM_X121_XTB_BUFFERS +{ + X121_XTB_TREND_LINE = 0, + X121_XTB_SAR_LINE = 2, + X121_XTB_SBAR_O_LINE = 4, + X121_XTB_SBAR_H_LINE = 5, + X121_XTB_SBAR_L_LINE = 6, + X121_XTB_SBAR_C_LINE = 7, + X121_XTB_HK_BAR_O_LINE = 9, + X121_XTB_HK_BAR_H_LINE = 10, + X121_XTB_HK_BAR_L_LINE = 11, + X121_XTB_HK_BAR_C_LINE = 12, + X121_XTB_HK_SBAR_O_LINE = 14, + X121_XTB_HK_SBAR_H_LINE = 15, + X121_XTB_HK_SBAR_L_LINE = 16, + X121_XTB_HK_SBAR_C_LINE = 17, + X121_XTB_ATR_BAND_UPPER_LINE = 19, + X121_XTB_ATR_BAND_LOWER_LINE = 20, + X121_XTB_TREND_STATE_LINE = 21, + X121_XTB_SAR_STATE_LINE = 22, + X121_XTB_RSI_LINE = 23, + X121_XTB_ADX_LINE = 24, + X121_XTB_ADXP_LINE = 25, + X121_XTB_ADXN_LINE = 26, + X121_XTB_DELTA_LINE = 27, + X121_XTB_DELTA_SIGNAL_LINE = 28, + X121_XTB_VOLUME_BULLISH_LINE = 29, + X121_XTB_VOLUME_BEARISH_LINE = 30, + X121_XTB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE = 31, + X121_XTB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE = 32, + X121_XTB_ATR_LINE = 33, + X121_XTB_ATR_BAND_RAW_UPPER_LINE = 34, + X121_XTB_ATR_BAND_RAW_LOWER_LINE = 35, +}; \ No newline at end of file diff --git a/Indicators/x-saherelm.x121.xcatb.mq5 b/Indicators/x-saherelm.x121.xcatb.mq5 new file mode 100644 index 00000000..6fec306d --- /dev/null +++ b/Indicators/x-saherelm.x121.xcatb.mq5 @@ -0,0 +1,2743 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XCATB +// Description: Integrates All Requirements inside +// this indicator for analyse Markets to +// Detect Trigger Blocks ... +// +// - HK Bars; +// - ATR Band; +// - Signal Bars; +// - Parabolic Sar; +// - HK Signal Bars; +// - Peaks and Vales; +// - Peaks and Vales Goldens; +// - Trending Average Prices; +// +// - ATR; +// - RSI; +// - ADX; +// - DELTA; +// - VOLUME; +// +// 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 XCATB Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 XCATB" + +// +// Imports ... +#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.x121.xcatb.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; + +// +// Short ... +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Short Period + +// +// Medium ... +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period + +// +// Long ... +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period + +// +// Hind ... +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period + +// +// Select Trending Cycle ... +// this Cycle Used for All Calculations ... +input ENUM_X_MARKET_CYCLES appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + +// +// Signal ... +input group "Signal"; +input int signalR2R = 4; // Risk Reward Ratio +input double slAtrMultiplier = 1.0; // ATR Multiplier for SL + +// +// Validating ... +input group "Validating"; +input bool forceHasSwing = false; // Force Blocks to Have Swing +input bool forceObBarType = false; // Force Block Has Reversal Bar +input bool forceOBFVGBarType = false; // Force FVG Has Same Bars +input bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +input bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +input bool validateGapSequence = false; // Validate Block's Gap Sequence +input bool validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + +// +// Filtering ... +input group "Filtering"; +input bool filterBasedOnPV = false; // Filter Based on Peak and Vale +input bool filterBasedOnSar = false; // Filter Based on Sar +input bool filterBasedOnRSI = false; // Filter Based on RSI +input bool filterBasedOnADX = false; // Filter Based on ADX +input bool filterBasedOnATR = false; // Filter Based on ATR +input bool filterBasedOnTrend = false; // Filter Based on Trend +input bool filterBasedOnDelta = false; // Filter Based on Delta +input bool filterBasedOnVolume = false; // Filter Based on Volume +input bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar +input bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +input group "Alerts"; +input string mAlertPrefix = ""; // Alert Prefix +input bool _logAlerts = true; // Log Alerts +input bool _pushAlerts = false; // Push Alerts +input bool _mailAlerts = false; // Mail Alerts +input bool _terminalAlerts = true; // Terminal Alerts + +// +// Presentation ... +input group "Presentation"; +input bool showBars = true; // Show Bars +input bool showPV = false; // Show PV +input bool showPVGolden = false; // Show PV Golden +input bool showSar = false; // Show Sar +input bool showTrend = false; // Show Trend +input bool showATRBand = false; // Show ATR Band +input bool showTrendBars = false; // Show Trend Bars +input bool showSignalBars = false; // Show Signal Bars +input bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars + +// +input int startCalculationForLastBars = 1500; // Calculate Last n Bars + +// +// Non Inputs ... +double sarStep = 0.02; // Step +double sarMax = 0.2; // Maximum +double rsiOBLevel = 70.0; // RSI OB Level +double rsiOSLevel = 30.0; // RSI OS Level +double adxThreshold = 25.0; // ADX Threshold +int sarArrowCode = 159; // Parabolic Sar Arrow Code +int peakArrowCode = 159; // Peaks Arrow Code +int valeArrowCode = 159; // Vales Arrow Code +double atrMultiplier = 1.5; // ATR Band Multiplier +bool showShortCycle = false; // Show Short Cycle Range +bool showMediumCycle = false; // Show Medium Cycle Range +bool showLongCycle = false; // Show Long Cycle Range +bool showHindCycle = false; // Show Hind Cycle Range +ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode +ENUM_SERIESMODE upperMode = MODE_HIGH; // Peak Method +ENUM_SERIESMODE lowerMode = MODE_LOW; // Vale Method +ENUM_X_PRICE atrUpperPriceType = X_PRICE_HIGH; // ATR Upper Zone Applied To +ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // ATR Lower Zone Applied To +ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To +ENUM_APPLIED_PRICE trendAppliedTo = PRICE_MEDIAN; // Trend Applied To +ENUM_X_MA_METHOD atrSignalMethod = X_MA_MODE_EMA; // ATR Signalling Method +ENUM_X_MA_METHOD barsSignalMethod = X_MA_MODE_EMA; // Bars Signalling Method +ENUM_X_MA_METHOD deltaSignalMethod = X_MA_MODE_EMA; // Delta Signalling Method +ENUM_X_MA_METHOD hkSignalBarMethod = X_MA_MODE_EMA; // Hiken Ashi Signal Method +ENUM_X_MA_METHOD volumeSignalMethod = X_MA_MODE_EMA; // Volume Signalling Method + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +#define bullishState 1 +#define neuturalState 0 +#define bearishState -1 + +// +#define emptyValue 0.0 + +// +// Buffers ... + +// +#property indicator_chart_window + +// +// Plot: 18 +// Color: 4 +// Bar: 8 +// Data Buffer: 19 +#property indicator_buffers 49 +#property indicator_plots 18 + +// +// Plot Buffers ... + +// +// SAR ... + +// +#define sarBufferIndex 0 +#define sarBufferPlotIndex 0 +double sarBuffer[]; + +// +#define sarColorBufferIndex 1 +double sarColorBuffer[]; + +// +#property indicator_label1 "SAR" +#property indicator_type1 DRAW_COLOR_ARROW +#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_width1 2 + +// +// PEAKS ... + +// +#define peakBufferIndex 2 +#define peakBufferPlotIndex 1 +double peakBuffer[]; + +// +#property indicator_label2 "PEAK" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +// VALES ... + +// +#define valeBufferIndex 3 +#define valeBufferPlotIndex 2 +double valeBuffer[]; + +// +#property indicator_label3 "VALE" +#property indicator_type3 DRAW_ARROW +#property indicator_color3 clrAqua +#property indicator_width3 1 + +// +// PEAKS Golden ... + +// +#define peakGoldenBufferIndex 4 +#define peakGoldenBufferPlotIndex 3 +double peakGoldenBuffer[]; + +// +#property indicator_label4 "PEAK Golden" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// VALE Golden ... + +// +#define valeGoldenBufferIndex 5 +#define valeGoldenBufferPlotIndex 4 +double valeGoldenBuffer[]; + +// +#property indicator_label5 "VALES Golden" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAqua +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// ATR ... + +// +// Upper ... + +// +#define atrUpperBufferIndex 6 +#define atrUpperBufferPlotIndex 5 +double atrUpperBuffer[]; + +// +#property indicator_label6 "XATRU" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrYellow +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// Lower ... + +// +#define atrLowerBufferIndex 7 +#define atrLowerBufferPlotIndex 6 +double atrLowerBuffer[]; + +// +#property indicator_label7 "XATRL" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrYellow +#property indicator_style7 STYLE_SOLID +#property indicator_width7 1 + +// +// TREND ... + +// +#define trendBufferIndex 8 +#define trendBufferPlotIndex 7 +double trendBuffer[]; + +// +#define trendColorBufferIndex 9 +double trendColorBuffer[]; + +// +#property indicator_label8 "Trend" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrAqua, clrMagenta, clrGray +#property indicator_style8 STYLE_SOLID +#property indicator_width8 2 + +// +// Signal Bar ... + +// +#define sBarOpenBufferIndex 10 +double sBarOpenSBuffer[]; + +// +#define sBarHighBufferIndex 11 +double sBarHighBuffer[]; + +// +#define sBarLowBufferIndex 12 +double sBarLowBuffer[]; + +// +#define sBarCloseBufferIndex 13 +double sBarCloseBuffer[]; + +// +#define sBarColorBufferIndex 14 +double sBarColorBuffer[]; + +// +#define sBarBufferPlotIndex 8 +#property indicator_label9 "XSGB Open;XSGB High;XSGB Low;XSGB Close" +#property indicator_type9 DRAW_COLOR_CANDLES +#property indicator_color9 CLR_NONE, clrLime, clrRed + +// +// XHK SIGNAL ... + +// +#define hkSBarOpenBufferIndex 15 +double hkSBarOpenBuffer[]; + +// +#define hkSBarHighBufferIndex 16 +double hkSBarHighBuffer[]; + +// +#define hkSBarLowBufferIndex 17 +double hkSBarLowBuffer[]; + +// +#define hkSBarCloseBufferIndex 18 +double hkSBarCloseBuffer[]; + +// +#define hkSBarColorBufferIndex 19 +double hkSBarColorBuffer[]; + +// +#define hkSBarBufferPlotIndex 9 +#property indicator_label10 "XHKSGB Open;XHKSGB High;XHKSGB Low;XHKSGB Close" +#property indicator_type10 DRAW_COLOR_CANDLES +#property indicator_color10 CLR_NONE, clrAqua, clrMagenta + +// +// CYCLES Range ... + +// +// SHORT ... + +// +#define sHHBufferIndex 20 +#define sHHBufferPlotIndex 10 +double sHHBuffer[]; + +// +#property indicator_label11 "SH" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define sLLBufferIndex 21 +#define sLLBufferPlotIndex 11 +double sLLBuffer[]; + +// +#property indicator_label12 "SL" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// MEDIUM ... + +// +#define mHHBufferIndex 22 +#define mHHBufferPlotIndex 12 +double mHHBuffer[]; + +// +#property indicator_label13 "MH" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrIndigo +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define mLLBufferIndex 23 +#define mLLBufferPlotIndex 13 +double mLLBuffer[]; + +// +#property indicator_label14 "ML" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrIndigo +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +// LONG ... + +// +#define lHHBufferIndex 24 +#define lHHBufferPlotIndex 14 +double lHHBuffer[]; + +// +#property indicator_label15 "LH" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrGoldenrod +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define lLLBufferIndex 25 +#define lLLBufferPlotIndex 15 +double lLLBuffer[]; + +// +#property indicator_label16 "LL" +#property indicator_type16 DRAW_LINE +#property indicator_color16 clrGoldenrod +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +// HIND ... + +// +#define hHHBufferIndex 26 +#define hHHBufferPlotIndex 16 +double hHHBuffer[]; + +// +#property indicator_label17 "HH" +#property indicator_type17 DRAW_LINE +#property indicator_color17 clrBrown +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +#define hLLBufferIndex 27 +#define hLLBufferPlotIndex 17 +double hLLBuffer[]; + +// +#property indicator_label18 "HL" +#property indicator_type18 DRAW_LINE +#property indicator_color18 clrBrown +#property indicator_style18 STYLE_DOT +#property indicator_width18 1 + +// +// Data Buffers ... + +// +#define mLastBufferIndex 27 + +// +// SAR ... + +// +#define sarStateBufferIndex mLastBufferIndex + 1 +double sarStateBuffer[]; + +// +// TREND State ... + +// +#define trendStateBufferIndex mLastBufferIndex + 2 +double trendStateBuffer[]; + +// +// RSI ... + +// +#define rsiBufferIndex mLastBufferIndex + 3 +double rsiBuffer[]; + +// +// ADX ... + +// +#define adxBufferIndex mLastBufferIndex + 4 +double adxBuffer[]; + +// +#define adxpBufferIndex mLastBufferIndex + 5 +double adxpBuffer[]; + +// +#define adxnBufferIndex mLastBufferIndex + 6 +double adxnBuffer[]; + +// +// DELTA ... + +// +#define deltaBufferIndex mLastBufferIndex + 7 +double deltaBuffer[]; + +// +#define deltaSignalBufferIndex mLastBufferIndex + 8 +double deltaSignalBuffer[]; + +// +// VOLUMES ... + +// +#define bullishVolumeBufferIndex mLastBufferIndex + 9 +double bullishVolumeBuffer[]; + +// +#define bearishVolumeBufferIndex mLastBufferIndex + 10 +double bearishVolumeBuffer[]; + +// +#define bullishVolumeSignalBufferIndex mLastBufferIndex + 11 +double bullishVolumeSignalBuffer[]; + +// +#define bearishVolumeSignalBufferIndex mLastBufferIndex + 12 +double bearishVolumeSignalBuffer[]; + +// +// ATR ... + +// +#define atrBufferIndex mLastBufferIndex + 13 +double atrBuffer[]; + +// +#define atrUpperRawBufferIndex mLastBufferIndex + 14 +double atrUpperRawBuffer[]; + +// +#define atrLowerRawBufferIndex mLastBufferIndex + 15 +double atrLowerRawBuffer[]; + +// +// HK ... + +// +#define openHKBufferIndex mLastBufferIndex + 16 +double openHKBuffer[]; + +// +#define highHKBufferIndex mLastBufferIndex + 17 +double highHKBuffer[]; + +// +#define lowHKBufferIndex mLastBufferIndex + 18 +double lowHKBuffer[]; + +// +#define closeHKBufferIndex mLastBufferIndex + 19 +double closeHKBuffer[]; + +// +// Variables, Properties and etc ... + +// +int limit; + +// +int maxLength; + +// +int firstBarIndex; + +// +// Bars Color Variables ... +color _upColor = clrLime; +color _downColor = clrRed; +color _lineColor = clrLime; +color _bullishColor = clrLime; +color _bearishColor = clrRed; + +// +// XMarketCycle sc; +int mSCLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// XMarketCycle mc; +int mMCLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// XMarketCycle lc; +int mLCLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// XMarketCycle hc; +int mHCLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +// Applied Cycle ... +int mAppliedLength; +ENUM_TIMEFRAMES mAppliedPeriod = NULL; + +// +// Handlers ... +int atrHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int adxHandler = INVALID_HANDLE; +int trendHandler = INVALID_HANDLE; + +// +XCAlert *mAlert; +CArrayObj mObjects; +XCPOIDrawer *mDrawer; +bool mEnableAlerts = false; +XCBarAnalyser *mBarAnalyser; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + bool has = false; + + // + ReadBarStyle(); + + // + // Validate Inputs ... + has = ValidateInputs(); + if (!has) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + has = InitCycles(); + if (!has) + { + 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(); + + // + // Initial Requirements ... + has = InitRequirements(); + if (!has) + { + return INIT_FAILED; + } + + // + if (showBars) + { + ShowBars(); + } + else + { + HideBars(); + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // 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 + + // + ShowBars(); + + // + mObjects.Clear(); + + // + delete mAlert; + ZeroMemory(mAlert); + + // + delete mDrawer; + ZeroMemory(mDrawer); + + // + delete mBarAnalyser; + ZeroMemory(mBarAnalyser); + + // + // De Initialize all Handlers and etc ... + IndicatorRelease(atrHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(adxHandler); + IndicatorRelease(trendHandler); +} + +/** + * 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 ... + + // + // ATR ... + int atrCalculatedBars = BarsCalculated(atrHandler); + + // + // SAR ... + int sarCalculatedBars = BarsCalculated(sarHandler); + + // + // RSI ... + int rsiCalculatedBars = BarsCalculated(rsiHandler); + + // + // ADX ... + int adxCalculatedBars = BarsCalculated(adxHandler); + + // + // TREND ... + int trendCalculatedBars = BarsCalculated(trendHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // ATR ... + atrCalculatedBars >= maxLength && + // + // SAR ... + sarCalculatedBars >= maxLength && + // + // RSI ... + rsiCalculatedBars >= maxLength && + // + // ADX ... + adxCalculatedBars >= maxLength && + // + // TREND ... + trendCalculatedBars >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // ATR ... + int copiedAtrs = CopyBuffer(atrHandler, MAIN_LINE, 0, limit, atrBuffer); + + // + // SAR ... + int copiedSars = CopyBuffer(sarHandler, MAIN_LINE, 0, limit, sarBuffer); + + // + // RSI ... + int copiedRSIs = CopyBuffer(rsiHandler, MAIN_LINE, 0, limit, rsiBuffer); + + // + // ADX ... + int copiedADXs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer); + + // + // ADX Plus ... + int copiedADXPs = CopyBuffer(adxHandler, PLUSDI_LINE, 0, limit, adxpBuffer); + + // + // ADX Negative ... + int copiedADXNs = CopyBuffer(adxHandler, MINUSDI_LINE, 0, limit, adxnBuffer); + + // + // TREND ... + int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit, trendBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // ATR ... + copiedAtrs >= limit && + // + // SAR ... + copiedSars >= limit && + // + // RSI ... + copiedRSIs >= limit && + // + // TREND ... + copiedTrends >= limit + // + ; + 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 // + ); + } + + // + if (prev_calculated == 0) + { + // + string message = "History Finished ..."; + Print(message); + } + + // + return rates_total; +} + +// +// Custom Functions ... + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + sarMax > 0 && + sarStep > 0 && + rsiOBLevel > 0 && + rsiOSLevel > 0 && + adxThreshold > 0 && + sarMax > sarStep && + atrMultiplier > 0 && + // + IsValid(appliedCycle) && + // + IsValid(atrUpperPriceType) && + IsValid(atrLowerPriceType) && + // + // CYCLES ... + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mSCLength, mMCLength); + result = MathMax(result, mLCLength); + result = MathMax(result, mHCLength); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // Plot Buffers ... + + // + // SAR ... + + // + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_SHOW_DATA, showSar); + PlotIndexSetDouble(sarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_ARROW, sarArrowCode); + + // + ArraySetAsSeries(sarColorBuffer, true); + SetIndexBuffer(sarColorBufferIndex, sarColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(sarStateBuffer, true); + SetIndexBuffer(sarStateBufferIndex, sarStateBuffer, INDICATOR_CALCULATIONS); + + // + // PEAK / VALE ... + + // + ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE; + + // + // PEAK ... + + // + ArraySetAsSeries(peakBuffer, true); + SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode); + + // + // VALE ... + + // + ArraySetAsSeries(valeBuffer, true); + SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode); + + // + // PV GOLDEN ... + + // + ENUM_DRAW_TYPE pvGoldenDrawType = showPVGolden ? DRAW_LINE : DRAW_NONE; + + // + // PEAK Golden ... + + // + ArraySetAsSeries(peakGoldenBuffer, true); + SetIndexBuffer(peakGoldenBufferIndex, peakGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(peakGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // VALE Golden ... + + // + ArraySetAsSeries(valeGoldenBuffer, true); + SetIndexBuffer(valeGoldenBufferIndex, valeGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(valeGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // ATR Band ... + + // + // UPPER ... + ENUM_DRAW_TYPE atrUpperDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrUpperBuffer, true); + SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrUpperBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_DRAW_TYPE, atrUpperDrawType); + + // + // LOWER ... + ENUM_DRAW_TYPE atrLowerDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrLowerBuffer, true); + SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrLowerBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_DRAW_TYPE, atrLowerDrawType); + + // + // TREND ... + + // + ArraySetAsSeries(trendBuffer, true); + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetDouble(trendBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(trendColorBuffer, true); + SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(trendStateBuffer, true); + SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); + + // + // SIGNAL Bar ... + + // + // Signal Bars Color ... + ArraySetAsSeries(sBarColorBuffer, true); + SetIndexBuffer(sBarColorBufferIndex, sBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(sBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(sBarOpenSBuffer, true); + SetIndexBuffer(sBarOpenBufferIndex, sBarOpenSBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(sBarHighBuffer, true); + SetIndexBuffer(sBarHighBufferIndex, sBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(sBarLowBuffer, true); + SetIndexBuffer(sBarLowBufferIndex, sBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(sBarCloseBuffer, true); + SetIndexBuffer(sBarCloseBufferIndex, sBarCloseBuffer, INDICATOR_DATA); + + // + // XHK SIGNAL Bar ... + + // + // HK Bars Color ... + ArraySetAsSeries(hkSBarColorBuffer, true); + SetIndexBuffer(hkSBarColorBufferIndex, hkSBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(hkSBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(hkSBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hkSBarOpenBuffer, true); + SetIndexBuffer(hkSBarOpenBufferIndex, hkSBarOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hkSBarHighBuffer, true); + SetIndexBuffer(hkSBarHighBufferIndex, hkSBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(hkSBarLowBuffer, true); + SetIndexBuffer(hkSBarLowBufferIndex, hkSBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(hkSBarCloseBuffer, true); + SetIndexBuffer(hkSBarCloseBufferIndex, hkSBarCloseBuffer, INDICATOR_DATA); + + // + // CYCLES ... + + // + // SHORT ... + + // + ENUM_DRAW_TYPE sDrawType = showShortCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // MEDIUM ... + + // + ENUM_DRAW_TYPE mDrawType = showMediumCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LONG ... + + // + ENUM_DRAW_TYPE lDrawType = showLongCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // HIND ... + + // + ENUM_DRAW_TYPE hDrawType = showHindCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // Data Buffers ... + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // ADX ... + + // + ArraySetAsSeries(adxBuffer, true); + SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxpBuffer, true); + SetIndexBuffer(adxpBufferIndex, adxpBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxnBuffer, true); + SetIndexBuffer(adxnBufferIndex, adxnBuffer, INDICATOR_CALCULATIONS); + + // + // DELTA ... + + // + ArraySetAsSeries(deltaBuffer, true); + SetIndexBuffer(deltaBufferIndex, deltaBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(deltaSignalBuffer, true); + SetIndexBuffer(deltaSignalBufferIndex, deltaSignalBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + + // + ArraySetAsSeries(bullishVolumeBuffer, true); + SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeBuffer, true); + SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + SetIndexBuffer(bullishVolumeSignalBufferIndex, bullishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + SetIndexBuffer(bearishVolumeSignalBufferIndex, bearishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + // ATR ... + + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrUpperRawBuffer, true); + SetIndexBuffer(atrUpperRawBufferIndex, atrUpperRawBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrLowerRawBuffer, true); + SetIndexBuffer(atrLowerRawBufferIndex, atrLowerRawBuffer, INDICATOR_CALCULATIONS); + + // + // XHK ... + + // + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_CALCULATIONS); + + // +} + +/** + * Initial Market Cycles ... + * + * @return ( bool ) + */ +bool InitCycles() +{ + // + bool result = false; + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + if (IsValid(mSCPeriod)) + { + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + if (IsValid(mMCPeriod)) + { + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + if (IsValid(mLCPeriod)) + { + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + if (IsValid(mHCPeriod)) + { + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + } + + // + result = mSCLength > 0 && + mMCLength > mSCLength && + mLCLength > mMCLength && + mHCLength > mLCLength; + + // + // Selecte Applied Cycle ... + if (result) + { + // + switch (appliedCycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + mAppliedLength = mSCLength; + mAppliedPeriod = mSCPeriod; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + mAppliedLength = mMCLength; + mAppliedPeriod = mMCPeriod; + break; + + // + case X_MARKET_CYCLE_LONG: + // + mAppliedLength = mLCLength; + mAppliedPeriod = mLCPeriod; + break; + + // + case X_MARKET_CYCLE_HIND: + // + mAppliedLength = mHCLength; + mAppliedPeriod = mHCPeriod; + break; + } + } + + // + return result; +} + +/** + * Initial all Indicator Requirements ... + * + * @return ( false ) + * + */ +bool InitRequirements() +{ + // + bool result = false; + + // + // Handlers ... + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMax // + ); + result = sarHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + mAppliedLength // + ); + result = atrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + mAppliedLength, + rsiAppliedTo // + ); + result = rsiHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ADX ... + adxHandler = iADX( + _Symbol, + _Period, + mAppliedLength // + ); + result = adxHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // TREND ... + trendHandler = iMA( + _Symbol, + _Period, + mAppliedLength, + 0, + trendMode, + trendAppliedTo // + ); + result = trendHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Initial Class Instances ... + + // + mDrawer = new XCPOIDrawer(); + mBarAnalyser = new XCBarAnalyser(); + + // + // Initialize and Configure Alert ... + mAlert = new XCAlert(); + mEnableAlerts = + _logAlerts || + _pushAlerts || + _mailAlerts || + _terminalAlerts; + string mPrefix = ShortName + + (!IsValid(mAlertPrefix) + ? "" + : "[" + mAlertPrefix + "]"); + mAlert.SetPrefix(mPrefix); + mAlert.SetLogAlerts(_logAlerts); + mAlert.SetMailAlerts(_mailAlerts); + mAlert.SetPushAlerts(_pushAlerts); + mAlert.SetEnableAlerts(mEnableAlerts); + mAlert.SetTerminalAlerts(_terminalAlerts); + + // + return result; +} + +/** + * Calculate Custom Buffers ... + * + * @param barIndex: 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 barIndex, + 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; + if (barsLimit == 0) + { + // + barsLimit = ratesTotal; + firstBarIndex = barsLimit - 1; + } + else + { + firstBarIndex = startCalculationForLastBars; + } + + // + // bool canCalculate = true; + bool canCalculate = + barIndex <= barsLimit; + if (canCalculate) + { + // + // Calculate Values ... + CalculateValues( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + } + else + { + FillBuffersZero(barIndex); + } +} + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + sarColorBuffer[barIndex] = hideColorIDX; + trendColorBuffer[barIndex] = hideColorIDX; + + // + atrUpperRawBuffer[barIndex] = emptyValue; + atrLowerRawBuffer[barIndex] = emptyValue; +} + +// +// Custom Handlers ... + +/** + * Calculate Values ... + * + * @param barIndex: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void CalculateValues( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + int maxBarIndex = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : ratesTotal; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + // Cycle Ranges ... + CalculateCycleRanges( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // PV ... + CalculatePV( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SAR ... + CalculateSAR( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SBAR ... + CalculateSBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // HKBAR ... + CalculateHKBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // DELTA ... + CalculateDelta( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // TREND ... + CalculateTrend( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // VOLUME ... + CalculateVolume( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // ATR Band ... + CalculateATRBand( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Try To Detect Trigger Block ... + + // + // Prevent Calculation ... + if (maxBarIndex - barIndex < maxLength) + { + return; + } + + // + XTriggerBlock tb; + bool has = DetectTriggerBlock( + // + _Symbol, + _Period, + // + tb, + // + mBarAnalyser, + // + // Required Buffers ... + atrBuffer, + rsiBuffer, + adxBuffer, + adxpBuffer, + adxnBuffer, + peakBuffer, + valeBuffer, + deltaBuffer, + sarBuffer, + sarStateBuffer, + trendBuffer, + trendStateBuffer, + atrUpperBuffer, + atrLowerBuffer, + sBarOpenSBuffer, + sBarCloseBuffer, + hkSBarOpenBuffer, + hkSBarCloseBuffer, + peakGoldenBuffer, + valeGoldenBuffer, + deltaSignalBuffer, + bullishVolumeSignalBuffer, + bearishVolumeSignalBuffer, + // + barIndex, + // + // Signalling ... + signalR2R, + slAtrMultiplier, + // + // Configs ... + rsiOBLevel, + rsiOSLevel, + adxThreshold, + // + // Validators ... + forceObBarType, + forceOBFVGBarType, + forceHasSwing, + forceHasFLiquidity, + forceHasRLiquidity, + validateGapSequence, + validateBlockEdgeBreakout, + // + // Filters ... + filterBasedOnPV, + filterBasedOnSar, + filterBasedOnRSI, + filterBasedOnADX, + filterBasedOnATR, + filterBasedOnTrend, + filterBasedOnDelta, + filterBasedOnVolume, + filterBasedOnSignalBar, + filterBasedOnHKSignalBar // + ); + if (has) + { + // + // Draw ... + has = DrawTriggerBlock( + tb, + mDrawer, + mObjects // + ); + + // + // Alert ... + } +} + +// +void CalculateCycleRanges( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // SHORT ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_SHORT, + sHHBuffer, + sLLBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_MEDIUM, + mHHBuffer, + mLLBuffer // + ); + + // + // LONG ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_LONG, + lHHBuffer, + lLLBuffer // + ); + + // + // HIND ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_HIND, + hHHBuffer, + hLLBuffer // + ); +} + +// +void CalculatePV( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iSHH = sHHBuffer[barIndex]; + double iSLL = sLLBuffer[barIndex]; + + // + double iMHH = mHHBuffer[barIndex]; + double iMLL = mLLBuffer[barIndex]; + + // + double iLHH = lHHBuffer[barIndex]; + double iLLL = lLLBuffer[barIndex]; + + // + double iHHH = hHHBuffer[barIndex]; + double iHLL = hLLBuffer[barIndex]; + + // + // Calculate VALE ... + bool isVale = iSLL == iMLL && + iMLL == iLLL && + iLLL == iHLL; + double iPVale = + isFirstBar + ? emptyValue + : valeBuffer[lastBarIndex]; + double iVale = + isVale + ? iSLL + : iPVale; + valeBuffer[barIndex] = iVale; + + // + // Calculate PEAK ... + bool isPeak = iSHH == iMHH && + iMHH == iLHH && + iLHH == iHHH; + double iPPeak = + isFirstBar + ? emptyValue + : peakBuffer[lastBarIndex]; + double iPeak = + isPeak + ? iSHH + : iPPeak; + peakBuffer[barIndex] = iPeak; + + // + // GOLDEN ... + + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + barIndex // + ); + + // + // Calculate PV Gold ... + double lastPeakGold = + isFirstBar + ? emptyValue + : peakGoldenBuffer[lastBarIndex]; + double lastValeGold = + isFirstBar + ? emptyValue + : valeGoldenBuffer[lastBarIndex]; + double iPeakGold = lastPeakGold; + double iValeGold = lastValeGold; + if (isInited) + { + // + iPeakGold = iBar.FindHighest(mHCLength, MODE_CLOSE); + if (iPeakGold == 0) + { + iPeakGold = lastPeakGold; + } + + // + iValeGold = iBar.FindLowest(mHCLength, MODE_CLOSE); + if (iValeGold == 0) + { + iValeGold = lastValeGold; + } + } + else + { + // + iPeakGold = lastPeakGold; + iValeGold = lastValeGold; + } + + // + peakGoldenBuffer[barIndex] = iPeakGold; + valeGoldenBuffer[barIndex] = iValeGold; + + // + iBar.Clean(); +} + +// +void CalculateSAR( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = low[barIndex]; + double iSar = sarBuffer[barIndex]; + + // + bool isBullish = iSar < iLow; + bool isBearish = iSar > iHigh; + + // + double iSarState = isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iSarColor = iSarState > 0 + ? bullishColorIDX + : iSarState < 0 + ? bearishColorIDX + : neuturalColorIDX; + sarStateBuffer[barIndex] = iSarState; + sarColorBuffer[barIndex] = showSar + ? iSarColor + : hideColorIDX; +} + +// +void CalculateSBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + open, + sBarOpenSBuffer, + barsSignalMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + close, + sBarCloseBuffer, + barsSignalMethod // + ); + + // + double min = MathMin(sBarCloseBuffer[barIndex], sBarOpenSBuffer[barIndex]); + double max = MathMin(sBarCloseBuffer[barIndex], sBarOpenSBuffer[barIndex]); + + // + sBarLowBuffer[barIndex] = min; + sBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iSignalColorValue = + sBarOpenSBuffer[barIndex] < sBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + sBarColorBuffer[barIndex] = + showSignalBars + ? iSignalColorValue + : hideColorIDX; +} + +// +void CalculateHKBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double lastHKOpen = + isFirstBar + ? emptyValue + : openHKBuffer[lastBarIndex]; + double lastHKClose = + isFirstBar + ? emptyValue + : closeHKBuffer[lastBarIndex]; + + // + double iHKOpenValue = (lastHKOpen + lastHKClose) / 2; + double iHKCloseValue = (open[barIndex] + high[barIndex] + close[barIndex] + low[barIndex]) / 4; + double iHKHighValue = MathMax(high[barIndex], MathMax(iHKOpenValue, iHKCloseValue)); + double iHKLowValue = MathMin(low[barIndex], MathMin(iHKOpenValue, iHKCloseValue)); + + // + // Raw HK Buffers ... + openHKBuffer[barIndex] = iHKOpenValue; + highHKBuffer[barIndex] = iHKHighValue; + lowHKBuffer[barIndex] = iHKLowValue; + closeHKBuffer[barIndex] = iHKCloseValue; + + // + // XHK Signal ... + + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + openHKBuffer, + hkSBarOpenBuffer, + hkSignalBarMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + closeHKBuffer, + hkSBarCloseBuffer, + hkSignalBarMethod // + ); + + // + double min = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + double max = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + + // + hkSBarLowBuffer[barIndex] = min; + hkSBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iHKSignalColorValue = + hkSBarOpenBuffer[barIndex] < hkSBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + hkSBarColorBuffer[barIndex] = + showHKSignalBars + ? iHKSignalColorValue + : hideColorIDX; +} + +// +void CalculateDelta( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + // DELTA ... + double lastDelta = + isFirstBar + ? emptyValue + : deltaBuffer[lastBarIndex]; + double iAppliedVolume = + isBullish + ? iVolume + : -1 * iVolume; + double iDelta = + lastDelta + iAppliedVolume; + deltaBuffer[barIndex] = iDelta; + + // + // Calculate Delta Signal ... + int deltaSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + deltaBuffer, + deltaSignalBuffer, + deltaSignalMethod // + ); +} + +// +void CalculateTrend( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = high[barIndex]; + double iClose = close[barIndex]; + double iTrend = trendBuffer[barIndex]; + + // + bool isBullish = iTrend < iLow; + bool isBearish = iTrend > iHigh; + + // + double iTrendState = + isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iTrendColor = + iTrendState > 0 + ? bullishColorIDX + : iTrendState < 0 + ? bearishColorIDX + : neuturalColorIDX; + trendStateBuffer[barIndex] = iTrendState; + trendColorBuffer[barIndex] = showTrend + ? iTrendColor + : hideColorIDX; +} + +// +void CalculateVolume( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + double iBullishVolume = emptyValue; + double iBearishVolume = emptyValue; + if (isBullish) + { + iBullishVolume = iVolume; + } + else if (isBearish) + { + iBearishVolume = iVolume; + } + else + { + // + double iHalfVolume = iVolume / 2; + + // + iBullishVolume = iHalfVolume; + iBearishVolume = iHalfVolume; + } + bullishVolumeBuffer[barIndex] = iBullishVolume; + bearishVolumeBuffer[barIndex] = iBearishVolume; + + // + // Calculate Volume Signals ... + + // + int bullishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bullishVolumeBuffer, + bullishVolumeSignalBuffer, + volumeSignalMethod // + ); + + // + int bearishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bearishVolumeBuffer, + bearishVolumeSignalBuffer, + volumeSignalMethod // + ); +} + +// +void CalculateATRBand( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iATR = atrBuffer[barIndex]; + double iAppliedATR = atrMultiplier * iATR; + double iATRUpperPrice = GetAppliedPrice( + atrUpperPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRLowerPrice = GetAppliedPrice( + atrLowerPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRUpper = iATRUpperPrice + iAppliedATR; + double iATRLower = iATRLowerPrice - iAppliedATR; + atrUpperRawBuffer[barIndex] = iATRUpper; + atrLowerRawBuffer[barIndex] = iATRLower; + + // + bool canSignalATR = IsValid(atrSignalMethod); + if (canSignalATR) + { + // + // Upper ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrUpperRawBuffer, + atrUpperBuffer, + atrSignalMethod // + ); + + // + // Lower ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrLowerRawBuffer, + atrLowerBuffer, + atrSignalMethod // + ); + } + else + { + // + atrUpperBuffer[barIndex] = iATRUpper; + atrLowerBuffer[barIndex] = iATRLower; + } +} + +/** + * Calculate Specified Market Cycle Info ... + * + * @param barIndex: Integer, Bar Index ... + * @param cycle: ENUM_X_MARKET_CYCLES member, Specified Cycle ... + * @param hhBuffer: Highest High Buffer Reference ... + * @param llBuffer: Lowest Low Buffer Reference ... + */ +void CalculateCycle( + int barIndex, + ENUM_X_MARKET_CYCLES cycle, + double &hhBuffer[], + double &llBuffer[] // +) +{ + // + XOHCL bar; + bool isBarInited = bar.Init( + _Symbol, + _Period, + barIndex + // + ); + if (!isBarInited) + { + return; + } + + // + int mLength = 0; + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + mLength = mSCLength; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + mLength = mMCLength; + break; + + // + case X_MARKET_CYCLE_LONG: + mLength = mLCLength; + break; + + // + case X_MARKET_CYCLE_HIND: + mLength = mHCLength; + break; + } + + // + if (mLength == 0) + { + return; + } + + // + // Find Highest High ... + double hhValue = bar.FindHighest( + mLength, + upperMode // + ); + hhBuffer[barIndex] = hhValue; + + // + // Find Lowest Low ... + double llValue = bar.FindLowest( + mLength, + lowerMode // + ); + llBuffer[barIndex] = llValue; + + // + bar.Clean(); +} + +// +void ReadBarStyle() +{ + // + long chartId = ChartID(); + + // + _upColor = GetChartUpColor(chartId); + _downColor = GetChartDownColor(chartId); + _lineColor = GetChartLineColor(chartId); + _bullishColor = GetChartBullishColor(chartId); + _bearishColor = GetChartBearishColor(chartId); +} + +// +void ShowBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(_upColor, chartId); + SetChartDownColor(_downColor, chartId); + SetChartLineColor(_lineColor, chartId); + SetChartBullishColor(_bullishColor, chartId); + SetChartBearishColor(_bearishColor, chartId); +} + +// +void HideBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(CLR_NONE, chartId); + SetChartDownColor(CLR_NONE, chartId); + SetChartLineColor(CLR_NONE, chartId); + SetChartBullishColor(CLR_NONE, chartId); + SetChartBearishColor(CLR_NONE, chartId); +} + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.x121.xcatb.lib.mq5 b/Libraries/x-saherelm.x121.xcatb.lib.mq5 new file mode 100644 index 00000000..4f967b0d --- /dev/null +++ b/Libraries/x-saherelm.x121.xcatb.lib.mq5 @@ -0,0 +1,1384 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Library +// --------------------------------------- +// Name: XCATBLib +// Description: required Parsers for XCATB ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright `023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#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.lib.mq5" + +// +// Definiions ... + +// +enum ENUM_XCAEA_TIGGER_TYPE +{ + XCA_TRIGGER_NONE, // None + XCA_TRIGGER_BULL, // TriggerBull + XCA_TRIGGER_BEAR, // TriggerBear +}; + +// +bool IsValid(ENUM_XCAEA_TIGGER_TYPE value) +{ + return value != XCA_TRIGGER_NONE; +} + +// +string ToString(ENUM_XCAEA_TIGGER_TYPE value) +{ + return EnumToString(value); +} + +// +ENUM_XCAEA_TIGGER_TYPE GetType(string type) +{ + // + ENUM_XCAEA_TIGGER_TYPE result = XCA_TRIGGER_NONE; + + // + bool isTriggerBull = type == ToString(XCA_TRIGGER_BULL); + bool isTriggerBear = type == ToString(XCA_TRIGGER_BEAR); + + // + if (isTriggerBull) + { + result = XCA_TRIGGER_BULL; + } + else if (isTriggerBear) + { + result = XCA_TRIGGER_BEAR; + } + + // + return result; +} + +// +ENUM_X_DIRECTION GetDirection(ENUM_XCAEA_TIGGER_TYPE value) +{ + return value == XCA_TRIGGER_BULL + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; +} + +// +struct XTriggerBlock +{ + // + // Props ... + XBoxZone ob; // Order Block + XBoxZone fvg; // Fair Value Gap + XOHCL swingBar; // Swing of Trigger + XBoxZone trigger; // Trigger Block + XBoxZone rLiquidity; // Reversal Liquidity + XBoxZone fLiquidity; // Following Liquidity + + // + XSignal signal; // Pepared Signal + + // + // Constructor ... + XTriggerBlock() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + ob.Clean(); + fvg.Clean(); + signal.Clean(); + trigger.Clean(); + swingBar.Clean(); + rLiquidity.Clean(); + fLiquidity.Clean(); + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = ob.IsValid() && + fvg.IsValid() && + trigger.IsValid(); + + // + return result; + } + + // + bool IsBullish() + { + return IsValid() && + ob.IsBullish(); + } + + // + bool IsBearish() + { + return IsValid() && + ob.IsBearish(); + } + + // + int ToIndex() + { + return trigger.ToIndex(); + } + + // + int FromIndex() + { + return trigger.FromIndex(); + } + + // + ENUM_X_DIRECTION GetDirection() + { + // + ENUM_X_DIRECTION result = X_DIRECTION_NONE; + + // + if (IsValid()) + { + result = ob.dir; + } + + // + return result; + } + + // +}; + +// +// Extensions ... + +bool DetectTriggerBlock( + // + string symbol, + ENUM_TIMEFRAMES period, + // + XTriggerBlock &tb, + // + XCBarAnalyser *barAnalyser, + // + // Required Buffers ... + const double &_atrBuffer[], + const double &_rsiBuffer[], + const double &_adxBuffer[], + const double &_adxpBuffer[], + const double &_adxnBuffer[], + const double &_peakBuffer[], + const double &_valeBuffer[], + const double &_deltaBuffer[], + const double &_sarBuffer[], + const double &_sarStateBuffer[], + const double &_trendBuffer[], + const double &_trendStateBuffer[], + const double &_atrUpperBuffer[], + const double &_atrLowerBuffer[], + const double &_sBarOpenSBuffer[], + const double &_sBarCloseBuffer[], + const double &_hkSBarOpenBuffer[], + const double &_hkSBarCloseBuffer[], + const double &_peakGoldenBuffer[], + const double &_valeGoldenBuffer[], + const double &_deltaSignalBuffer[], + const double &_bullishVolumeSignalBuffer[], + const double &_bearishVolumeSignalBuffer[], + // + int barIndex, + // + int _r2r, + double _slAtrMultiplier, + // + // Configs ... + double _rsiOBLevel, + double _rsiOSLevel, + double _adxThreshold, + // + // Validators ... + // + bool _forceObBarType = false, + bool _forceFVGBarType = false, + bool _forceHasSwing = false, + bool _forceHasFLiquidity = false, + bool _forceHasRLiquidity = false, + bool _validateGapSequence = false, + bool _validateBlockEdgeBreakout = false, + // + // Filters ... + bool _filterBasedOnPV = false, + bool _filterBasedOnSar = false, + bool _filterBasedOnRSI = false, + bool _filterBasedOnADX = false, + bool _filterBasedOnATR = false, + bool _filterBasedOnTrend = false, + bool _filterBasedOnDelta = false, + bool _filterBasedOnVolume = false, + bool _filterBasedOnSignalBar = false, + bool _filterBasedOnHKSignalBar = false // +) +{ + // + bool result = false; + + // + // Custom Configs ... + + // + // Validators ... + _forceHasSwing = true; + _forceObBarType = true; + _forceFVGBarType = true; + _validateGapSequence = true; + + // + _forceHasFLiquidity = false; + _forceHasRLiquidity = false; + _validateBlockEdgeBreakout = false; + + // + // Filters ... + _filterBasedOnPV = true; + _filterBasedOnATR = true; + _filterBasedOnDelta = true; + _filterBasedOnVolume = true; + + // + _filterBasedOnSar = false; + _filterBasedOnRSI = false; + _filterBasedOnADX = false; + _filterBasedOnTrend = false; + _filterBasedOnSignalBar = false; + _filterBasedOnHKSignalBar = false; + + // + tb.Clean(); + + // + result = barAnalyser != NULL; + if (!result) + { + return result; + } + + // + int zIDX = 0; + bool has = false; + bool isDone = false; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Retrieve Required Bars ... + + // + XOHCL iBar; + XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ... + has = zBar.Init( + symbol, + period, + barIndex // + ); + + // + // Detect Based Order Block ... + has = + has && + barAnalyser.IsOB( + zBar, + tb.ob, + _forceFVGBarType, // Force FVG Bar Type ... + _forceObBarType // Force Block Two Bar Checking ... + ); + + // + // Detect Based Fair Value Gap ... + has = + has && + barAnalyser.IsFVG( + zBar, + tb.fvg, + _forceFVGBarType // Force FVG Bar Type ... + ); + + // + // Clone Trigger Block ... + if (has) + { + tb.trigger = tb.ob; + } + + // + bool isBullish = + has && + tb.IsBullish(); + + // + bool isBearish = + has && + tb.IsBearish(); + + // + int toIDX = tb.ToIndex(); + int fromIDX = tb.FromIndex(); + + // + // Verifications and Filters ... + + // + int loopback = 144; + + // + // Forces ... + + // + // Force Has Proper Swing ... + if (has && + _forceHasSwing) + { + // + XOHCL iPBar; + XOHCL iP2Bar; + toIDX = tb.ToIndex(); + fromIDX = tb.FromIndex(); + for (int i = toIDX; i <= fromIDX; i++) + { + // + // Initialize iBar ... + isDone = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + isDone = + isDone && + iBar.GetPreviousBar(iPBar); + isDone = + isDone && + iPBar.GetPreviousBar(iP2Bar); + isDone = + isDone && + barAnalyser.IsSimpleSwing( + iBar, + iDir // + ) && + iDir == tb.GetDirection(); + if (isDone) + { + // + bool canSet = + !tb.swingBar.IsValid() + ? true + : (isBullish + ? tb.swingBar.low > iP2Bar.low + : tb.swingBar.high < iP2Bar.high); + if (canSet) + { + tb.swingBar = iP2Bar; + } + } + + // + iBar.Clean(); + iPBar.Clean(); + iP2Bar.Clean(); + } + + // + has = tb.swingBar.IsValid(); + } + + // + // Force Has Liquidity ... + // TODO: Add Validation based on Liquidities + // if necessary ... + if (has && + (_forceHasFLiquidity || + _forceHasRLiquidity)) + { + // + toIDX = tb.ToIndex(); + fromIDX = tb.FromIndex(); + for (int i = toIDX; i < fromIDX + loopback; i++) + { + // + // Initialize iBar ... + isDone = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + + // + bool isRejected = + isDone && + barAnalyser.IsRejected( + iBar, + iDir, + false, // Force Bar Type ... + true // Force Fibo Pressure ... + ); + + // + // Following Liquidity ... + bool isFLiq = + isDone && + isRejected && + iDir == tb.GetDirection() && + (isBullish + ? iBar.low < tb.trigger.lower + : iBar.high > tb.trigger.upper); + if (isFLiq && + _forceHasFLiquidity && + !tb.fLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iDir, + tb.fLiquidity, + tb.trigger.to // + ); + } + + // + // Reversal Liquidity ... + bool isRLiq = + isDone && + isRejected && + Opposit(iDir) == tb.GetDirection() && + (isBullish + ? iBar.low > tb.trigger.upper + : iBar.high < tb.trigger.lower); + if (isRLiq && + _forceHasRLiquidity && + !tb.rLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iDir, + tb.rLiquidity, + tb.trigger.to // + ); + } + + // + // Checking Conditions ... + isDone = + (!_forceHasFLiquidity + ? true + : tb.fLiquidity.IsValid()) && + (!_forceHasRLiquidity + ? true + : tb.rLiquidity.IsValid()); + if (isDone) + { + // + iBar.Clean(); + break; + } + + // + iBar.Clean(); + } + + // + // Checking Conditions ... + has = + (!_forceHasFLiquidity + ? true + : tb.fLiquidity.IsValid()) && + (!_forceHasRLiquidity + ? true + : tb.rLiquidity.IsValid()); + } + + // + // Validations ... + + // + // Validating Gap Sequence means + // Gap Bars must Follow each Other ... + if (has && + _validateGapSequence) + { + // + XOHCL iPBar; + toIDX = tb.fvg.ToIndex(); + fromIDX = tb.fvg.FromIndex(); + + // + for (int i = toIDX; i < fromIDX - 1; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + has = + has && + iBar.GetPreviousBar(iPBar); + has = + has && + (isBullish + ? iBar.low > iPBar.low + : iBar.high < iPBar.high); + if (!has) + { + break; + } + } + + // + iBar.Clean(); + iPBar.Clean(); + } + + // + // Validate Block Edge Breakout ... + if (has && + _validateBlockEdgeBreakout) + { + // + has = tb.fvg.ToBar(iBar); + has = + has && + (isBullish + ? (iBar.GetDown() < tb.ob.upper && + iBar.GetUp() > tb.ob.upper) + : (iBar.GetDown() < tb.ob.lower && + iBar.GetUp() > tb.ob.lower)); + + // + iBar.Clean(); + } + + // + // Filters ... + + // + // PV ... + if (has && + _filterBasedOnPV) + { + // + double iPeak = _peakBuffer[barIndex]; + double iPPeak = _peakBuffer[barIndex + 1]; + double iP2Peak = _peakBuffer[barIndex + 2]; + + // + double iPeakGolden = _peakGoldenBuffer[barIndex]; + double iPPeakGolden = _peakGoldenBuffer[barIndex + 1]; + double iP2PeakGolden = _peakGoldenBuffer[barIndex + 2]; + + // + double iVale = _valeBuffer[barIndex]; + double iPVale = _valeBuffer[barIndex + 1]; + double iP2Vale = _valeBuffer[barIndex + 2]; + + // + double iValeGolden = _valeGoldenBuffer[barIndex]; + double iPValeGolden = _valeGoldenBuffer[barIndex + 1]; + double iP2ValeGolden = _valeGoldenBuffer[barIndex + 2]; + + // + has = + has && + (isBullish + ? (tb.trigger.lower <= iVale || + tb.trigger.lower <= iValeGolden) + : (tb.trigger.upper >= iPeak || + tb.trigger.upper >= iPeakGolden)); + } + + // + // SAR ... + if (has && + _filterBasedOnSar) + { + // + double iSarState = _sarStateBuffer[barIndex]; + double iPSarState = _sarStateBuffer[barIndex + 1]; + double iP2SarState = _sarStateBuffer[barIndex + 2]; + + // + bool isSarBullish = iSarState > 0; + bool isPSarBullish = iPSarState > 0; + bool isP2SarBullish = iP2SarState > 0; + + // + bool isSarBearish = iSarState < 0; + bool isPSarBearish = iPSarState < 0; + bool isP2SarBearish = iP2SarState < 0; + + // + bool isSarSwitchedToBullish = + isSarBullish && + !isPSarBullish; + + // + bool isSarSwitchedToBearish = + isSarBearish && + !isPSarBearish; + + // + bool isSarPSwitchedToBullish = + isPSarBullish && + !isP2SarBullish; + + // + bool isSarPSwitchedToBearish = + isPSarBearish && + !isP2SarBearish; + + // + has = + has && + (isBullish + ? (isSarSwitchedToBullish || + isSarPSwitchedToBullish) + : (isSarSwitchedToBearish || + isSarPSwitchedToBearish)); + } + + // + // RSI ... + if (has && + _filterBasedOnRSI) + { + // + double rsiTrend = (_rsiOBLevel + _rsiOSLevel) / 2; + + // + double iRSI = rsiBuffer[barIndex]; + double iPRSI = rsiBuffer[barIndex + 1]; + double iP2RSI = rsiBuffer[barIndex + 2]; + + // + bool isRSICrossedOverOS = + iRSI > rsiOSLevel && + iPRSI <= rsiOSLevel; + + // + bool isRSICrossedUnderOB = + iRSI < rsiOBLevel && + iPRSI >= rsiOBLevel; + + // + bool isPRSICrossedOverOS = + iPRSI > rsiOSLevel && + iP2RSI <= rsiOSLevel; + + // + bool isPRSICrossedUnderOB = + iPRSI < rsiOBLevel && + iP2RSI >= rsiOBLevel; + + // + has = + has && + (isBullish + ? (isRSICrossedOverOS || + isPRSICrossedOverOS) + : (isRSICrossedUnderOB || + isPRSICrossedUnderOB)); + } + + // + // ADX ... + if (has && + _filterBasedOnADX) + { + // + // ADX ... + double iADX = adxBuffer[barIndex]; + double iPADX = adxBuffer[barIndex + 1]; + double iP2ADX = adxBuffer[barIndex + 2]; + + // + // ADX +DI ... + double iADXP = adxpBuffer[barIndex]; + double iPADXP = adxpBuffer[barIndex + 1]; + double iP2ADXP = adxpBuffer[barIndex + 2]; + + // + // ADX -DI ... + double iADXN = adxnBuffer[barIndex]; + double iPADXN = adxnBuffer[barIndex + 1]; + double iP2ADXN = adxnBuffer[barIndex + 2]; + + // + // Preparing Conditions ... + + // + bool isADXBullish = iADX > adxThreshold; + bool isADXBearish = iADX < adxThreshold; + + // + bool isPADXBullish = iPADX > adxThreshold; + bool isPADXBearish = iPADX < adxThreshold; + + // + bool isP2ADXBullish = iP2ADX > adxThreshold; + bool isP2ADXBearish = iP2ADX < adxThreshold; + + // + bool isADXSwitchedToBullish = + isADXBullish && + !isPADXBullish; + + // + bool isADXSwitchedToBearish = + isADXBearish && + !isPADXBearish; + + // + bool isPADXSwitchedToBullish = + isPADXBullish && + !isP2ADXBullish; + + // + bool isPADXSwitchedToBearish = + isPADXBearish && + !isP2ADXBearish; + + // + has = + has && + (isBullish + ? (isADXSwitchedToBullish || + isPADXSwitchedToBullish) + : (isADXSwitchedToBearish || + isPADXSwitchedToBearish)); + } + + // + // ATR ... + if (has && + _filterBasedOnATR) + { + // + fromIDX = tb.FromIndex(); + double iATRUpper = _atrUpperBuffer[fromIDX]; + double iATRLower = _atrLowerBuffer[fromIDX]; + + // + has = + has && + (isBullish + ? tb.trigger.lower < iATRLower + : tb.trigger.upper > iATRUpper); + } + + // + // TREND ... + if (has && + _filterBasedOnTrend) + { + // + double iTrendState = _trendStateBuffer[barIndex]; + double iPTrendState = _trendStateBuffer[barIndex + 1]; + + // + bool isTrendBullish = iTrendState > 0; + bool isPTrendBullish = iPTrendState > 0; + + // + bool isTrendBearish = iTrendState < 0; + bool isPTrendBearish = iPTrendState < 0; + + // + double trends[]; + int toIDX = tb.ToIndex(); + int fromIDX = tb.FromIndex(); + double iTrend = trendBuffer[toIDX]; + for (int i = toIDX; i <= fromIDX; i++) + { + // + Add( + trendBuffer[i], + trends // + ); + } + double trendsMin = GetMin(trends); + double trendsMax = GetMax(trends); + double trendsAVG = GetAverage(trends); + + // + bool isTrendUp = + iTrend > trendsMin && + iTrend >= trendsAVG; + + // + bool isTrendDown = + iTrend < trendsMax && + iTrend <= trendsAVG; + + // + bool isTrendSwitchedToBullish = + isTrendUp && + isTrendBullish && + !isPTrendBullish; + + // + bool isTrendSwitchedToBearish = + isTrendDown && + isTrendBearish && + !isPTrendBearish; + + // + has = + has && + (isBullish + ? isTrendSwitchedToBullish + : isTrendSwitchedToBearish); + } + + // + // DELTA ... + if (has && + _filterBasedOnDelta) + { + // + double iDelta = _deltaBuffer[barIndex]; + double iPDelta = _deltaBuffer[barIndex + 1]; + + // + bool isDeltaUp = iDelta > iPDelta; + bool isDeltaDown = iDelta < iPDelta; + + // + double iDeltaSignal = _deltaSignalBuffer[barIndex]; + double iPDeltaSignal = _deltaSignalBuffer[barIndex + 1]; + + // + bool isDeltaSignalUp = iDeltaSignal > iPDeltaSignal; + bool isDeltaSignalDown = iDeltaSignal < iPDeltaSignal; + + // + bool isDeltaSwitchedToBullish = + isDeltaUp && + isDeltaSignalUp && + iDelta > iDeltaSignal && + iPDelta < iPDeltaSignal; + + // + bool isDeltaSwitchedToBearish = + isDeltaDown && + isDeltaSignalDown && + iDelta < iDeltaSignal && + iPDelta > iPDeltaSignal; + + // + has = + has && + (isBullish + ? isDeltaSwitchedToBullish + : isDeltaSwitchedToBearish); + } + + // + // VOLUME ... + if (has && + _filterBasedOnVolume) + { + // + double iBullishVolumeSignal = _bullishVolumeSignalBuffer[barIndex]; + double iPBullishVolumeSignal = _bullishVolumeSignalBuffer[barIndex + 1]; + + // + bool isBullishVolumeSignalUp = iBullishVolumeSignal > iPBullishVolumeSignal; + bool isBullishVolumeSignalDown = iBullishVolumeSignal < iPBullishVolumeSignal; + + // + double iBearishVolumeSignal = _bearishVolumeSignalBuffer[barIndex]; + double iPBearishVolumeSignal = _bearishVolumeSignalBuffer[barIndex + 1]; + + // + bool isBearishVolumeSignalUp = iBearishVolumeSignal > iPBearishVolumeSignal; + bool isBearishVolumeSignalDown = iBearishVolumeSignal < iPBearishVolumeSignal; + + // + bool isVolumeSwitchdToBullish = + isBullishVolumeSignalUp && + !isBearishVolumeSignalUp && + iBullishVolumeSignal > iBearishVolumeSignal && + iPBullishVolumeSignal < iPBearishVolumeSignal; + + // + bool isVolumeSwitchdToBearish = + isBearishVolumeSignalUp && + !isBullishVolumeSignalUp && + iBearishVolumeSignal > iBullishVolumeSignal && + iPBearishVolumeSignal < iPBullishVolumeSignal; + + // + has = + has && + (isBullish + ? isVolumeSwitchdToBullish + : isVolumeSwitchdToBearish); + } + + // + // SIGNAL Bar ... + if (has && + _filterBasedOnSignalBar) + { + // + double iSignalOpen = _sBarOpenSBuffer[barIndex]; + double iPSignalOpen = _sBarOpenSBuffer[barIndex + 1]; + + // + double iSignalClose = _sBarCloseBuffer[barIndex]; + double iPSignalClose = _sBarCloseBuffer[barIndex + 1]; + + // + bool isSignalBarBullish = iSignalOpen < iSignalClose; + bool isPSignalBarBullish = iPSignalOpen < iPSignalClose; + + // + bool isSignalBarBearish = iSignalOpen > iSignalClose; + bool isPSignalBarBearish = iPSignalOpen > iPSignalClose; + + // + bool isSignalBarSwitchedToBullish = + isSignalBarBullish && + !isPSignalBarBullish; + + // + bool isSignalBarSwitchedToBearish = + isSignalBarBearish && + !isPSignalBarBearish; + + // + has = + has && + (isBullish + ? isSignalBarSwitchedToBullish + : isSignalBarSwitchedToBearish); + } + + // + // HK SIGNAL Bar ... + if (has && + _filterBasedOnHKSignalBar) + { + // + double iHKSignalOpen = _hkSBarOpenBuffer[barIndex]; + double iPHKSignalOpen = _hkSBarOpenBuffer[barIndex + 1]; + + // + double iHKSignalClose = _hkSBarCloseBuffer[barIndex]; + double iPHKSignalClose = _hkSBarCloseBuffer[barIndex + 1]; + + // + bool isHKSignalBarBullish = iHKSignalOpen < iHKSignalClose; + bool isPHKSignalBarBullish = iPHKSignalOpen < iPHKSignalClose; + + // + bool isHKSignalBarBearish = iHKSignalOpen > iHKSignalClose; + bool isPHKSignalBarBearish = iPHKSignalOpen > iPHKSignalClose; + + // + bool isHKSignalBarSwitchedToBullish = + isHKSignalBarBullish && + !isPHKSignalBarBullish; + + // + bool isHKSignalBarSwitchedToBearish = + isHKSignalBarBearish && + !isPHKSignalBarBearish; + + // + has = + has && + (isBullish + ? isHKSignalBarSwitchedToBullish + : isHKSignalBarSwitchedToBearish); + } + + // + // Preparing Signal ... + if (has) + { + // + double targets[]; + for (int i = 1; i <= _r2r; i++) + { + // + Add( + (double)i, + targets // + ); + } + + // + double iATR = atrBuffer[barIndex]; + double slAdditional = _slAtrMultiplier * iATR; + + // + has = ToSignal( + tb.trigger, + tb.signal, + targets, + slAdditional // + ); + } + + // + result = has; + + // + return result; +} + +// +// Draw Specific Trigger Block ... +bool DrawTriggerBlock( + XTriggerBlock &trigger, + XCPOIDrawer *drawer, + CArrayObj &objects, + datetime to = NULL, + int rrZoneLength = 10, + // + // Styles ... + // + // Trigger Block ... + int tbWidth = 1, // Trigger Block Width + color tbBullishColor = clrAqua, // Trigger Block Bullish Color + color tbBearishColor = clrMagenta, // Trigger Block Bearish Color + ENUM_LINE_STYLE tbStyle = STYLE_DASHDOTDOT, // Trigger Block Style + // + // OB ... + int obWidth = 1, // OB Width + color obBullishColor = clrLime, // OB Bullish Color + color obBearishColor = clrRed, // OB Bearish Color + ENUM_LINE_STYLE obStyle = STYLE_DOT, // OB Style + // + // FVG ... + int fvgWidth = 2, // FVG Width + color fvgBullishColor = clrLime, // FVG Bullish Color + color fvgBearishColor = clrRed, // FVG Bearish Color + ENUM_LINE_STYLE fvgStyle = STYLE_SOLID // FVG Style +) +{ + // + bool result = false; + + // + // Validate Args ... + result = trigger.IsValid() && + drawer != NULL; + if (!result) + { + return result; + } + + // + // Update To ... + bool canUpdateTo = IsValid(to); + if (canUpdateTo) + { + // + trigger.trigger.to = to; + trigger.rLiquidity.to = to; + trigger.fLiquidity.to = to; + } + + // + bool isBullish = trigger.IsBullish(); + + // + // Draw OB ... + if (trigger.ob.IsValid()) + { + // + XCBoxObject *iOBObj; + result = drawer.DrawBox( + trigger.ob, + iOBObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? obBullishColor + : obBearishColor; + + // + iOBObj.BoxColor(iClr); + iOBObj.BoxWidth(obWidth); + iOBObj.BoxStyle(obStyle); + + // + // Store Object ... + objects.Add(iOBObj); + } + ZeroMemory(iOBObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw FVG ... + if (trigger.fvg.IsValid()) + { + // + XCBoxObject *iFVGObj; + result = drawer.DrawBox( + trigger.fvg, + iFVGObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? fvgBullishColor + : fvgBearishColor; + + // + iFVGObj.BoxColor(iClr); + iFVGObj.BoxWidth(fvgWidth); + iFVGObj.BoxStyle(fvgStyle); + + // + // Store Object ... + objects.Add(iFVGObj); + } + ZeroMemory(iFVGObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Trigger ... + if (trigger.trigger.IsValid()) + { + // + XCBoxObject *iTriggerObj; + result = drawer.DrawBox( + trigger.trigger, + iTriggerObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? tbBullishColor + : tbBearishColor; + + // + iTriggerObj.BoxColor(iClr); + iTriggerObj.BoxWidth(tbWidth); + iTriggerObj.BoxStyle(tbStyle); + + // + // Store Object ... + objects.Add(iTriggerObj); + } + ZeroMemory(iTriggerObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Liquidities ... + + // + // Reversla Liquidity ... + if (trigger.rLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = drawer.DrawBox( + trigger.rLiquidity, + iLiqObj // + ); + if (result) + { + objects.Add(iLiqObj); + } + ZeroMemory(iLiqObj); + + // + if (!result) + { + return result; + } + } + + // + // Following Liquidity ... + if (trigger.fLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = drawer.DrawBox( + trigger.fLiquidity, + iLiqObj // + ); + if (result) + { + objects.Add(iLiqObj); + } + ZeroMemory(iLiqObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Swing Bar ... + if (trigger.swingBar.IsValid()) + { + // + color swingColor = + trigger.fvg.IsBullish() + ? clrAqua + : clrMagenta; + ENUM_X_PRICE swingPType = + trigger.fvg.IsBullish() + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *swingObj; + result = drawer.CreateBarArrow( + trigger.swingBar, + swingObj, + swingPType, + 159, + swingColor // + ); + if (result) + { + objects.Add(swingObj); + } + ZeroMemory(swingObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw RR of Signal ... + if (trigger.signal.IsValid() && + rrZoneLength > 0) + { + // + XCRRObject *iRRObj; + iRRObj = new XCRRObject(); + result = iRRObj.Create( + drawer.ChartIdentification(), + drawer.SubWindowIdentification(), + trigger.signal, + rrZoneLength // + ); + if (result) + { + // + int iWidth = 2; + ENUM_LINE_STYLE iStyle = STYLE_SOLID; + + // + iRRObj.TPWidth(iWidth); + iRRObj.SLWidth(iWidth); + iRRObj.EntryWidth(iWidth); + iRRObj.TargetWidth(iWidth); + + // + iRRObj.TPStyle(iStyle); + iRRObj.SLStyle(iStyle); + iRRObj.EntryStyle(iStyle); + iRRObj.TargetStyle(iStyle); + + // + iRRObj.TPColor(clrLime); + iRRObj.SLColor(clrRed); + iRRObj.EntryColor(clrYellow); + iRRObj.TargetColor(clrLightBlue); + + // + objects.Add(iRRObj); + } + ZeroMemory(iRRObj); + + // + if (result) + { + return result; + } + } + + // + return result; +}