/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: X121 X3MA // Description: X3MA ... // // // 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 XCZone Indicator" #property strict // // Definitions ... // #define ShortName "X121 XCZone" // // Includes Common Library ... #include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" #include "../Libraries/x-saherelm.x-poi.lib.mq5" // 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; } // }; // // Inputs ... input group "Market"; input ENUM_X_PERIOD_METHOD trendPeriodMethod = X_PERIOD_AUTO; // How to Find Trend Period input ENUM_TIMEFRAMES trendPeriod = NULL; // Trend Time Period input ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode input ENUM_APPLIED_PRICE trendAppliedTo = PRICE_CLOSE; // Trend Applied To input double sarStep = 0.02; // Sar Step input double sarMax = 0.2; // Sar Maximum input int adxLength = 14; // ADX Length input double adxThreshold = 25.0; // ADX Threshold input int rsiLength = 14; // RSI Length 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 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 input ENUM_X_MA_METHOD deltaSignalMethod = X_MA_MODE_EMA; // Delta Signalling Method input int volumeSignalLength = 14; // Volume Signal Length input ENUM_X_MA_METHOD volumeSignalMethod = X_MA_MODE_EMA; // Volume Signalling Method input int hkSignalBarLength = 14; // Hiken Ashi Signal Length input ENUM_X_MA_METHOD hkSignalBarMethod = X_MA_MODE_EMA; // Hiken Ashi Signal Method // // Validating ... input group "Validating"; input bool forceHasSwing = true; // Force Blocks to Have Swing 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 filterBasedOnSar = false; // Filter Based on Sar input bool filterBasedOnRSI = false; // Filter Based on RSI input bool filterBasedOnADX = false; // Filter Based on ADX 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 filterBasedOnTrendBars = false; // Filter Based on Trend Bars input bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar // // Alert ... input group "Alerts"; input string alertPrefix = ""; // 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 showSar = false; // Show Sar input bool showTrend = false; // Show Trend input bool showHKBars = false; // Show Hiken Ashi Bars 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 int startCalculationForLastBars = 1000; // Calculate Last n Bars input int sarArrowCode = 159; // Sar Arrow Code input int rrZoneLength = 7; // Draw Risk Reward Ratio till n Bars input int maxSignalR2R = 4; // Max Allowed Signal R2R input double slAtrMultiplier = 0; // Additional SL ATR Multiplier // // Styling ... // // Trigger Block ... input int tbWidth = 1; // Trigger Block Width input color tbBullishColor = clrAqua; // Trigger Block Bullish Color input color tbBearishColor = clrMagenta; // Trigger Block Bearish Color input ENUM_LINE_STYLE tbStyle = STYLE_DASHDOTDOT; // Trigger Block Style // // OB ... input int obWidth = 1; // OB Width input color obBullishColor = clrLime; // OB Bullish Color input color obBearishColor = clrRed; // OB Bearish Color input ENUM_LINE_STYLE obStyle = STYLE_DOT; // OB Style // // FVG ... input int fvgWidth = 2; // FVG Width input color fvgBullishColor = clrLime; // FVG Bullish Color input color fvgBearishColor = clrRed; // FVG Bearish Color input ENUM_LINE_STYLE fvgStyle = STYLE_SOLID; // FVG Style // // Buffers ... // #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 // #property indicator_chart_window // #property indicator_buffers 32 #property indicator_plots 5 // // Plot Buffers ... // // TREND ... // #define trendBufferIndex 0 #define trendBufferPlotIndex 0 double trendBuffer[]; // #define trendColorBufferIndex 1 double trendColorBuffer[]; // #property indicator_label1 "X121 Trend" #property indicator_type1 DRAW_COLOR_LINE #property indicator_color1 CLR_NONE, clrAqua, clrMagenta, clrGray #property indicator_style1 STYLE_DASH #property indicator_width1 2 // // SAR ... // #define sarBufferIndex 2 #define sarBufferPlotIndex 2 double sarBuffer[]; // #define sarColorBufferIndex 3 double sarColorBuffer[]; // #property indicator_label2 "X121 SAR" #property indicator_type2 DRAW_COLOR_ARROW #property indicator_color2 CLR_NONE, clrAqua, clrMagenta, clrGray #property indicator_width2 2 // // Signal Bar ... // #define openSignalBufferIndex 4 double openSignalBuffer[]; // #define highSignalBufferIndex 5 double highSignalBuffer[]; // #define lowSignalBufferIndex 6 double lowSignalBuffer[]; // #define closeSignalBufferIndex 7 double closeSignalBuffer[]; // #define signalBarColorBufferIndex 8 double signalBarColorBuffer[]; // #define signalBarBufferIndex 2 #property indicator_label3 "X121 XSGB Open;X121 XSGB High;X121 XSGB Low;X121 XSGB Close" #property indicator_type3 DRAW_COLOR_CANDLES #property indicator_color3 CLR_NONE, clrLime, clrRed // // XHK ... // #define openHKBufferIndex 9 double openHKBuffer[]; // #define highHKBufferIndex 10 double highHKBuffer[]; // #define lowHKBufferIndex 11 double lowHKBuffer[]; // #define closeHKBufferIndex 12 double closeHKBuffer[]; // #define barHKColorBufferIndex 13 double barHKColorBuffer[]; // #define barHKBufferIndex 3 #property indicator_label4 "X121 XHK Open;X121 XHK High;X121 XHK Low;X121 XHK Close" #property indicator_type4 DRAW_COLOR_CANDLES #property indicator_color4 CLR_NONE, clrDodgerBlue, clrDarkGoldenrod // // XHK SIGNAL ... // // Open ... #define openHKSignalBufferIndex 14 double openHKSignalBuffer[]; // // High ... #define highHKSignalBufferIndex 15 double highHKSignalBuffer[]; // // Low ... #define lowHKSignalBufferIndex 16 double lowHKSignalBuffer[]; // // Close ... #define closeHKSignalBufferIndex 17 double closeHKSignalBuffer[]; // // Candle Color ... #define barHKSignalColorBufferIndex 18 double barHKSignalColorBuffer[]; // #define barHKSignalBufferIndex 4 #property indicator_label5 "X121 XHKSM Open;X121 XHKSM High;X121 XHKSM Low;X121 XHKSM Close" #property indicator_type5 DRAW_COLOR_CANDLES #property indicator_color5 CLR_NONE, clrAqua, clrMagenta // // Data Buffers ... #define mLastBufferIndex 18 // // TREND State ... // #define trendStateBufferIndex mLastBufferIndex + 1 double trendStateBuffer[]; // // SAR ... // #define sarStateBufferIndex mLastBufferIndex + 2 double sarStateBuffer[]; // // 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[]; // // 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; // XCAlert *alert; double mPoints = 0; CArrayObj mObjects; XCPOIDrawer *drawer; bool mEnableAlerts = false; XCBarAnalyser *barAnalyser; int mTrendPeriodLength = 0; int atrHandler = INVALID_HANDLE; int sarHandler = INVALID_HANDLE; int rsiHandler = INVALID_HANDLE; int adxHandler = INVALID_HANDLE; int trendHandler = INVALID_HANDLE; ENUM_TIMEFRAMES mTrendPeriod = NULL; // // Event Handlers ... /** * Initialize Indicator ... * * @return ( int ) */ int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initialize Indicator Handlers ... // // Configure Alert ... alert = new XCAlert(); mEnableAlerts = _logAlerts || _pushAlerts || _mailAlerts || _terminalAlerts; string mPrefix = ShortName + (!IsValid(alertPrefix) ? "" : "[" + alertPrefix + "]"); alert.SetPrefix(mPrefix); alert.SetLogAlerts(_logAlerts); alert.SetMailAlerts(_mailAlerts); alert.SetPushAlerts(_pushAlerts); alert.SetEnableAlerts(mEnableAlerts); alert.SetTerminalAlerts(_terminalAlerts); // drawer = new XCPOIDrawer(); barAnalyser = new XCBarAnalyser(); // // Initializing TrendPeriod ... int cPeriodSeconds = PeriodSeconds(_Period); if (trendPeriodMethod == X_PERIOD_AUTO) { // // Select Period ... mTrendPeriod = GetCyclePeriod( X_MARKET_CYCLE_HIND, _Period // ); } else { mTrendPeriod = trendPeriod; } if (IsValid(mTrendPeriod)) { mTrendPeriodLength = PeriodSeconds(mTrendPeriod) / cPeriodSeconds; } // // ATR ... atrHandler = iATR( _Symbol, _Period, atrLength // ); bool isInited = atrHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // // SAR ... sarHandler = iSAR( _Symbol, _Period, sarStep, sarMax // ); isInited = sarHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // // RSI ... rsiHandler = iRSI( _Symbol, _Period, rsiLength, rsiAppliedTo // ); isInited = rsiHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // // ADX ... adxHandler = iADX( _Symbol, _Period, adxLength // ); isInited = adxHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // // TREND ... trendHandler = iMA( _Symbol, _Period, mTrendPeriodLength, 0, trendMode, trendAppliedTo // ); isInited = trendHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // mPoints = GetPoints(_Symbol); // // 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(); // ReadBarStyle(); // 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 // mObjects.Clear(); // delete alert; delete drawer; // ZeroMemory(alert); ZeroMemory(drawer); ZeroMemory(barAnalyser); // ShowBars(); // 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 // ); } // return rates_total; } // // Functions ... /** * Validate Input Args for Initialization ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = false; // result = // sarMax > 0 && sarStep > 0 && adxLength > 0 && atrLength > 0 && rsiLength > 0 && rsiOBLevel > 0 && rsiOSLevel > 0 && sarMax > sarStep && barsSignalLength > 2 && deltaSignalLength > 2 && hkSignalBarLength > 2 && volumeSignalLength > 2 && barsSignalMethod != X_MA_MODE_NONE && deltaSignalMethod != X_MA_MODE_NONE && hkSignalBarMethod != X_MA_MODE_NONE && volumeSignalMethod != X_MA_MODE_NONE && IsValid(trendPeriodMethod, trendPeriod) // ; // return result; } /** * Extract Max Length of Inputs ... * * @return ( int ) */ int ExtractMaxLengthOfInputs() { // int result = 0; // result = MathMax(adxLength, rsiLength); result = MathMax(result, barsSignalLength); result = MathMax(result, deltaSignalLength); result = MathMax(result, volumeSignalLength); result = MathMax(result, hkSignalBarLength); // return result; } /** * Define Required Buffers ... */ void DefineBuffers() { // // Plot Buffers ... // // 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); // // 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); // // SIGNAL Bar ... // // Signal Bars Color ... ArraySetAsSeries(signalBarColorBuffer, true); SetIndexBuffer(signalBarColorBufferIndex, signalBarColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on XHK Bar Buffer ... PlotIndexSetDouble(signalBarBufferIndex, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetInteger(signalBarBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(openSignalBuffer, true); SetIndexBuffer(openSignalBufferIndex, openSignalBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(highSignalBuffer, true); SetIndexBuffer(highSignalBufferIndex, highSignalBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(closeSignalBuffer, true); SetIndexBuffer(closeSignalBufferIndex, closeSignalBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(lowSignalBuffer, true); SetIndexBuffer(lowSignalBufferIndex, lowSignalBuffer, INDICATOR_DATA); // // XHK ... // // HK Bars Color ... ArraySetAsSeries(barHKColorBuffer, true); SetIndexBuffer(barHKColorBufferIndex, barHKColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on XHK Bar Buffer ... PlotIndexSetDouble(barHKBufferIndex, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetInteger(barHKBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(openHKBuffer, true); SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(highHKBuffer, true); SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(closeHKBuffer, true); SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(lowHKBuffer, true); SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA); // // XHK SIGNAL ... // // HK Bars Color ... ArraySetAsSeries(barHKSignalColorBuffer, true); SetIndexBuffer(barHKSignalColorBufferIndex, barHKSignalColorBuffer, INDICATOR_COLOR_INDEX); // // Set EMPTY_VALUE on XHK Bar Buffer ... PlotIndexSetDouble(barHKSignalBufferIndex, PLOT_EMPTY_VALUE, 0.0); PlotIndexSetInteger(barHKSignalBufferIndex, PLOT_SHOW_DATA, false); // // Open ... ArraySetAsSeries(openHKSignalBuffer, true); SetIndexBuffer(openHKSignalBufferIndex, openHKSignalBuffer, INDICATOR_DATA); // // High ... ArraySetAsSeries(highHKSignalBuffer, true); SetIndexBuffer(highHKSignalBufferIndex, highHKSignalBuffer, INDICATOR_DATA); // // Close ... ArraySetAsSeries(closeHKSignalBuffer, true); SetIndexBuffer(closeHKSignalBufferIndex, closeHKSignalBuffer, INDICATOR_DATA); // // Low ... ArraySetAsSeries(lowHKSignalBuffer, true); SetIndexBuffer(lowHKSignalBufferIndex, lowHKSignalBuffer, INDICATOR_DATA); // // Data Buffers ... // ArraySetAsSeries(trendStateBuffer, true); SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(sarStateBuffer, true); SetIndexBuffer(sarStateBufferIndex, sarStateBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(rsiBuffer, true); SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); // 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); } /** * Set Indicator Short Name and also we can define Buffers Labels ... */ void SetIndicatorName() { // IndicatorSetInteger(INDICATOR_DIGITS, _Digits); IndicatorSetString(INDICATOR_SHORTNAME, ShortName); } /** * 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; if (barsLimit == 0) { // barsLimit = ratesTotal; firstBarIndex = barsLimit - 1; } else { // firstBarIndex = startCalculationForLastBars; } // // bool canCalculate = true; bool canCalculate = bar_index <= barsLimit; if (canCalculate) { // // Calculate Values ... CalculateValues( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume // ); } else { FillBuffersZero(bar_index); } } /** * Fill All Bufers to Zero Vlue for Specified Bar Index ... * * @param barIndex: Integer ... */ void FillBuffersZero(int bar_index) { // sarColorBuffer[bar_index] = hideColorIDX; trendColorBuffer[bar_index] = hideColorIDX; } /** * Calculate Values ... * * @param bar_index: 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 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 lastBarIndex = bar_index + 1; bool isFirstBar = startCalculationForLastBars > 0 ? bar_index == startCalculationForLastBars : bar_index == firstBarIndex; // // Bar Info ... double iLow = high[bar_index]; double iHigh = high[bar_index]; double iClose = close[bar_index]; double iOpen = open[bar_index]; double iVolume = (double)iVolume(_Symbol, _Period, bar_index); // bool isBullish = iClose > iOpen; bool isBearish = iClose < iOpen; // double points = GetPoints(_Symbol); // // Calculate Sar Color Buffer ... double iSar = sarBuffer[bar_index]; // double iSarState = neuturalState; double iSarColor = neuturalColorIDX; if (iLow > iSar) { // iSarState = bullishState; iSarColor = !showSar ? hideColorIDX : bullishColorIDX; } else if (iHigh < iSar) { // iSarState = bearishState; iSarColor = !showSar ? hideColorIDX : bearishColorIDX; } sarStateBuffer[bar_index] = iSarState; sarColorBuffer[bar_index] = iSarColor; // // Calculate Trend Color Buffer ... double iTrend = trendBuffer[bar_index]; // double iTrendState = neuturalState; double iTrendColor = neuturalColorIDX; if (iClose > iTrend) { // iTrendState = bullishState; iTrendColor = !showTrend ? hideColorIDX : bullishColorIDX; } else if (iClose < iTrend) { // iTrendState = bearishState; iTrendColor = !showTrend ? hideColorIDX : bearishColorIDX; } trendStateBuffer[bar_index] = iTrendState; trendColorBuffer[bar_index] = iTrendColor; // // DELTA ... double lastDelta = isFirstBar ? emptyValue : deltaBuffer[lastBarIndex]; double iAppliedVolume = isBullish ? iVolume : -1 * iVolume; double iDelta = lastDelta + iAppliedVolume; deltaBuffer[bar_index] = iDelta; // // Calculate Delta Signal ... int deltaSignalsCount = iMAOnBuffer( ratesTotal, prevCalculated, bar_index, deltaSignalLength, deltaBuffer, deltaSignalBuffer, deltaSignalMethod // ); // // VOLUME ... // 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[bar_index] = iBullishVolume; bearishVolumeBuffer[bar_index] = iBearishVolume; // // Calculate Volume Signals ... // int bullishVolumeSignalsCount = iMAOnBuffer( ratesTotal, prevCalculated, bar_index, volumeSignalLength, bullishVolumeBuffer, bullishVolumeSignalBuffer, volumeSignalMethod // ); // int bearishVolumeSignalsCount = iMAOnBuffer( ratesTotal, prevCalculated, bar_index, volumeSignalLength, bearishVolumeBuffer, bearishVolumeSignalBuffer, volumeSignalMethod // ); // // SIGNAL Bar ... // // Open ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, barsSignalLength, open, openSignalBuffer, barsSignalMethod // ); // // Close ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, barsSignalLength, close, closeSignalBuffer, barsSignalMethod // ); // double min = MathMin(closeSignalBuffer[bar_index], openSignalBuffer[bar_index]); double max = MathMin(closeSignalBuffer[bar_index], openSignalBuffer[bar_index]); // lowSignalBuffer[bar_index] = min; highSignalBuffer[bar_index] = max; // // Calculate HK Signal Color ... double iSignalColorValue = openSignalBuffer[bar_index] < closeSignalBuffer[bar_index] ? bullishColorIDX : bearishColorIDX; signalBarColorBuffer[bar_index] = showSignalBars ? iSignalColorValue : hideColorIDX; // // XHK ... // double lastHKOpen = isFirstBar ? emptyValue : openHKBuffer[lastBarIndex]; double lastHKClose = isFirstBar ? emptyValue : closeHKBuffer[lastBarIndex]; // double iHKOpenValue = (lastHKOpen + lastHKClose) / 2; double iHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; double iHKHighValue = MathMax(high[bar_index], MathMax(iHKOpenValue, iHKCloseValue)); double iHKLowValue = MathMin(low[bar_index], MathMin(iHKOpenValue, iHKCloseValue)); // double iHKColorValue = iHKOpenValue < iHKCloseValue ? bullishColorIDX : bearishColorIDX; // // Raw HK Buffers ... openHKBuffer[bar_index] = iHKOpenValue; highHKBuffer[bar_index] = iHKHighValue; lowHKBuffer[bar_index] = iHKLowValue; closeHKBuffer[bar_index] = iHKCloseValue; barHKColorBuffer[bar_index] = showHKBars ? iHKColorValue : hideColorIDX; // // XHK Signal ... // // Open ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, hkSignalBarLength, openHKBuffer, openHKSignalBuffer, hkSignalBarMethod // ); // // Close ... iMAOnBuffer( ratesTotal, prevCalculated, bar_index, hkSignalBarLength, closeHKBuffer, closeHKSignalBuffer, hkSignalBarMethod // ); // min = MathMin(closeHKSignalBuffer[bar_index], openHKSignalBuffer[bar_index]); max = MathMin(closeHKSignalBuffer[bar_index], openHKSignalBuffer[bar_index]); // lowHKSignalBuffer[bar_index] = min; highHKSignalBuffer[bar_index] = max; // // Calculate HK Signal Color ... double iHKSignalColorValue = openHKSignalBuffer[bar_index] < closeHKSignalBuffer[bar_index] ? bullishColorIDX : bearishColorIDX; barHKSignalColorBuffer[bar_index] = showHKSignalBars ? iHKSignalColorValue : hideColorIDX; // DetectTriggerBlock( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume // ); } /** * Detect Trigger Block ... * * @param bar_index: 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 DetectTriggerBlock( 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 lastBarIndex = bar_index + 1; int maxBarIndex = startCalculationForLastBars > 0 ? startCalculationForLastBars : ratesTotal; bool isFirstBar = bar_index == maxBarIndex; // // Prevent Calculation ... if (maxBarIndex - bar_index < maxLength) { return; } // 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, bar_index // ); // // Detect Trend Bar ... XOHCL zTrendBar; int zTrendIDX = iBarShift( _Symbol, mTrendPeriod, zBar.time // ); has = has && zTrendBar.Init( _Symbol, mTrendPeriod, zTrendIDX + 1 // ); // // Define Zone Structure ... XTriggerBlock tb; // bool validateObBarType = true; bool validateFVGBarType = true; // // Detect Based Order Block ... has = has && barAnalyser.IsOB( zBar, tb.ob, validateFVGBarType, // Force FVG Bar Type ... validateObBarType // Force Block Two Bar Checking ... ); // // Detect Based Fair Value Gap ... has = has && barAnalyser.IsFVG( zBar, tb.fvg, validateFVGBarType // 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) { // 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 && barAnalyser.IsSimpleSwing( iBar, iDir // ) && iDir == tb.GetDirection(); if (isDone) { // bool canSet = !tb.swingBar.IsValid() ? true : (isBullish ? tb.swingBar.low > iBar.low : tb.swingBar.high < iBar.high); if (canSet) { tb.swingBar = iBar; } } // iBar.Clean(); } // has = tb.swingBar.IsValid(); } // // Force Has Liquidity ... 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 ... // // DELTA ... if (has && filterBasedOnDelta) { // double iDelta = deltaBuffer[bar_index]; double iPDelta = deltaBuffer[lastBarIndex]; // bool isDeltaUp = iDelta > iPDelta; bool isDeltaDown = iDelta < iPDelta; // double iDeltaSignal = deltaSignalBuffer[bar_index]; double iPDeltaSignal = deltaSignalBuffer[lastBarIndex]; // 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[bar_index]; double iPBullishVolumeSignal = bullishVolumeSignalBuffer[lastBarIndex]; // bool isBullishVolumeSignalUp = iBullishVolumeSignal > iPBullishVolumeSignal; bool isBullishVolumeSignalDown = iBullishVolumeSignal < iPBullishVolumeSignal; // double iBearishVolumeSignal = bearishVolumeSignalBuffer[bar_index]; double iPBearishVolumeSignal = bearishVolumeSignalBuffer[lastBarIndex]; // 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 = openSignalBuffer[bar_index]; double iPSignalOpen = openSignalBuffer[lastBarIndex]; // double iSignalClose = closeSignalBuffer[bar_index]; double iPSignalClose = closeSignalBuffer[lastBarIndex]; // 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 = openHKSignalBuffer[bar_index]; double iPHKSignalOpen = openHKSignalBuffer[lastBarIndex]; // double iHKSignalClose = closeHKSignalBuffer[bar_index]; double iPHKSignalClose = closeHKSignalBuffer[lastBarIndex]; // 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); } // // SAR ... if (has && filterBasedOnSar) { // double iSarState = sarStateBuffer[bar_index]; double iPSarState = sarStateBuffer[lastBarIndex]; double iP2SarState = sarStateBuffer[lastBarIndex + 1]; // 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)); } // // TREND ... if (has && filterBasedOnTrend) { // double iTrendState = trendStateBuffer[bar_index]; double iPTrendState = trendStateBuffer[lastBarIndex]; // 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); } // // TREND Bars ... if (has && zTrendBar.IsValid() && filterBasedOnTrendBars) { // // Calculate Trend Bar's Midd Range ... double mid = zTrendBar.low + ((zTrendBar.high - zTrendBar.low) / 2); // // Check zBar Close based on MID ... has = has && (isBullish ? zBar.close < mid : zBar.close > mid); // // Check Trigger Block ... has = has && (isBullish ? tb.trigger.lower < zTrendBar.GetDown() : tb.trigger.upper > zTrendBar.GetUp()); } // // RSI ... if (has && filterBasedOnRSI) { // double rsiTrend = (rsiOBLevel + rsiOSLevel) / 2; // double iRSI = rsiBuffer[bar_index]; double iPRSI = rsiBuffer[lastBarIndex]; double iP2RSI = rsiBuffer[lastBarIndex + 1]; // 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[bar_index]; double iPADX = adxBuffer[lastBarIndex]; double iP2ADX = adxBuffer[lastBarIndex + 1]; // // ADX +DI ... double iADXP = adxpBuffer[bar_index]; double iPADXP = adxpBuffer[lastBarIndex]; double iP2ADXP = adxpBuffer[lastBarIndex + 1]; // // ADX -DI ... double iADXN = adxnBuffer[bar_index]; double iPADXN = adxnBuffer[lastBarIndex]; double iP2ADXN = adxnBuffer[lastBarIndex + 1]; // // 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)); } // // SIGNAL ... if (has && (drawSignals && maxSignalR2R > 0)) { // double targets[]; for (int i = 1; i <= maxSignalR2R; i++) { // Add( (double)i, targets // ); } // double iATR = atrBuffer[bar_index]; double slAdditional = slAtrMultiplier * iATR; // has = ToSignal( tb.trigger, tb.signal, targets, slAdditional // ); } // // Handle Draw ... // // Draw Trend Bar ... if (has && showTrendBars) { // XCOHCLObject *iObj; isDone = drawer.CreateBar( zTrendBar, iObj, zBar.time // ); if (isDone) { // // Style Object ... // // Store Object ... mObjects.Add(iObj); } } // // Draw Trigger Block ... if (has && drawZones) { DrawTB(tb); } // // Handle Alerst ... bool canAlert = mEnableAlerts && prevCalculated > 0; bool canLogOnly = mEnableAlerts && prevCalculated == 0; if (has && (canAlert || canLogOnly)) { // string message = tb.trigger.symbol + "," + ToString(tb.trigger.period) + "> " + ToString(tb.trigger.dir) + " Zone Detected at: " + ToString(tb.trigger.to); // if (canLogOnly) { alert.LogAlert(message); } else if (canAlert) { alert.Alert(message); } } // // Cleanup Resources ... // tb.Clean(); zBar.Clean(); iBar.Clean(); zTrendBar.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); } // // Draw Specific Trigger Block ... bool DrawTB( XTriggerBlock &trigger, datetime to = NULL // ) { // bool result = false; // // Validate Args ... result = trigger.IsValid(); 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 ... mObjects.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 ... mObjects.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 ... mObjects.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) { mObjects.Add(iLiqObj); } ZeroMemory(iLiqObj); // if (!result) { return result; } } // // Following Liquidity ... if (trigger.fLiquidity.IsValid()) { // XCBoxObject *iLiqObj; result = drawer.DrawBox( trigger.fLiquidity, iLiqObj // ); if (result) { mObjects.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) { mObjects.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); // mObjects.Add(iRRObj); } ZeroMemory(iRRObj); // if (result) { return result; } } // return result; } //