/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: X121 // Description: Peaks and Vales ... // // // 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 Indicator" #property strict // // Definitions ... // #define ShortName "X121" // // Includes Common Library ... #include "../Classes/x-saherelm.x-poi.class.mq5" #include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // // Inputs ... // input group "Makret Cycles"; // input group "Short"; input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period // input group "Medium"; input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period // input group "Long"; input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period // input group "Hind"; input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period // input group "Boundary Detection Modes"; input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method // input group "Paraboli Sar Detection"; input double sarStep = 0.02; // Step input double sarMax = 0.2; // Maximum // input group "VWap Detection"; input int vwapFastLength = 20; // Fast Length input int vwapMidLength = 40; // Mid Length input int vwapSlowLength = 60; // Slow Length input ENUM_APPLIED_PRICE vwapAppliedTo = PRICE_CLOSE; // Applied To // input group "Donchain Detection"; input int donchainLength = 40; // Donchain Length // input group "POI Detector"; input int poiRequiredItems = 20; // Required POI Detects On Start input int poiMaxItems = 20; // Max POI Detects Holding input ENUM_X_MARKET_CYCLES poiCycle = X_MARKET_CYCLE_UNKNOWN; // POI Detector Cycle // input group "Presentation"; // input int startCalculationForLastBars = 1000; // Calculate Last n Bars // input int sarArrowCode = 159; // Parabolic Sar Arrow Code input int peaksArrowCode = 159; // Peaks Arrow Code input int valesArrowCode = 159; // Vales Arrow Code // input bool showSar = true; // Show Parabolic Sar input bool showPeaks = true; // Show Peaks input bool showVales = true; // Show Vales input bool showVWap = true; // Show VWap input bool showDonchain = true; // Show Donchain input bool showPOIs = false; // Show POIs // input group "VWap Presentation"; input bool showVWapFast = false; // Show VWap Fast input bool showVWapMedium = false; // Show VWap Medium input bool showVWapSlow = false; // Show VWap Slow // input group "Donchain Presentation"; input bool showUpper = true; // Show Upper Band input bool showLower = true; // Show Lower Band input bool showOpen = true; // Show Open input bool showHigh = false; // Show High input bool showClose = true; // Show Close input bool showLow = false; // Show Low // // Define Variables to Draw POI(s) ... input group "POI Presentation"; input bool drawSwingHighs = false; // Draw Swing Highs input bool drawSwingLows = false; // Draw Swing Lows input bool drawSupportZones = false; // Draw Support Zones input bool drawResistanceZones = false; // Draw Resistance Zones input bool drawSupplyZones = false; // Draw Supply Zones input bool drawDemandZones = false; // Draw Demand Zones input bool drawBullishOrderBlocks = false; // Draw Bullish Order Blocks input bool drawBearishOrderBlocks = false; // Draw Bearish Order Blocks input bool drawBullishFairValueGaps = false; // Draw Bullish FairValue Gaps input bool drawBearishFairValueGaps = false; // Draw Bearish FairValue Gaps input bool drawBullishRejectionBars = false; // Draw Bullish Rejection Bars input bool drawBearishRejectionBars = false; // Draw Bearish Rejection Bars input bool drawBullishMomentumBars = false; // Draw Bullish Momentum Bars input bool drawBearishMomentumBars = false; // Draw Bearish Momentum Bars // // Buffers ... // #define hideColorIDX 0 #define bullishColorIDX 1 #define bearishColorIDX 2 #define neuturalColorIDX 3 // #property indicator_chart_window // #property indicator_buffers 34 #property indicator_plots 14 // // PEAKS ... // #define peaksBufferIndex 0 double peaksBuffer[]; // #property indicator_label1 "X121 PEAKS" #property indicator_type1 DRAW_ARROW #property indicator_color1 clrAqua #property indicator_width1 1 // // VALES ... // #define valesBufferIndex 1 double valesBuffer[]; // #property indicator_label2 "X121 VALES" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrMagenta #property indicator_width2 1 // #define sarBufferIndex 2 double sarBuffer[]; // #property indicator_label3 "X121 SAR" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrYellow #property indicator_width3 1 // // FAST ... #define vwapFastBufferIndex 3 double vwapFastBuffer[]; #define vwapFastColorBufferIndex 4 double vwapFastColorBuffer[]; // #define vwapFastPlotBufferIndex 3 #property indicator_label4 "X121 VWF" #property indicator_type4 DRAW_COLOR_LINE #property indicator_color4 CLR_NONE, clrAqua, clrMagenta, clrGray #property indicator_style4 STYLE_SOLID #property indicator_width4 2 // // MID ... #define vwapMidBufferIndex 5 double vwapMidBuffer[]; #define vwapMidColorBufferIndex 6 double vwapMidColorBuffer[]; // #define vwapMidPlotBufferIndex 4 #property indicator_label5 "X121 VWM" #property indicator_type5 DRAW_COLOR_LINE #property indicator_color5 CLR_NONE, clrGreen, clrRed, clrGray #property indicator_style5 STYLE_SOLID #property indicator_width5 2 // // SLOW ... #define vwapSlowBufferIndex 7 double vwapSlowBuffer[]; #define vwapSlowColorBufferIndex 8 double vwapSlowColorBuffer[]; // #define vwapSlowPlotBufferIndex 5 #property indicator_label6 "X121 VWS" #property indicator_type6 DRAW_COLOR_LINE #property indicator_color6 CLR_NONE, clrSteelBlue, clrDarkRed, clrGray #property indicator_style6 STYLE_SOLID #property indicator_width6 2 // // XDON ... // // Open ... // #define donOpenUpperBufferIndex 9 double donOpenUpperBuffer[]; // #define donOpenUpperPlotBufferIndex 6 #property indicator_label7 "X121 O U" #property indicator_type7 DRAW_LINE #property indicator_color7 clrCornflowerBlue #property indicator_width7 1 // #define donOpenLowerBufferIndex 10 double donOpenLowerBuffer[]; // #define donOpenLowerPlotBufferIndex 7 #property indicator_label8 "X121 O L" #property indicator_type8 DRAW_LINE #property indicator_color8 clrCornflowerBlue #property indicator_width8 1 // // High ... // #define donHighUpperBufferIndex 11 double donHighUpperBuffer[]; // #define donHighUpperPlotBufferIndex 8 #property indicator_label9 "X121 H U" #property indicator_type9 DRAW_LINE #property indicator_color9 clrAquamarine #property indicator_width9 1 // #define donHighLowerBufferIndex 12 double donHighLowerBuffer[]; // #define donHighLowerPlotBufferIndex 9 #property indicator_label10 "X121 H L" #property indicator_type10 DRAW_LINE #property indicator_color10 clrAquamarine #property indicator_width10 1 // // Low ... // #define donLowUpperBufferIndex 13 double donLowUpperBuffer[]; // #define donLowUpperPlotBufferIndex 10 #property indicator_label11 "X121 L U" #property indicator_type11 DRAW_LINE #property indicator_color11 clrDarkOrchid #property indicator_width11 1 // #define donLowLowerBufferIndex 14 double donLowLowerBuffer[]; // #define donLowLowerPlotBufferIndex 11 #property indicator_label12 "X121 L L" #property indicator_type12 DRAW_LINE #property indicator_color12 clrDarkOrchid #property indicator_width12 1 // // Close ... // #define donCloseUpperBufferIndex 15 double donCloseUpperBuffer[]; // #define donCloseUpperPlotBufferIndex 12 #property indicator_label13 "X121 C U" #property indicator_type13 DRAW_LINE #property indicator_color13 clrCoral #property indicator_width13 1 // #define donCloseLowerBufferIndex 16 double donCloseLowerBuffer[]; // #define donCloseLowerPlotBufferIndex 13 #property indicator_label14 "X121 C L" #property indicator_type14 DRAW_LINE #property indicator_color14 clrCoral #property indicator_width14 1 // // Data Buffers ... // int mLastBufferIndex = 16; // // CURRENT ... // #define cHHBufferIndex mLastBufferIndex + 1 double cHHBuffer[]; // #define cLLBufferIndex mLastBufferIndex + 2 double cLLBuffer[]; // // SHORT ... // #define sHHBufferIndex mLastBufferIndex + 3 double sHHBuffer[]; // #define sLLBufferIndex mLastBufferIndex + 4 double sLLBuffer[]; // // MEDIUM ... // #define mHHBufferIndex mLastBufferIndex + 5 double mHHBuffer[]; // #define mLLBufferIndex mLastBufferIndex + 6 double mLLBuffer[]; // // LONG ... // #define lHHBufferIndex mLastBufferIndex + 7 double lHHBuffer[]; // #define lLLBufferIndex mLastBufferIndex + 8 double lLLBuffer[]; // // HIND ... // #define hHHBufferIndex mLastBufferIndex + 9 double hHHBuffer[]; // #define hLLBufferIndex mLastBufferIndex + 10 double hLLBuffer[]; // // VOLUME ... #define vwapVolumeBufferIndex mLastBufferIndex + 11 double vwapVolumeBuffer[]; // // Price ... #define vwapPriceBufferIndex mLastBufferIndex + 12 double vwapPriceBuffer[]; // // Fast State ... #define vwapFastStateBufferIndex mLastBufferIndex + 13 double vwapFastStateBuffer[]; // // Mid State ... #define vwapMidStateBufferIndex mLastBufferIndex + 14 double vwapMidStateBuffer[]; // // Slow State ... #define vwapSlowStateBufferIndex mLastBufferIndex + 15 double vwapSlowStateBuffer[]; // // Valid Peaks and Vales ... #define validPeaksBufferIndex mLastBufferIndex + 16 double validPeaksBuffer[]; #define validValesBufferIndex mLastBufferIndex + 17 double validValesBuffer[]; // // Variables, Properties and etc ... // // this counts Available Bars ... int limit; // int maxLength; // // SAR Handler ... int sarHandler = INVALID_HANDLE; // double mHideColorIDX = 0; // // 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; // // XPOI ... XCPOIDrawer *mPOIDrawer; CArrayObj mDrawnObjects; XCPOIDetector *mPOIDetector; // // Event Handlers ... /** * Initialize Indicator ... * * @return ( int ) */ int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initialize Indicator Handlers ... // // SAR ... sarHandler = iSAR( _Symbol, _Period, sarStep, sarMax // ); bool isInited = sarHandler != INVALID_HANDLE; if (!isInited) { return INIT_FAILED; } // // XPOI Drawer ... mPOIDrawer = new XCPOIDrawer(); // // Initialize POI Detector ... int mPoiMaxItems = poiMaxItems > 0 ? poiMaxItems : 5; int mPoiRequiredItems = poiRequiredItems > 0 ? poiRequiredItems : 5; // ENUM_TIMEFRAMES mPOIPeriod = NULL; switch (poiCycle) { // case X_MARKET_CYCLE_UNKNOWN: mPOIPeriod = _Period; break; // case X_MARKET_CYCLE_SHORT: mPOIPeriod = mSCPeriod; break; // case X_MARKET_CYCLE_MEDIUM: mPOIPeriod = mMCPeriod; break; // case X_MARKET_CYCLE_LONG: mPOIPeriod = mLCPeriod; break; // case X_MARKET_CYCLE_HIND: mPOIPeriod = mHCPeriod; break; } mPOIPeriod = NormalizePeriod(mPOIPeriod); mPOIDetector = new XCPOIDetector( _Symbol, mPOIPeriod // ); mPOIDetector.MaxNumberOfPOIs(mPoiMaxItems); mPOIDetector.MaxNumberOfRequiredPOIs(mPoiRequiredItems); mPOIDetector.Init(); // if (!InitMarketCycles()) { return INIT_PARAMETERS_INCORRECT; } // // because in some cases we may have more than one input for // calculation and we must prevent any calculation // untill we pass the biggest input length, here we get max Input length // and then wait until pass it ... maxLength = ExtractMaxLengthOfInputs(); // // Define Index Buffers ... DefineBuffers(); // // Set Indicator ShortName ... SetIndicatorName(); // // 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 // delete mPOIDrawer; delete mPOIDetector; // mDrawnObjects.Clear(); // IndicatorRelease(sarHandler); } /** * 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); // // Fill All Buffers by Zero ... if (prev_calculated == 0) { // ArrayInitialize(peaksBuffer, 0); ArrayInitialize(valesBuffer, 0); ArrayInitialize(sarBuffer, 0); } // // Validate Calculated Bars ... // // SAR ... int sarCalculatedBars = BarsCalculated(sarHandler); // bool isPassedRequiredCalculatedBars = // // SAR ... sarCalculatedBars >= maxLength // ; if (!isPassedRequiredCalculatedBars) { return prev_calculated; } // limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; // // Buffers Copy ... // // SAR ... int copiedSars = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); // // Validate Copied Items ... bool isPassedRequiredCopiedItems = // // // SAR ... copiedSars > 0 // ; if (!isPassedRequiredCopiedItems) { return prev_calculated; } // // Main Loop ... for (int i = limit - 1; i >= 0 && !IsStopped(); i--) { // CalculateBuffers( i, prev_calculated, rates_total, // open, high, close, low, tick_volume // ); } // return rates_total; } // // Functions ... /** * Validate Input Args for Initialization ... * * @return ( bool ) */ bool ValidateInputs() { // bool result = // // PSAR ... sarMax > 0 && sarStep > 0 && sarMax > sarStep && // // XDON ... donchainLength > 0 && // // VWAP ... vwapFastLength > 2 && vwapMidLength > vwapFastLength && vwapSlowLength > vwapMidLength && // // XPV ... (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; // // XPV ... result = MathMax(mSCLength, mMCLength); result = MathMax(result, mLCLength); result = MathMax(result, mHCLength); // // XVWAP ... result = MathMax(result, vwapFastLength); result = MathMax(result, vwapMidLength); result = MathMax(result, vwapSlowLength); // return result; } /** * Define Required Buffers ... */ void DefineBuffers() { // // PEAKS ... // ENUM_DRAW_TYPE peaksDrawType = showPeaks ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(peaksBuffer, true); SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); // PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaks); PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, peaksDrawType); // PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, peaksArrowCode); // // VALES ... // ENUM_DRAW_TYPE valesDrawType = showVales ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(valesBuffer, true); SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); // PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showVales); PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, valesDrawType); // PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, valesArrowCode); // // SAR ... // ENUM_DRAW_TYPE sarDrawType = showSar ? DRAW_ARROW : DRAW_NONE; // ArraySetAsSeries(sarBuffer, true); SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); // PlotIndexSetInteger(sarBufferIndex, PLOT_SHOW_DATA, showSar); PlotIndexSetInteger(sarBufferIndex, PLOT_DRAW_TYPE, sarDrawType); // PlotIndexSetDouble(sarBufferIndex, PLOT_EMPTY_VALUE, 0); PlotIndexSetInteger(sarBufferIndex, PLOT_ARROW, sarArrowCode); // // XVWAP ... // // Fast ... ArraySetAsSeries(vwapFastBuffer, true); ArraySetAsSeries(vwapFastColorBuffer, true); SetIndexBuffer(vwapFastBufferIndex, vwapFastBuffer, INDICATOR_DATA); SetIndexBuffer(vwapFastColorBufferIndex, vwapFastColorBuffer, INDICATOR_COLOR_INDEX); // // Mid ... ArraySetAsSeries(vwapMidBuffer, true); ArraySetAsSeries(vwapMidColorBuffer, true); SetIndexBuffer(vwapMidBufferIndex, vwapMidBuffer, INDICATOR_DATA); SetIndexBuffer(vwapMidColorBufferIndex, vwapMidColorBuffer, INDICATOR_COLOR_INDEX); // // Slow ... ArraySetAsSeries(vwapSlowBuffer, true); ArraySetAsSeries(vwapSlowColorBuffer, true); SetIndexBuffer(vwapSlowBufferIndex, vwapSlowBuffer, INDICATOR_DATA); SetIndexBuffer(vwapSlowColorBufferIndex, vwapSlowColorBuffer, INDICATOR_COLOR_INDEX); // // XDON ... // // Open ... // // UPPER ... bool canShowCOpenUpper = showDonchain && showUpper && showOpen; ENUM_DRAW_TYPE donOpenUpperDrawType = canShowCOpenUpper ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donOpenUpperBuffer, true); SetIndexBuffer(donOpenUpperBufferIndex, donOpenUpperBuffer, INDICATOR_DATA); PlotIndexSetDouble(donOpenUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donOpenUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCOpenUpper); PlotIndexSetInteger(donOpenUpperPlotBufferIndex, PLOT_DRAW_TYPE, donOpenUpperDrawType); // // LOWER ... bool canShowCOpenLower = showDonchain && showLower && showOpen; ENUM_DRAW_TYPE donOpenLowerDrawType = canShowCOpenLower ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donOpenLowerBuffer, true); SetIndexBuffer(donOpenLowerBufferIndex, donOpenLowerBuffer, INDICATOR_DATA); PlotIndexSetDouble(donOpenLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donOpenLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCOpenLower); PlotIndexSetInteger(donOpenLowerPlotBufferIndex, PLOT_DRAW_TYPE, donOpenLowerDrawType); // // Close ... // // UPPER ... bool canShowCCloseUpper = showDonchain && showUpper && showClose; ENUM_DRAW_TYPE donCloseUpperDrawType = canShowCCloseUpper ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donCloseUpperBuffer, true); SetIndexBuffer(donCloseUpperBufferIndex, donCloseUpperBuffer, INDICATOR_DATA); PlotIndexSetDouble(donCloseUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donCloseUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCCloseUpper); PlotIndexSetInteger(donCloseUpperPlotBufferIndex, PLOT_DRAW_TYPE, donCloseUpperDrawType); // // LOWER ... bool canShowCCloseLower = showDonchain && showLower && showClose; ENUM_DRAW_TYPE donCloseLowerDrawType = canShowCCloseLower ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donCloseLowerBuffer, true); SetIndexBuffer(donCloseLowerBufferIndex, donCloseLowerBuffer, INDICATOR_DATA); PlotIndexSetDouble(donCloseLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donCloseLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCCloseLower); PlotIndexSetInteger(donCloseLowerPlotBufferIndex, PLOT_DRAW_TYPE, donCloseLowerDrawType); // // High ... // // UPPER ... bool canShowCHighUpper = showDonchain && showUpper && showHigh; ENUM_DRAW_TYPE donHighUpperDrawType = canShowCHighUpper ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donHighUpperBuffer, true); SetIndexBuffer(donHighUpperBufferIndex, donHighUpperBuffer, INDICATOR_DATA); PlotIndexSetDouble(donHighUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donHighUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCHighUpper); PlotIndexSetInteger(donHighUpperPlotBufferIndex, PLOT_DRAW_TYPE, donHighUpperDrawType); // // LOWER ... bool canShowCHighLower = showDonchain && showLower && showHigh; ENUM_DRAW_TYPE donHighLowerDrawType = canShowCHighLower ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donHighLowerBuffer, true); SetIndexBuffer(donHighLowerBufferIndex, donHighLowerBuffer, INDICATOR_DATA); PlotIndexSetDouble(donHighLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donHighLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCHighLower); PlotIndexSetInteger(donHighLowerPlotBufferIndex, PLOT_DRAW_TYPE, donHighLowerDrawType); // // Low ... // // UPPER ... bool canShowCLowUpper = showDonchain && showUpper && showLow; ENUM_DRAW_TYPE donLowUpperDrawType = canShowCLowUpper ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donLowUpperBuffer, true); SetIndexBuffer(donLowUpperBufferIndex, donLowUpperBuffer, INDICATOR_DATA); PlotIndexSetDouble(donLowUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donLowUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCLowUpper); PlotIndexSetInteger(donLowUpperPlotBufferIndex, PLOT_DRAW_TYPE, donLowUpperDrawType); // // LOWER ... bool canShowCLowLower = showDonchain && showLower && showLow; ENUM_DRAW_TYPE donLowLowerDrawType = canShowCLowLower ? DRAW_LINE : DRAW_NONE; ArraySetAsSeries(donLowLowerBuffer, true); SetIndexBuffer(donLowLowerBufferIndex, donLowLowerBuffer, INDICATOR_DATA); PlotIndexSetDouble(donLowLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(donLowLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCLowLower); PlotIndexSetInteger(donLowLowerPlotBufferIndex, PLOT_DRAW_TYPE, donLowLowerDrawType); // // Data Buffers ... // // CURRENT ... // ArraySetAsSeries(cHHBuffer, true); SetIndexBuffer(cHHBufferIndex, cHHBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(cLLBuffer, true); SetIndexBuffer(cLLBufferIndex, cLLBuffer, INDICATOR_CALCULATIONS); // // SHORT ... // ArraySetAsSeries(sHHBuffer, true); SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(sLLBuffer, true); SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_CALCULATIONS); // // MEDIUM ... // ArraySetAsSeries(mHHBuffer, true); SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(mLLBuffer, true); SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_CALCULATIONS); // // LONG ... // ArraySetAsSeries(lHHBuffer, true); SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(lLLBuffer, true); SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_CALCULATIONS); // // HIND ... // ArraySetAsSeries(hHHBuffer, true); SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(hLLBuffer, true); SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_CALCULATIONS); // // XVWAP ... // // Volumes ... ArraySetAsSeries(vwapVolumeBuffer, true); SetIndexBuffer(vwapVolumeBufferIndex, vwapVolumeBuffer, INDICATOR_CALCULATIONS); // // Price ... ArraySetAsSeries(vwapPriceBuffer, true); SetIndexBuffer(vwapPriceBufferIndex, vwapPriceBuffer, INDICATOR_CALCULATIONS); // // Fast State ... ArraySetAsSeries(vwapFastStateBuffer, true); SetIndexBuffer(vwapFastStateBufferIndex, vwapFastStateBuffer, INDICATOR_CALCULATIONS); // // Mid State ... ArraySetAsSeries(vwapMidStateBuffer, true); SetIndexBuffer(vwapMidStateBufferIndex, vwapMidStateBuffer, INDICATOR_CALCULATIONS); // // Slow State ... ArraySetAsSeries(vwapSlowStateBuffer, true); SetIndexBuffer(vwapSlowStateBufferIndex, vwapSlowStateBuffer, INDICATOR_CALCULATIONS); // // VALID Peaks and Vales ... // ArraySetAsSeries(validPeaksBuffer, true); SetIndexBuffer(validPeaksBufferIndex, validPeaksBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(validValesBuffer, true); SetIndexBuffer(validValesBufferIndex, validValesBuffer, INDICATOR_CALCULATIONS); } /** * Set Indicator Short Name and also we can define Buffers Labels ... */ void SetIndicatorName() { 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; // // bool canCalculate = true; bool canCalculate = barsLimit == 0 || bar_index <= barsLimit; if (canCalculate) { // // Calculate Cycles ... CalculateCycles(bar_index); // // Calculate Peaks and Vales ... CalculatePeaksAndVales(bar_index); // CalculatePOIS(bar_index); // CalculateDonchains( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume // ); // CalculateValidPeaksAndVales( bar_index, prevCalculated // ); // // Calculate Required VWAP Data Buffers ... if (ratesTotal - bar_index <= maxLength) { // CalculateVWAPDataBuffers( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume // ); // // Prevent Moving Forward ... } else { // CalculateVWAPDataBuffers( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume // ); // CalculateVWAPS( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume // ); } } else { FillBuffersZero(bar_index); } } // // Custom ... /** * Initial Market Cycles ... * * @return ( bool ) */ bool InitMarketCycles() { // 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; // return result; } /** * Fill All Bufers to Zero Vlue for Specified Bar Index ... * * @param barIndex: Integer ... */ void FillBuffersZero(int barIndex) { // // CURRENT ... cHHBuffer[barIndex] = 0; cLLBuffer[barIndex] = 0; // // SHORT ... sHHBuffer[barIndex] = 0; sLLBuffer[barIndex] = 0; // // MEDIUM ... mHHBuffer[barIndex] = 0; mLLBuffer[barIndex] = 0; // // LONG ... lHHBuffer[barIndex] = 0; lLLBuffer[barIndex] = 0; // // HIND ... hHHBuffer[barIndex] = 0; hLLBuffer[barIndex] = 0; // // PEAKS ... peaksBuffer[barIndex] = 0; // // VALES ... valesBuffer[barIndex] = 0; // // SARS ... sarBuffer[barIndex] = 0; // // VWAP ... // vwapFastBuffer[barIndex] = 0; vwapMidBuffer[barIndex] = 0; vwapSlowBuffer[barIndex] = 0; vwapVolumeBuffer[barIndex] = 0; vwapPriceBuffer[barIndex] = 0; // vwapFastColorBuffer[barIndex] = hideColorIDX; vwapMidColorBuffer[barIndex] = hideColorIDX; vwapSlowColorBuffer[barIndex] = hideColorIDX; vwapFastStateBuffer[barIndex] = hideColorIDX; vwapMidStateBuffer[barIndex] = hideColorIDX; vwapSlowStateBuffer[barIndex] = hideColorIDX; // validPeaksBuffer[barIndex] = 0; validValesBuffer[barIndex] = 0; // donOpenUpperBuffer[barIndex] = 0; donOpenLowerBuffer[barIndex] = 0; donCloseUpperBuffer[barIndex] = 0; donCloseLowerBuffer[barIndex] = 0; donHighUpperBuffer[barIndex] = 0; donHighLowerBuffer[barIndex] = 0; donLowUpperBuffer[barIndex] = 0; donLowLowerBuffer[barIndex] = 0; } /** * 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, hhMode // ); hhBuffer[barIndex] = hhValue; // // Find Lowest Low ... double llValue = bar.FindLowest( mLength, llMode // ); llBuffer[barIndex] = llValue; } /** * Claculate Cycles ... * * @param barIndex: Integer, Bar Index ... */ void CalculateCycles(int barIndex) { // // 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 // ); } /** * Calculate Peaks and Vales ... * * @param barIndex: Integer, Bar Index ... */ void CalculatePeaksAndVales(int barIndex) { // int lastIndex = barIndex + 1; int barsCount = iBars(_Symbol, _Period); // // PEAKS ... double lastPeak = lastIndex < barsCount ? peaksBuffer[lastIndex] : 0; // double isHH = sHHBuffer[barIndex]; double imHH = mHHBuffer[barIndex]; double ilHH = lHHBuffer[barIndex]; double ihHH = hHHBuffer[barIndex]; // double iHHs[4] = { isHH, imHH, ilHH, ihHH // }; double rValue = GetAverage(iHHs); bool isPeak = rValue == isHH && isHH == imHH && imHH == ilHH && ilHH == ihHH; double iPeak = isPeak ? rValue : lastPeak; peaksBuffer[barIndex] = iPeak; // // VALES ... double lastVale = lastIndex < barsCount ? valesBuffer[lastIndex] : 0; // double isLL = sLLBuffer[barIndex]; double imLL = mLLBuffer[barIndex]; double ilLL = lLLBuffer[barIndex]; double ihLL = hLLBuffer[barIndex]; // double iLLs[4] = { isLL, imLL, ilLL, ihLL // }; double sValue = GetAverage(iLLs); bool isVale = sValue == isLL && isLL == imLL && imLL == ilLL && ilLL == ihLL; double iVale = isVale ? sValue : lastVale; valesBuffer[barIndex] = iVale; } /** * Calculate VWAP Value for Specified Bar ... * * @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 ... * @param _length: Integer, Specified VWAP Length ... * @param _show: Boolean, Specified Show Buffer or not ... * @param _buffer: Double Array Reference, Points to Buffer ... * @param _colorBuffer: Double Array Reference, Points to Color Buffer ... * @param _stateBuffer: Double Array Reference, Points to State Buffer ... */ void CalculateVWAP( 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 _length, // Calculation Length bool _show, double &_buffer[], double &_colorBuffer[], double &_stateBuffer[] // ) { // double vSum = 0; double pSum = 0; double mSum = 0; for (int x = 0; x < _length; x++) { // pSum += vwapPriceBuffer[x + bar_index]; vSum += vwapVolumeBuffer[x + bar_index]; mSum += vwapPriceBuffer[x + bar_index] * vwapVolumeBuffer[x + bar_index]; } // double iValue = mSum / vSum; iValue = NormalizeDouble(iValue, _Digits); // _buffer[bar_index] = iValue; // bool isBullish = low[bar_index] > iValue; bool isBearish = high[bar_index] < iValue; // double iColor = isBullish ? bullishColorIDX : isBearish ? bearishColorIDX : neuturalColorIDX; // _colorBuffer[bar_index] = hideColorIDX; _stateBuffer[bar_index] = iColor; if (showVWap && _show) { _colorBuffer[bar_index] = iColor; } } /** * Calculate Donchain ... * * @param bar_index: Integer, Bar Index ... * @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 ... * @param _length: Integer, Donchain Length ... * @param _ouBuffer: Double Array Reference ... * @param _olBuffer: Double Array Reference ... * @param _huBuffer: Double Array Reference ... * @param _hlBuffer: Double Array Reference ... * @param _luBuffer: Double Array Reference ... * @param _llBuffer: Double Array Reference ... * @param _cuBuffer: Double Array Reference ... * @param _clBuffer: Double Array Reference ... */ void CalculateDonchain( 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 _length, // double &_ouBuffer[], double &_olBuffer[], double &_huBuffer[], double &_hlBuffer[], double &_luBuffer[], double &_llBuffer[], double &_cuBuffer[], double &_clBuffer[] // ) { // double iUpper = 0; double iLower = 0; // // OPEN ... // int from = bar_index; // iUpper = open[ArrayMaximum(open, from, _length)]; iLower = open[ArrayMinimum(open, from, _length)]; // _ouBuffer[bar_index] = iUpper; _olBuffer[bar_index] = iLower; // // HIGH ... // iUpper = high[ArrayMaximum(high, from, _length)]; iLower = high[ArrayMinimum(high, from, _length)]; // _huBuffer[bar_index] = iUpper; _hlBuffer[bar_index] = iLower; // // LOW ... // iUpper = low[ArrayMaximum(low, from, _length)]; iLower = low[ArrayMinimum(low, from, _length)]; // _luBuffer[bar_index] = iUpper; _llBuffer[bar_index] = iLower; // // CLOSE ... // iUpper = close[ArrayMaximum(close, from, _length)]; iLower = close[ArrayMinimum(close, from, _length)]; // _cuBuffer[bar_index] = iUpper; _clBuffer[bar_index] = iLower; } /** * Calculate VWAP Required Data 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 CalculateVWAPDataBuffers( 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[] // ) { // double price = GetAppliedPrice( vwapAppliedTo, open, high, low, close, bar_index // ); vwapPriceBuffer[bar_index] = price; vwapVolumeBuffer[bar_index] = (double)tickVolume[bar_index]; } /** * Calculate Different VWaps ... * * @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 CalculateVWAPS( 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[] // ) { // // Fast ... CalculateVWAP( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume, // vwapFastLength, showVWapFast, vwapFastBuffer, vwapFastColorBuffer, vwapFastStateBuffer // ); // // Mid ... CalculateVWAP( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume, // vwapMidLength, showVWapMedium, vwapMidBuffer, vwapMidColorBuffer, vwapMidStateBuffer // ); // // Fast ... CalculateVWAP( bar_index, prevCalculated, ratesTotal, open, high, close, low, tickVolume, // vwapSlowLength, showVWapSlow, vwapSlowBuffer, vwapSlowColorBuffer, vwapSlowStateBuffer // ); } /** * Calculate Different VWaps ... * * @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 CalculateDonchains( 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[] // ) { // CalculateDonchain( // bar_index, prevCalculated, ratesTotal, // open, high, close, low, tickVolume, // donchainLength, // donOpenUpperBuffer, donOpenLowerBuffer, donHighUpperBuffer, donHighLowerBuffer, donLowUpperBuffer, donLowLowerBuffer, donCloseUpperBuffer, donCloseLowerBuffer // ); } /** * Calculate POIs ... * * @param bar_index: Integer, Current Bar ... */ void CalculatePOIS(int bar_index) { // ENUM_XPOI_EVENTS events[]; int eventsCount = mPOIDetector.Update(events); // XPOIState poiState; mPOIDetector.GetState(poiState); // bool redrawState = true; if (redrawState) { ReDrawPOIState(poiState); } // if (!IsValidSize(eventsCount)) { return; } // string msg = ToString(eventsCount) + " POI Events: " + "\n"; for (int i = 0; i < eventsCount; i++) { // ENUM_XPOI_EVENTS iEvent = events[i]; // string iMSG = ToString(i) + "_ " + ToString(iEvent); msg += iMSG + "\n"; // // Drawn Objects ... // // Swing High ... if (iEvent == X_SWING_HIGH_DETECTED) { // XCSwing *iSwing; bool hasSwing = GetLastItem( iSwing, poiState.swingHighs // ); } // // Swing Low ... if (iEvent == X_SWING_HIGH_DETECTED) { // XCSwing *iSwing; bool hasSwing = GetLastItem( iSwing, poiState.swingLows // ); } // // Bullish Rejection Bar ... if (iEvent == X_BULLISH_REJECTION_BAR_DETECTED) { // XCRejectionBar *iRejectionBar; bool hasBar = GetLastItem( iRejectionBar, poiState.bullishRejectionBars // ); } // // Bearish Rejection Bar ... if (iEvent == X_BEARISH_REJECTION_BAR_DETECTED) { // XCRejectionBar *iRejectionBar; bool hasBar = GetLastItem( iRejectionBar, poiState.bearishRejectionBars // ); } // // Bullish Momentum Bar ... if (iEvent == X_BULLISH_MOMENTUM_BAR_DETECTED) { // XCMomentumBar *iMomentumBar; bool hasBar = GetLastItem( iMomentumBar, poiState.bullishMomentumBars // ); } // // Bearish Momentum Bar ... if (iEvent == X_BEARISH_MOMENTUM_BAR_DETECTED) { // XCMomentumBar *iMomentumBar; bool hasBar = GetLastItem( iMomentumBar, poiState.bearishMomentumBars // ); } // // Support Zone ... if (iEvent == X_SUPPORT_ZONE_DETECTED) { // XCSupportZone *iZone; bool hasZone = GetLastItem( iZone, poiState.supportZones // ); } // // Demand Zone ... if (iEvent == X_DEMAND_ZONE_DETECTED) { // XCDemandZone *iZone; bool hasZone = GetLastItem( iZone, poiState.demandZones // ); } // // Bullish Order Block ... if (iEvent == X_BULLISH_ORDERBLOCK_DETECTED) { // XCOrderBlock *iZone; bool hasZone = GetLastItem( iZone, poiState.bullishOrderBlocks // ); } // // Bullish Fair Value Gap ... if (iEvent == X_BULLISH_FVG_DETECTED) { // XCFVG *iZone; bool hasZone = GetLastItem( iZone, poiState.bullishFairValueGaps // ); } // // Resistance Zone ... if (iEvent == X_RESISTANCE_ZONE_DETECTED) { // XCResistanceZone *iZone; bool hasZone = GetLastItem( iZone, poiState.resistanceZones // ); } // // Supply Zone ... if (iEvent == X_SUPPLY_ZONE_DETECTED) { // XCSupplyZone *iZone; bool hasZone = GetLastItem( iZone, poiState.supplyZones // ); } // // Bearish Order Block ... if (iEvent == X_BEARISH_ORDERBLOCK_DETECTED) { // XCOrderBlock *iZone; bool hasZone = GetLastItem( iZone, poiState.bearishOrderBlocks // ); } // // Bearish Fair Value Gap ... if (iEvent == X_BEARISH_FVG_DETECTED) { // XCFVG *iZone; bool hasZone = GetLastItem( iZone, poiState.bearishFairValueGaps // ); } } // // Update Drawn Objects ... ReDrawPOIState( poiState // ); } /** * Calculate Valid Vales and Peaks ... * * @param bar_index: Integer, current Bar Index ... */ void CalculateValidPeaksAndVales( int bar_index, int prevCalculated // ) { // int minRepetition = 40; int maxAllowedLoopbackBars = 576; // int barIndex = bar_index; int start = barIndex; int end = start + maxAllowedLoopbackBars; // double peak = 0; int peakRepeate = 0; int peakToBarIndex = 0; int peakFromBarIndex = 0; // double vale = 0; int valeRepeate = 0; int valeToBarIndex = 0; int valeFromBarIndex = 0; // bool canLookupPeak = true; bool canLookupVale = true; bool canLookup = true; // while (canLookup) { // // Check Peak ... if (canLookupPeak) { // double iPeak = peaksBuffer[barIndex]; if (iPeak != peak) { // if (peak != 0 && peakRepeate >= minRepetition) { // canLookupPeak = false; } else { // peak = iPeak; peakRepeate = 0; peakFromBarIndex = 0; peakToBarIndex = barIndex; } } else if (iPeak == peak) { // peakRepeate++; peakFromBarIndex = barIndex; } } // // Check Vale ... if (canLookupVale) { // double iVale = valesBuffer[barIndex]; if (iVale != vale) { // if (vale != 0 && valeRepeate >= minRepetition) { canLookupVale = false; } else { // vale = iVale; valeRepeate = 0; valeFromBarIndex = 0; valeToBarIndex = barIndex; } } else if (iVale == vale) { // valeRepeate++; valeFromBarIndex = barIndex; } } // canLookup = barIndex < end && (canLookupPeak || canLookupVale); if (canLookup) { barIndex++; } } // if (!canLookupPeak) { validPeaksBuffer[bar_index] = peak; } else { // double lastValidPeak = prevCalculated == 0 ? 0 : validPeaksBuffer[bar_index + 1]; // validPeaksBuffer[bar_index] = lastValidPeak; } // if (!canLookupVale) { validValesBuffer[bar_index] = vale; } else { // double lastValidVale = prevCalculated == 0 ? 0 : validValesBuffer[bar_index + 1]; // validValesBuffer[bar_index] = lastValidVale; } } // // Draw Functions ... /** * Add Drawn Specified Object to Collection ... */ void AddDrawnObject(XCBaseObject *object) { // string name = object.ObjName(); // bool canAdd = true; int count = mDrawnObjects.Total(); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // string iName = ((XCBaseObject *)mDrawnObjects.At(i)).ObjName(); // if (name == iName) { // canAdd = false; break; } } } // if (canAdd) { mDrawnObjects.Add(object); } } /** * Update Drawn Objects ... */ void UpdateDrawnObjects() { // int count = mDrawnObjects.Total(); if (!IsValidSize(count)) { return; } // // Loop Through Drawn Objects ... // TODO: Implement this ... } /** * ReDraw State POI ... * * @param state: XPOIState instance */ void ReDrawPOIState( XPOIState &state, bool forceUpdateZones = true, bool clearDraws = false // ) { // if (!showPOIs || !state.IsValid() || !state.HasChild()) { return; } // // Clear Draws ... if (clearDraws) { mDrawnObjects.Clear(); } // datetime cTime = TimeCurrent(); // int swingHighsCount = state.CountSwingHighs(); if (drawSwingHighs && IsValidSize(swingHighsCount)) { // for (int i = 0; i < swingHighsCount; i++) { // XCSwing *iSwing = state.swingHighs[i]; XCSwingHighObject *iObj; bool isCreated = mPOIDrawer.CreateSwingHigh( iSwing, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int swingLowsCount = state.CountSwingLows(); if (drawSwingLows && IsValidSize(swingLowsCount)) { // for (int i = 0; i < swingLowsCount; i++) { // XCSwing *iSwing = state.swingLows[i]; XCSwingLowObject *iObj; bool isCreated = mPOIDrawer.CreateSwingLow( iSwing, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int supportZonesCount = state.CountSupportZones(); if (drawSupportZones && IsValidSize(supportZonesCount)) { // for (int i = 0; i < supportZonesCount; i++) { // XCSupportZone *iZone = state.supportZones[i]; if (forceUpdateZones) { iZone.To(cTime); } XCSupportZoneObject *iObj; bool isCreated = mPOIDrawer.CreateSupportZone( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int resistanceZonesCount = state.CountResistanceZones(); if (drawResistanceZones && IsValidSize(resistanceZonesCount)) { // for (int i = 0; i < resistanceZonesCount; i++) { // XCResistanceZone *iZone = state.resistanceZones[i]; if (forceUpdateZones) { iZone.To(cTime); } XCResistanceZoneObject *iObj; bool isCreated = mPOIDrawer.CreateResistanceZone( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int supplyZonesCount = state.CountSupplyZones(); if (drawSupplyZones && IsValidSize(supplyZonesCount)) { // for (int i = 0; i < supplyZonesCount; i++) { // XCSupplyZone *iZone = state.supplyZones[i]; if (forceUpdateZones) { iZone.To(cTime); } XCSupplyZoneObject *iObj; bool isCreated = mPOIDrawer.CreateSupplyZone( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int demandZonesCount = state.CountDemandZones(); if (drawDemandZones && IsValidSize(demandZonesCount)) { // for (int i = 0; i < demandZonesCount; i++) { // XCDemandZone *iZone = state.demandZones[i]; if (forceUpdateZones) { iZone.To(cTime); } XCDemandZoneObject *iObj; bool isCreated = mPOIDrawer.CreateDemandZone( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bullishOrderBlocksCount = state.CountBullishOrderBlocks(); if (drawBullishOrderBlocks && IsValidSize(bullishOrderBlocksCount)) { // for (int i = 0; i < bullishOrderBlocksCount; i++) { // XCOrderBlock *iZone = state.bullishOrderBlocks[i]; if (forceUpdateZones) { iZone.To(cTime); } XCBullishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBullishOrderBlock( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bearishOrderBlocksCount = state.CountBearishOrderBlocks(); if (drawBearishOrderBlocks && IsValidSize(bearishOrderBlocksCount)) { // for (int i = 0; i < bearishOrderBlocksCount; i++) { // XCOrderBlock *iZone = state.bearishOrderBlocks[i]; if (forceUpdateZones) { iZone.To(cTime); } XCBearishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBearishOrderBlock( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bullishFairValueGapsCount = state.CountBullishFairValueGaps(); if (drawBullishFairValueGaps && IsValidSize(bullishFairValueGapsCount)) { // for (int i = 0; i < bullishFairValueGapsCount; i++) { // XCFVG *iZone = state.bullishFairValueGaps[i]; if (forceUpdateZones) { iZone.To(cTime); } XCBullishFairValueGapObject *iObj; bool isCreated = mPOIDrawer.CreateBullishFairValueGap( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bearishFairValueGapsCount = state.CountBearishFairValueGaps(); if (drawBearishFairValueGaps && IsValidSize(bearishFairValueGapsCount)) { // for (int i = 0; i < bearishFairValueGapsCount; i++) { // XCFVG *iZone = state.bearishFairValueGaps[i]; if (forceUpdateZones) { iZone.To(cTime); } XCBearishFairValueGapObject *iObj; bool isCreated = mPOIDrawer.CreateBearishFairValueGap( iZone, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bullishRejectionBarsCount = state.CountBullishRejectionBars(); if (drawBullishRejectionBars && IsValidSize(bullishRejectionBarsCount)) { // for (int i = 0; i < bullishRejectionBarsCount; i++) { // XCRejectionBar *iRejectionBar = state.bullishRejectionBars[i]; XCBullishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishRejectionBar( iRejectionBar, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bearishRejectionBarsCount = state.CountBearishRejectionBars(); if (drawBearishRejectionBars && IsValidSize(bearishRejectionBarsCount)) { // for (int i = 0; i < bearishRejectionBarsCount; i++) { // XCRejectionBar *iRejectionBar = state.bearishRejectionBars[i]; XCBearishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBearishRejectionBar( iRejectionBar, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bullishMomentumBarsCount = state.CountBullishMomentumBars(); if (drawBullishMomentumBars && IsValidSize(bullishMomentumBarsCount)) { // for (int i = 0; i < bullishMomentumBarsCount; i++) { // XCMomentumBar *iMomentumBar = state.bullishMomentumBars[i]; XCBullishMomentumBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishMomentumBar( iMomentumBar, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } // int bearishMomentumBarsCount = state.CountBearishMomentumBars(); if (drawBearishMomentumBars && IsValidSize(bearishMomentumBarsCount)) { // for (int i = 0; i < bearishMomentumBarsCount; i++) { // XCMomentumBar *iMomentumBar = state.bearishMomentumBars[i]; XCBearishMomentumBarObject *iObj; bool isCreated = mPOIDrawer.CreateBearishMomentumBar( iMomentumBar, iObj // ); // if (isCreated) { AddDrawnObject(iObj); } } } } //