From c5a1e326b25e75e0f3a49c9c58f0b47e7e779c63 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 1 Oct 2025 05:10:42 +0330 Subject: [PATCH] last works on XFIMA ... --- Classes/x-saherelm.x-helper.class.mq5 | 124 + .../x-saherelm.xfima.backtester.ea copy.mq5 | 1899 +++++++ .../BKP/x-saherelm.xfima.helper copy.mq5 | 3820 +++++++++++++ Documents/BKP/x-saherelm.xfima.helper.mq5 | 4974 +++++++++++++++++ .../x-saherelm.xfima.signaller.class copy.mq5 | 1697 ++++++ Experts/x-saherelm.xfima.backtester.ea.mq5 | 1016 +--- Helpers/x-saherelm.xfima.helper.mq5 | 2255 ++------ Libraries/x-saherelm.x-poi.extensions.lib.mq5 | 68 +- .../x-saherelm.xfima.signaller.class.mq5 | 847 +-- 9 files changed, 13315 insertions(+), 3385 deletions(-) create mode 100644 Documents/BKP/x-saherelm.xfima.backtester.ea copy.mq5 create mode 100644 Documents/BKP/x-saherelm.xfima.helper copy.mq5 create mode 100644 Documents/BKP/x-saherelm.xfima.helper.mq5 create mode 100644 Documents/BKP/x-saherelm.xfima.signaller.class copy.mq5 diff --git a/Classes/x-saherelm.x-helper.class.mq5 b/Classes/x-saherelm.x-helper.class.mq5 index 6c036547..e5a35e1b 100644 --- a/Classes/x-saherelm.x-helper.class.mq5 +++ b/Classes/x-saherelm.x-helper.class.mq5 @@ -23,6 +23,7 @@ // // Includes ... #include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" // // Definitions ... @@ -125,6 +126,25 @@ class XCBaseHelper : public XCBase // // Functions ... + /** + * Validate Handler Exists ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = IsXValid(mSymbol) && + IsXValid(mPeriod) && + mHandler != INVALID_HANDLE; + + // + return result; + } + /** * Extract Validated Zones ... * @@ -511,6 +531,110 @@ class XCBaseHelper : public XCBase // Indicator Handler ... int mHandler; + /** + * Read Value of Specified Buffer ... + * + * @param bufferIndex: int, which handler buffer to read value ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( double ) + */ + double ReadValue( + int bufferIndex, + int barIndex = 0 // + ) + { + // + double result = EMPTY_VALUE; + + // + // Normalize ... + int barsTotal = CountBars(); + barIndex = NormalizeInt(barIndex, 0, barsTotal - 1); + bufferIndex = NormalizeInt(bufferIndex, 0); + + // + // Validate ... + if (!IsValid()) + { + return result; + } + + // + double tmp[]; + int count = CopyBuffer( + mHandler, + bufferIndex, + barIndex, + 1, + tmp // + ); + result = tmp[0]; + + // + return result; + } + + /** + * Read Values of Specified Buffer ... + * + * @param buffer: double, reference collection to holds result ... + * @param bufferIndex: int, which handler buffer to read value ... + * @param barIndex: int, Specified Bar Index ... + * @param count: int, number of items to read, 0 for WHOLE_ARRAY ... + * @param asSeries: bool, set As Series Buffer or not ... + * + * @return ( int ) + */ + int ReadValues( + double &buffer[], + int bufferIndex, + int barIndex = 0, + int count = 0, + bool asSeries = true // + ) + { + // + int result = 0; + + // + // Prepare ... + XClean(buffer); + + // + // Normalize ... + int barsTotal = CountBars(); + count = NormalizeInt(count, 0); + bufferIndex = NormalizeInt(bufferIndex, 0); + barIndex = NormalizeInt(barIndex, 0, barsTotal - 1); + + // + // Validate ... + if (!IsValid()) + { + return result; + } + + // + result = CopyBuffer( + mHandler, + bufferIndex, + barIndex, + count, + buffer // + ); + + // + // Set As Series Flag ... + ArraySetAsSeries(buffer, asSeries); + + // + result = ArraySize(buffer); + + // + return result; + } + // // Private ... private: diff --git a/Documents/BKP/x-saherelm.xfima.backtester.ea copy.mq5 b/Documents/BKP/x-saherelm.xfima.backtester.ea copy.mq5 new file mode 100644 index 00000000..a2ff4f56 --- /dev/null +++ b/Documents/BKP/x-saherelm.xfima.backtester.ea copy.mq5 @@ -0,0 +1,1899 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XTest MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XBackTester +// Description: a Backtest Tools Strategy Tester +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XBackTester" +#property icon "../Images/SaherElm_Logo_Color.ico" +#property strict + +// +#define ShortName "XBackTester" + +// +// Imports ... +#include "../Classes/x-saherelm.x-backtester.expert.class.mq5" +#include "../XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5" + +// +// Definitions ... + +// +// Inputs ... + +// +// Common ... +input group "Common"; +input long eaMagicNumber = 78692110; // Magic Number +input int eaSlippage = 10; // Slippgae +input string eaLogSuffix = ""; // Log Suffix + +// +// Alert ... +// Here we Provider All Requirements for +// Configuring Alert Provider ... +input group "Alert"; +input bool eaEnableAlerts = true; // Enable Alerts +input bool eaLogAlerts = true; // Log Alerts +input bool eaMailAlerts = false; // Mail Alerts +input bool eaPushAlerts = false; // Push Alerts +input bool eaTerminalAlerts = false; // Terminal Alerts + +// +// Configurations ... +input group "Configuration"; +input bool eaProcessAllTicks = false; // Process All Ticks +input double eaSignallerR2R = 2.0; // Risk To Reward Ratio +input double eaSignallerVolume = 0.01; // Default Volume +input double eaSignallerRiskInPoint = 50; // Default Risk In Point + +// +// Indicator Inputs ... +// +input group "Calculation"; + +// +// Short ... +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Short Period + +// +// Medium ... +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period + +// +// Long ... +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period + +// +// Hind ... +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period + +// +// PV ... +input ENUM_SERIESMODE upperMode = MODE_HIGH; // Peak Method +input ENUM_SERIESMODE lowerMode = MODE_LOW; // Vale Method + +// +// Others ... +input ENUM_X_FIBO_LEVELS fiboUpperZoneLevel = X_FIBO_LEVEL_382; // Upper Zone Level +input ENUM_X_FIBO_LEVELS fiboMiddleZoneLevel = X_FIBO_LEVEL_500; // Middle Zone Level +input ENUM_X_FIBO_LEVELS fiboLowerZoneLevel = X_FIBO_LEVEL_618; // Lower Zone Level +input double sarStep = 0.02; // SAR Step +input double sarMax = 0.2; // SAR Maximum +input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method +input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // MA Applied To +input int maFastLength = 7; // Fast MA Length +input int maSlowLength = 20; // Slow MA Length +input int maBandLength = 7; // MA Band Length +input int zigzagDepth = 12; // ZigZag Depth +input int zigzagDeviation = 5; // ZigZag Deviation +input int zigzagBackStep = 3; // ZigZag Back Step +input ENUM_X_PRICE zigzagUppersMode = X_PRICE_HIGH; // ZigZag High Detect Mode +input ENUM_X_PRICE zigzagLowersMode = X_PRICE_LOW; // ZigZag Low Detect Mode + +// +input group "Bar Timer"; +input int barTimeFontSize = 10; // Font Size +input string barTimeFont = "Arial"; // Font +input color barTimeColor = clrYellow; // Text Color +input ENUM_BASE_CORNER barTimeCorner = CORNER_RIGHT_LOWER; // Text Position + +// +// Presentation ... +input group "Presentation"; +input bool showPV = true; // Show PV +input bool showHK = true; // Show HK +input bool showSAR = true; // Show Sar +input bool showMAFast = true; // Show MA Fast +input bool showMASlow = true; // Show MA Slow +input bool showMABand = true; // Show MA Band +input bool showBarTime = true; // Show Bar Time +input bool showZigZag = true; // Show ZigZag +input bool showFiboZone = true; // Show Fibo Zone + +// +input int startCalculationForLastBars = 1500; // Calculate Last n Bars + +// +input int sarArrowCode = 159; // Parabolic Sar Arrow Code +input int peakArrowCode = 159; // Peaks Arrow Code +input int valeArrowCode = 159; // Vales Arrow Code + +// +// Define Local Variables ... + +// +// Requirements ... +string eaLogTag; // EA Log Prefix ... +XCBackTesterEA *eaExpert; // EA Expert ... + +// +// Registered Signallers ... +XCXFIMAStrategy1Signaller *fima1Signaller; // XFIMA1 Signaller ... + +// +XFIMAMarketStructure marketStructure; // POI Analysis Result ... +XFIMAPatternDetectorConfig detectorConfig; // POI Detector Config ... +XFIMAMarketStructureDrawerConfig marketStructureDrawerConfig; // POI Drawer Config ... + +// +// Drawer and eaDraws ... +CArrayObj eaDraws; // Drawn Objects ... +CArrayObj *marketStructureObjects; // Market Structure Objects ... + +// +XBarTracker eaBarTracker; // EA Bar Traker ... + +// +// Registered Handlers ... +int eaCTHandler = INVALID_HANDLE; // Candle Timer Handler ... + +// +bool eaIsNewBar; // Check New Bar ... + +// +// Define Indicators Here ... + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Preparing Tags ... + string eaTag = + (IsValid(eaLogSuffix) + ? eaLogSuffix + "_" + : "") + + ShortName; + + // + // Validate Inputs and Required Parameters + // for EA to Works fine ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize Timer ... + if (!InitTimer()) + { + return INIT_FAILED; + } + + // + // Configure EA Expert Class ... + eaExpert = new XCBackTesterEA(); + + // + // Symbol / Period ... + eaExpert.symbol = _Symbol; + eaExpert.period = _Period; + + // + // Common ... + eaExpert.eaMagicNumber = eaMagicNumber; + eaExpert.eaSlippage = eaSlippage; + eaExpert.eaLogSuffix = eaTag; + + // + // Alert ... + eaExpert.eaEnableAlerts = eaEnableAlerts; + eaExpert.eaLogAlerts = eaLogAlerts; + eaExpert.eaMailAlerts = eaMailAlerts; + eaExpert.eaPushAlerts = eaPushAlerts; + eaExpert.eaTerminalAlerts = eaTerminalAlerts; + + // + // Attach Event Handlers ... + eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged); + eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered); + eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged); + eaExpert.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); + eaExpert.AddOnModifyPositionEventHandler(OnPositionModified); + eaExpert.AddOnPositionsChangedEventHandler(OnPositionsChanged); + eaExpert.AddOnTradeStateChangedEventHandler(OnTradeStateChanged); + eaExpert.AddOnForceClosePositionEventHandler(OnPositionForceClosed); + eaExpert.AddOnPartialClosePositionEventHandler(OnPositionPartialClosed); + + // + // Configure Other Requirements ... + eaExpert.allowedTPSLStep = 10; + eaExpert.minAllowedRiskInPoint = 20; + eaExpert.volume = eaSignallerVolume; + eaExpert.riskToRewardRatio = eaSignallerR2R; + eaExpert.riskInPoint = eaSignallerRiskInPoint; + + // + // Try to Initialize eaExpert ... + bool isInited = eaExpert.HandleOnInit(); + if (!isInited) + { + // + Print(ShortName, ": Initialization Failed ..."); + return INIT_FAILED; + } + + // + // Here Instantiate Signaller Class ... + + // + // Preparing Indicator Inputs ... + XFIMAInputs fimaInputs; + + // + // This is Default Configuration ... + fimaInputs.Default(); + fimaInputs.Hide(); + + // + // Here we Attach Inputs to Indicator ... + fimaInputs.scMethod = scMethod; + fimaInputs.scPeriod = scPeriod; + fimaInputs.mcMethod = mcMethod; + fimaInputs.mcPeriod = mcPeriod; + fimaInputs.lcMethod = lcMethod; + fimaInputs.lcPeriod = lcPeriod; + fimaInputs.hcMethod = hcMethod; + fimaInputs.hcPeriod = hcPeriod; + fimaInputs.upperMode = upperMode; + fimaInputs.lowerMode = lowerMode; + fimaInputs.fiboUpperZoneLevel = fiboUpperZoneLevel; + fimaInputs.fiboMiddleZoneLevel = fiboMiddleZoneLevel; + fimaInputs.fiboLowerZoneLevel = fiboLowerZoneLevel; + fimaInputs.sarStep = sarStep; + fimaInputs.sarMax = sarMax; + fimaInputs.maMethod = maMethod; + fimaInputs.maAppliedTo = maAppliedTo; + fimaInputs.maFastLength = maFastLength; + fimaInputs.maSlowLength = maSlowLength; + fimaInputs.maBandLength = maBandLength; + fimaInputs.zigzagDepth = zigzagDepth; + fimaInputs.zigzagDeviation = zigzagDeviation; + fimaInputs.zigzagBackStep = zigzagBackStep; + fimaInputs.zigzagUppersMode = zigzagUppersMode; + fimaInputs.zigzagLowersMode = zigzagLowersMode; + fimaInputs.showPV = showPV; + fimaInputs.showHK = showHK; + fimaInputs.showSAR = showSAR; + fimaInputs.showMAFast = showMAFast; + fimaInputs.showMASlow = showMASlow; + fimaInputs.showMABand = showMABand; + fimaInputs.showZigZag = showZigZag; + fimaInputs.showFiboZone = showFiboZone; + fimaInputs.startCalculationForLastBars = startCalculationForLastBars; + fimaInputs.sarArrowCode = sarArrowCode; + fimaInputs.peakArrowCode = peakArrowCode; + fimaInputs.valeArrowCode = valeArrowCode; + + // + // Instantiate Signaller ... + + // + // XFIMA1 Signaller ... + fima1Signaller = new XCXFIMAStrategy1Signaller( + _Symbol, + _Period, + fimaInputs, + eaProcessAllTicks, // Process All Ticks ... + eaSignallerR2R, // Signaller Risk to Reward Ratio ... + eaSignallerRiskInPoint, // Default Risk In Points ... + eaSignallerVolume // Defaul Volume ... + ); + fima1Signaller.AddOnSignalEventHandler(OnSignalTriggered); + + // + isInited = + fima1Signaller.IsValid(); + if (!isInited) + { + // + Print(ShortName, ": Initialization Failed ..."); + return INIT_FAILED; + } + + // + // Initialize Candle Timer Handler ... + eaCTHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.x121.xct", + // + // Inputs ... + barTimeFontSize, // Font Size ... + barTimeFont, // Font ... + barTimeColor, // Text Color ... + barTimeCorner, // Text Position ... + // + // Presentation ... + "", + showBarTime // Show Candle Time + // + ); + isInited = eaCTHandler != INVALID_HANDLE; + if (!isInited) + { + // + Print(ShortName, ": Initialization Failed ..."); + return INIT_FAILED; + } + + // + // Initialize Bar Tracker ... + isInited = eaBarTracker.Init( + _Symbol, + _Period // + ); + if (!isInited) + { + // + Print(ShortName, ": Initialization Failed ..."); + return INIT_FAILED; + } + + // + // Configure XFIMA POI Detector / Drawer ... + detectorConfig.Default(); + detectorConfig.FullDetect(); + marketStructureDrawerConfig.FullDraw(); + + // + Print(ShortName, ": Initialized Successfully ..."); + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +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 + + // + // Destroy Timer ... + eaExpert.HandleOnDeInit(); + + // + // De Init Indicator ... + IndicatorRelease(eaCTHandler); + + // + eaBarTracker.Clean(); + + // + delete fima1Signaller; + ZeroMemory(fima1Signaller); + + // + delete eaExpert; + ZeroMemory(eaExpert); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + eaIsNewBar = eaBarTracker.IsNewBar(); + bool canProcess = eaProcessAllTicks + ? true + : eaIsNewBar; + // + eaExpert.HandleOnTick(); + + // + if (!canProcess) + { + return; + } + + // + // Bar Index ... + int barIndex = 1; + + // + fima1Signaller.OnTick(barIndex); + + // + // AnalyseMarket(barIndex); +} + +// +// Handle On Trade Event ... +void OnTrade() +{ + eaExpert.HandleOnTrade(); +} + +// +// On Timer ... +void OnTimer() +{ + eaExpert.HandleOnTimer(); +} + +// +// Chart Event Handler ... +void OnChartEvent( + const int id, + const long &lparam, + const double &dparam, + const string &sparam // +) +{ + eaExpert.HandleOnChartEvent(id, lparam, dparam, sparam); +} + +// +// Custom Functions ... + +/** + * Validate all Inputs of Expert Adviser ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + string errMessage = ""; + + // + bool isCommonValid = ( + // + eaSlippage > 0 && + eaMagicNumber > 0 && + // + // Indicator Inputs ... + // + // MA ... + maFastLength >= 2 && + maSlowLength >= 2 && + maSlowLength > maFastLength && + // + // SAR ... + sarMax > 0 && + sarStep > 0 && + sarMax > sarStep && + // + // CYCLES ... + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) && + // + // ZIGZAG ... + zigzagDepth > 0 && + zigzagDeviation > 0 && + zigzagBackStep > 0 && + // + // Validate Upper Mode Detection ... + IsXValid(zigzagUppersMode) && + // + // Validate Lower Mode Detection ... + IsXValid(zigzagLowersMode) + // + ); + if (!isCommonValid) + { + // + errMessage += "common configurations error;" + "\n"; + } + + // + result = + // + // Common ... + isCommonValid && + // + // Otere ... + true + // + ; + + // + if (!result) + { + // + // Since here Logger not Initiallized, we Use Raw Print Command ... + Print(ShortName + " Errors: \n", errMessage); + } + + // + return result; +} + +/** + * Initialize Timer ... + * + * @return ( bool ) + */ +bool InitTimer() +{ + // + bool result = false; + + // + // TODO: Initialize Timer if necessary ... + // result = EventSetTimer(1); + // result = EventSetMillisecondTimer(100); + result = true; + + // + return result; +} + +/** + * Destroy Timer ... + */ +void DestroyTimer() +{ + // + // TODO: Use This ... + // EventKillTimer(); +} + +/** + * Trigger OnSignal Event ... + * + * @param signal: XSignal + */ +void OnSignalTriggered(XSignal &signal) +{ + // + // Validate Signal ... + if (!signal.IsValid()) + { + return; + } + + // + // TODO: Fix this ... + // return; + + // + // Draw Signal on Chart ... + XCSignalObject *iSignalObj; + bool has = fima1Signaller.poiDrawer.DrawSignal( + signal, + iSignalObj, + 7 // + ); + + // + if (has) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT result; + eaExpert.eaTrader.ExecuteSignal( + signal, + result // + ); + + // + Print("Signal Issued: ", signal.GetObjectID()); + } + + // + // Try to Execute Signal ... + + // + // Draw Signal Vertical Line ... + + // // + // CChartObjectVLine *iObj = new CChartObjectVLine(); + + // // + // string iName = signal.GetObjectID(); + // color iColor = IsLong(signal.type) ? clrLime : clrRed; + + // // + // bool has = iObj.Create( + // fima2Signaller.poiDrawer.ChartIdentification(), + // iName, + // fima2Signaller.poiDrawer.SubWindowIdentification(), + // signal.time // + // ); + // if (has) + // { + // // + // iObj.Width(2); + // iObj.Color(iColor); + + // // + // // eaDraws.Add(iObj); + // } + + // // + // // Alert Issued Signal ... + // string message = signal.GetMessage(); + + // + // int signalBarIndex = GetBarIndex( + // signal.symbol, + // signal.period, + // signal.time // + // ); + // AnalyseMarket(signalBarIndex); +} + +// +// Trade Event Handlers ... + +/** + * Handle StopLoss Triggered Positions ... + * + * @param deal: XDeal instance ... + */ +void OnStopLossTriggered(const XDeal &deal) +{ + eaExpert.HandleOnStopLossTriggered(deal); +} + +/** + * Handle Take Profit Triggered Positions ... + * + * @param deal: XDeal instance ... + */ +void OnTakeProfitTriggered(const XDeal &deal) +{ + eaExpert.HandleOnTakeProfitTriggered(deal); +} + +/** + * Handle Force Close a Position ... + * + * @param ticket: ULONG ... + * @param position: XPosition instance ... + * @param comment: String ... + */ +void OnPositionForceClosed( + const ulong ticket, + const XPosition &position, + const string comment // +) +{ + // + eaExpert.HandleOnPositionForceClosed( + ticket, + position, + comment // + ); +} + +/** + * Handle Deals Changes ... + * + * @param count: Integer, Number of Changes ... + */ +void OnDealsChanged(int count) +{ + eaExpert.HandleOnDealsChanged(count); +} + +/** + * Handle Orders Changes ... + * + * @param count: Integer, Number of Changes ... + */ +void OnOrdersChanged(int count) +{ + eaExpert.HandleOnOrdersChanged(count); +} + +/** + * Handle Positions Changes ... + * + * @param count: Integer, Number of Changes ... + */ +void OnPositionsChanged(int count) +{ + eaExpert.HandleOnPositionsChanged(count); +} + +/** + * Handle Position Modified ... + * + * @param ticket: ulong, Position Ticket ... + * @param profit: double, Position Profit ... + * @param comment: string, Comment ... + */ +void OnPositionModified( + const ulong ticket, + const double profit, + const string comment // +) +{ + // + eaExpert.HandleOnPositionModified( + ticket, + profit, + comment // + ); +} + +/** + * Handle Position Partial Closed ... + * + * @param ticket: ulong, Position Ticket ... + * @param profit: double, Position Profit ... + * @param comment: string, Comment ... + */ +void OnPositionPartialClosed( + const ulong ticket, + const double profit, + const string comment // +) +{ + // + eaExpert.HandleOnPositionPartialClosed( + ticket, + profit, + comment // + ); +} + +/** + * Handle Trade State Changed ... + * + * @param state: XOnTradeHandlerState instance ... + */ +void OnTradeStateChanged(const XOnTradeHandlerState &state) +{ + eaExpert.HandleOnTradeStateChanged(state); +} + +// +void AnalyseMarket(int barIndex = 0) +{ + // + bool has = false; + + // + barIndex = NormalizeInt(barIndex, 0); + + // + string symbol = fima1Signaller.symbol; + ENUM_TIMEFRAMES period = fima1Signaller.period; + + // + // Retrieve Signal Bar ... + XOHCL bar; + has = bar.Init( + symbol, + period, + barIndex // + ); + if (!has) + { + // + bar.Clean(); + return; + } + + // + // TODO: Remove this and add in OnInit() Method ... + + // + // Configuring Detector ... + + // + detectorConfig.detectOB = true; + detectorConfig.detectFVG = true; + + // + detectorConfig.detectSupport = true; + detectorConfig.detectResistance = true; + detectorConfig.detectSwingTrend = true; + + // + detectorConfig.detectPinned = true; + detectorConfig.detectMomentum = true; + detectorConfig.detectEngulfed = true; + detectorConfig.detectTrueGaped = true; + + // + detectorConfig.detectStarPattern = true; + detectorConfig.detectFlagPattern = true; + detectorConfig.detectRisingPattern = true; + detectorConfig.detectPiercingPattern = true; + detectorConfig.detectSignalKeyBarPattern = true; + + // + detectorConfig.analyseFIMAPVPivots = true; + detectorConfig.analyseFIMASARPivots = false; + detectorConfig.analyseFIMAZigZagPivots = true; + + // + // Configure Drawer ... + + // + marketStructureDrawerConfig.drawOB = false; + marketStructureDrawerConfig.drawFVG = false; + + // + marketStructureDrawerConfig.drawPinned = false; + marketStructureDrawerConfig.drawEngulfed = true; + marketStructureDrawerConfig.drawTrueGaped = false; + marketStructureDrawerConfig.drawMomentum = false; + marketStructureDrawerConfig.drawFlagPattern = false; + marketStructureDrawerConfig.drawStarPattern = false; + marketStructureDrawerConfig.drawRisingPattern = false; + marketStructureDrawerConfig.drawPiercingPattern = false; + marketStructureDrawerConfig.drawSignalKeyBarPattern = true; + + // + // Recents ... + marketStructureDrawerConfig.drawRecentPatterns = false; + marketStructureDrawerConfig.drawFakeBreakedZone = false; + marketStructureDrawerConfig.drawRecentlyTestedZones = false; + marketStructureDrawerConfig.drawRecentlyBreakedZones = false; + + // + // XPV ... + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysis = true; + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisZones = true; + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisTrends = true; + marketStructureDrawerConfig.drawFIMAPVPivotsAnalysisPivots = true; + + // + // XSAR ... + marketStructureDrawerConfig.drawFIMASARPivotsAnalysis = false; + marketStructureDrawerConfig.drawFIMASARPivotsAnalysisZones = false; + marketStructureDrawerConfig.drawFIMASARPivotsAnalysisTrends = false; + marketStructureDrawerConfig.drawFIMASARPivotsAnalysisPivots = false; + + // + // XZigZag ... + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysis = true; + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisZones = true; + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisTrends = false; + marketStructureDrawerConfig.drawFIMAZigZagPivotsAnalysisPivots = false; + + // + // Analyse Market on Signalling Bar ... + fima1Signaller.poiDetector.AnalyseMarket( + bar, + marketStructure, + detectorConfig // + ); + + // + XFIMASIgballer2First(bar); + // HandleLookupSignal(bar); + + // + bar.Clean(); +} + +// +// Handle Signal Looking Up ... +// Register it as XFIMA Signaller 2 ... +void XFIMASIgballer2First(XOHCL &bar) +{ + // + bool has = + bar.IsValid(); + if (!has) + { + return; + } + + // + XBoxZone iZone; + XSignal iSignal; + string iName = NULL; + XBoxZone supports[]; + XBoxZone resistances[]; + bool isBullish = false; + int barIndex = bar.Index(); + double iPrice = EMPTY_VALUE; + ENUM_X_PRICE iPriceType = X_PRICE_NONE; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Check Required Pattern Exists ... + bool hasPinnedBar = HasDirection(marketStructure.pinnedDir); + bool hasEngulfedBar = HasDirection(marketStructure.engulfedDir); + bool hasFlagPattern = HasDirection(marketStructure.flagPatternDir); + bool hasStarPattern = HasDirection(marketStructure.starPatternDir); + bool hasRisingPattern = HasDirection(marketStructure.risingPatternDir); + bool hasPiercingPattern = HasDirection(marketStructure.piercingPatternDir); + bool hasSignalKeyBar = HasDirection(marketStructure.signalKeyBarPatternDir); + + // + // PV Trend Line ... + string pvTrendName = "XPVTrend"; + CChartObjectTrend *pvTrendLine = NULL; + ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE; + + // + // ZigZag Trend Line ... + string zgTrendName = "XZGTrend"; + CChartObjectTrend *zgTrendLine = NULL; + ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE; + + // + // Check PV Analysis ... + bool hasPVAnalysis = marketStructure.pvAnalysis.IsValid(); + if (hasPVAnalysis) + { + // + // Support ... + XBoxZone supportBox; + XCBoxObject *iSupportObj; + has = marketStructure.pvAnalysis.HasSupportBox(supportBox); + if (has) + { + // + supportBox.to = bar.time; + AddIfNotExists( + supportBox, + supports // + ); + has = fima2Signaller.poiDrawer.DrawBox( + supportBox, + iSupportObj, + true, // Ignore At ... + supportBox.type // Name ... + ); + if (has) + { + // + XPOIStyle iStyle; + fima2Signaller.poiDrawer.GetBoxStyle( + iStyle, + supportBox.dir // + ); + fima2Signaller.poiDrawer.ApplyBoxStyle( + iSupportObj, + iStyle // + ); + iStyle.Clean(); + } + } + + // + // Resistance ... + XBoxZone resistanceBox; + XCBoxObject *iResistanceObj; + has = marketStructure.pvAnalysis.HasResistanceBox(resistanceBox); + if (has) + { + // + resistanceBox.to = bar.time; + AddIfNotExists( + resistanceBox, + supports // + ); + has = fima2Signaller.poiDrawer.DrawBox( + resistanceBox, + iResistanceObj, + true, // Ignore At ... + resistanceBox.type // Name ... + ); + if (has) + { + // + XPOIStyle iStyle; + fima2Signaller.poiDrawer.GetBoxStyle( + iStyle, + resistanceBox.dir // + ); + fima2Signaller.poiDrawer.ApplyBoxStyle( + iResistanceObj, + iStyle // + ); + iStyle.Clean(); + } + } + + // + // Pivots ... + XPivot pivots[]; + int pivotsCount = fima2Signaller.poiDetector.ExtractPVPivots( + pivots, + barIndex, + 50 // + ); + has = IsValidSize(pivotsCount); + + // + // Sort ... + Sort( + pivots, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Remove Newest ... + ArrayRemove( + pivots, + 0, + 1 // + ); + + // + // Check Trend ... + if (has) + { + // + XPivot highs[]; + int highsCount = ExtractPivots( + highs, + pivots, + X_PIVOT_TYPE_PEAK // + ); + Sort( + highs, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + XPivot lows[]; + int lowsCount = ExtractPivots( + lows, + pivots, + X_PIVOT_TYPE_VALE // + ); + Sort( + lows, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Check Highs and Lows ... + has = IsValidSize(lowsCount) && + IsValidSize(highsCount) && + lowsCount >= 2 && + highsCount >= 2; + if (has) + { + // + // Try to Get Market Strucutre ... + + // + bool hasLowerHigh = highs[0].value < highs[1].value; + bool hasLowerLow = lows[0].value < lows[1].value; + + // + bool hasHigherHigh = highs[0].value > highs[1].value; + bool hasHigherLow = lows[0].value > lows[1].value; + + // + pvTrend = + (hasHigherHigh && + hasHigherLow) + ? X_DIRECTION_BULLISH + : (hasLowerHigh && + hasLowerLow) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(pvTrend); + if (has) + { + // + // Select Swings for Trend Line ... + XOHCL tmpBar; + int llIDX = -1; + int hhIDX = -1; + datetime toTime = NULL; + datetime fromTime = NULL; + double toPrice = EMPTY_VALUE; + color trendColor = CLR_NONE; + double fromPrice = EMPTY_VALUE; + if (IsSpecifiedBullish(pvTrend)) + { + // + llIDX = GetLowest(lows); + hhIDX = GetHighest(lows); + + // + trendColor = clrAqua; + + // + toTime = lows[hhIDX].time; + toPrice = lows[hhIDX].value; + + // + fromTime = lows[llIDX].time; + fromPrice = lows[llIDX].value; + } + else + { + // + llIDX = GetLowest(highs); + hhIDX = GetHighest(highs); + + // + trendColor = clrMagenta; + + // + toTime = highs[llIDX].time; + toPrice = highs[llIDX].value; + + // + fromTime = highs[hhIDX].time; + fromPrice = highs[hhIDX].value; + } + + // + // Check Requirements for Trend ... + has = + NotEmptyZero(toPrice) && + NotEmptyZero(fromPrice) && + IsSpecifiedValid(toTime) && + IsSpecifiedValid(fromTime); + if (has) + { + // + has = fima2Signaller.poiDrawer.DrawTrendLine( + fromPrice, + fromTime, + toPrice, + toTime, + pvTrendLine, + pvTrendName, + true // Ray Right ... + ); + if (has) + { + pvTrendLine.Color(trendColor); + } + } + + // + // Cleanup Resources ... + tmpBar.Clean(); + } + + // + if (!has) + { + SpecifiedClean(pivots); + } + } + + // + // Cleanup Resources ... + SpecifiedClean(lows); + SpecifiedClean(highs); + } + + // + // Draw Pivots ... + has = HasChild(pivots); + if (has) + { + // + CArrayObj *drawnPivots = new CArrayObj(); + pivotsCount = fima2Signaller.poiDrawer.DrawPivots( + pivots, + drawnPivots // + ); + } + + // + // Cleanup Resources ... + SpecifiedClean(pivots); + } + + // + // Check ZigZag Analysis ... + bool hasZGAnalysis = marketStructure.zigzagAnalysis.IsValid(); + if (hasZGAnalysis) + { + // + // Support ... + XBoxZone supportBox; + XCBoxObject *iSupportObj; + has = marketStructure.zigzagAnalysis.HasSupportBox(supportBox); + if (has) + { + // + supportBox.to = bar.time; + AddIfNotExists( + supportBox, + supports // + ); + has = fima2Signaller.poiDrawer.DrawBox( + supportBox, + iSupportObj, + true, // Ignore At ... + supportBox.type // Name ... + ); + if (has) + { + // + XPOIStyle iStyle; + fima2Signaller.poiDrawer.GetBoxStyle( + iStyle, + supportBox.dir // + ); + fima2Signaller.poiDrawer.ApplyBoxStyle( + iSupportObj, + iStyle // + ); + iStyle.Clean(); + } + } + + // + // Resistance ... + XBoxZone resistanceBox; + XCBoxObject *iResistanceObj; + has = marketStructure.zigzagAnalysis.HasResistanceBox(resistanceBox); + if (has) + { + // + resistanceBox.to = bar.time; + AddIfNotExists( + resistanceBox, + supports // + ); + has = fima2Signaller.poiDrawer.DrawBox( + resistanceBox, + iResistanceObj, + true, // Ignore At ... + resistanceBox.type // Name ... + ); + if (has) + { + // + XPOIStyle iStyle; + fima2Signaller.poiDrawer.GetBoxStyle( + iStyle, + resistanceBox.dir // + ); + fima2Signaller.poiDrawer.ApplyBoxStyle( + iResistanceObj, + iStyle // + ); + iStyle.Clean(); + } + } + + // + // Pivots ... + XPivot pivots[]; + int pivotsCount = fima2Signaller.poiDetector.ExtractZigZagPivots( + pivots, + barIndex, + 10 // + ); + has = IsValidSize(pivotsCount); + + // + // Sort ... + Sort( + pivots, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Remove Newest ... + ArrayRemove( + pivots, + 0, + 1 // + ); + + // + // Check Trend ... + if (has) + { + // + XPivot highs[]; + int highsCount = ExtractPivots( + highs, + pivots, + X_PIVOT_TYPE_PEAK // + ); + Sort( + highs, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + XPivot lows[]; + int lowsCount = ExtractPivots( + lows, + pivots, + X_PIVOT_TYPE_VALE // + ); + Sort( + lows, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Check Highs and Lows ... + has = IsValidSize(lowsCount) && + IsValidSize(highsCount) && + lowsCount >= 2 && + highsCount >= 2; + if (has) + { + // + // Try to Get Market Strucutre ... + + // + bool hasLowerHigh = highs[0].value < highs[1].value; + bool hasLowerLow = lows[0].value < lows[1].value; + + // + bool hasHigherHigh = highs[0].value > highs[1].value; + bool hasHigherLow = lows[0].value > lows[1].value; + + // + zgTrend = + (hasHigherHigh && + hasHigherLow) + ? X_DIRECTION_BULLISH + : (hasLowerHigh && + hasLowerLow) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(zgTrend); + if (has) + { + // + // Select Swings for Trend Line ... + XOHCL tmpBar; + int llIDX = -1; + int hhIDX = -1; + datetime toTime = NULL; + datetime fromTime = NULL; + double toPrice = EMPTY_VALUE; + color trendColor = CLR_NONE; + double fromPrice = EMPTY_VALUE; + if (IsSpecifiedBullish(zgTrend)) + { + // + llIDX = GetLowest(lows); + hhIDX = GetHighest(lows); + + // + trendColor = clrAqua; + + // + toTime = lows[hhIDX].time; + toPrice = lows[hhIDX].value; + + // + fromTime = lows[llIDX].time; + fromPrice = lows[llIDX].value; + } + else + { + // + llIDX = GetLowest(highs); + hhIDX = GetHighest(highs); + + // + trendColor = clrMagenta; + + // + toTime = highs[llIDX].time; + toPrice = highs[llIDX].value; + + // + fromTime = highs[hhIDX].time; + fromPrice = highs[hhIDX].value; + } + + // + // Check Requirements for Trend ... + has = + NotEmptyZero(toPrice) && + NotEmptyZero(fromPrice) && + IsSpecifiedValid(toTime) && + IsSpecifiedValid(fromTime); + if (has) + { + // + has = fima2Signaller.poiDrawer.DrawTrendLine( + fromPrice, + fromTime, + toPrice, + toTime, + zgTrendLine, + zgTrendName, + true // Ray Right ... + ); + if (has) + { + zgTrendLine.Color(trendColor); + } + } + + // + // Cleanup Resources ... + tmpBar.Clean(); + } + + // + if (!has) + { + SpecifiedClean(pivots); + } + } + + // + // Cleanup Resources ... + SpecifiedClean(lows); + SpecifiedClean(highs); + } + + // + // Draw Pivots ... + has = HasChild(pivots); + if (has) + { + // + CArrayObj *drawnPivots = new CArrayObj(); + pivotsCount = fima2Signaller.poiDrawer.DrawPivots( + pivots, + drawnPivots // + ); + } + + // + // Cleanup Resources ... + SpecifiedClean(pivots); + } + + // + // Support ... + bool hasSupport = marketStructure.support.IsValid(); + if (hasSupport) + { + // + AddIfNotExists( + marketStructure.support, + supports // + ); + + // + XCBoxObject *iObj; + has = fima2Signaller.poiDrawer.DrawBox( + marketStructure.support, + iObj); + if (has) + { + } + } + + // + // Resistance ... + bool hasResistance = marketStructure.resistance.IsValid(); + if (hasResistance) + { + // + AddIfNotExists( + marketStructure.resistance, + resistances // + ); + + // + XCBoxObject *iObj; + has = fima2Signaller.poiDrawer.DrawBox( + marketStructure.resistance, + iObj); + if (has) + { + } + } + + // + // Check Bar Pattern Exists ... + has = hasPinnedBar || + hasEngulfedBar || + hasFlagPattern || + hasStarPattern || + hasSignalKeyBar || + hasRisingPattern || + hasPiercingPattern; + + // + // Select Pattern Direction and Price and Price Type ... + if (has) + { + // + if (hasPinnedBar) + { + // + iDir = marketStructure.pinnedDir; + iName = "pinned" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasEngulfedBar) + { + // + iDir = marketStructure.engulfedDir; + iName = "engulfed" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasFlagPattern) + { + // + iDir = marketStructure.flagPatternDir; + iName = "flagPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasStarPattern) + { + // + iDir = marketStructure.starPatternDir; + iName = "starPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasSignalKeyBar) + { + // + iDir = marketStructure.risingPatternDir; + iName = "risingPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasRisingPattern) + { + // + iDir = marketStructure.piercingPatternDir; + iName = "piercingPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasPiercingPattern) + { + // + iDir = marketStructure.signalKeyBarPatternDir; + iName = "signalKeyBarPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); + } + + // + isBullish = IsSpecifiedBullish(iDir); + + // + // Retrieve Price Type for Validate ... + iPriceType = isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + iPrice = bar.GetPrice(iPriceType); + + // + has = HasDirection(iDir); + } + + // + // Validate Patterns based on MA Band ... + if (has) + { + // + // Retrieve MA Band for Validation ... + double iMABandUpper = fima2Signaller.fimaHelper.GetMABandUpper(barIndex); + double iMABandLower = fima2Signaller.fimaHelper.GetMABandLower(barIndex); + + // + // Validate ... + has = isBullish + ? iPrice < iMABandLower + : iPrice > iMABandUpper; + } + + // + // Select a Zone which Price inside it ... + + // + // Validate Happens in Zone ... + int insideZoneIDX = -1; + has = has && + (isBullish + ? HasInside( + insideZoneIDX, + bar, + supports // + ) + : HasInside( + insideZoneIDX, + bar, + resistances // + )); + + // + // Validate Selected Inside Zone ... + // whith Bars Edge ... + has = IsValidIndex(insideZoneIDX); + if (has) + { + // + if (isBullish) + { + iZone = supports[insideZoneIDX]; + } + else + { + iZone = resistances[insideZoneIDX]; + } + + // + has = isBullish + ? bar.high > supports[insideZoneIDX].upper + : bar.low < resistances[insideZoneIDX].lower; + } + + // + // Checking Liquidities ... + + // + // Draw Selected and Validated Bar and Selected Zone ... + if (has) + { + // + int iWidth = 1; + int iCode = 159; + color iClr = isBullish + ? clrYellow + : clrDarkOrange; + ENUM_ARROW_ANCHOR iAnchor = isBullish + ? ANCHOR_TOP + : ANCHOR_BOTTOM; + + // + XCBoxObject *iZoneObj; + XCBarArrowObject *iPatternObj; + + // + has = fima2Signaller.poiDrawer.DrawBarArrow( + bar, + iPatternObj, + iPriceType, + iCode, + iClr, + iWidth, + iAnchor, + iName, + true, // Ignore Bar Tag ... + 10 // Threshold ... + ); + if (has) + { + } + + // + has = fima2Signaller.poiDrawer.DrawBox( + iZone, + iZoneObj, + true, // Ignore At ... + iZone.type // Name ... + ); + if (has) + { + // + XPOIStyle iStyle; + fima2Signaller.poiDrawer.GetBoxStyle( + iStyle, + iZone.dir // + ); + iStyle.width = 2; + iStyle.clr = iClr; + fima2Signaller.poiDrawer.ApplyBoxStyle( + iZoneObj, + iStyle // + ); + } + } + + // + // Preparing Signal ... + if (has) + { + // + iSignal.time = bar.time; + iSignal.provider = "XFima"; + iSignal.symbol = bar.symbol; + iSignal.period = bar.period; + iSignal.mode = X_ORDER_MODE_MARKET; + iSignal.entry = GetEntry(bar.symbol, iDir); + iSignal.type = isBullish + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + iSignal.volume = 0.01; + + // + double _r2r = 2.0; + double _slDistanceInPoint = 5; + double _point = GetPoints(iSignal.symbol); + double _riskDistance = _slDistanceInPoint * _point; + double _risk = _riskDistance + MathAbs((isBullish ? iZone.lower : iZone.upper) - iSignal.entry); + double _reward = GetSpread(iSignal.symbol) + (_risk * _r2r); + + // + double sl = isBullish + ? iSignal.entry - _risk + : iSignal.entry + _risk; + double tp = isBullish + ? iSignal.entry + _reward + : iSignal.entry - _reward; + + // + iSignal.sl = sl; + iSignal.tp = tp; + + // + has = iSignal.IsValid(); + if (has) + { + // + XCSignalObject *iSignalObj; + has = fima2Signaller.poiDrawer.DrawSignal( + iSignal, + iSignalObj, + 7 // + ); + } + } + + // + // For Logging ... + if (has) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT eResult; + has = eaExpert.eaTrader.ExecuteSignal(iSignal, eResult); + Print("Detect a Potential Place for Price Movement: ", ToXString(iDir), ", Time: ", bar.time); + } + + // + // Cleanup Resources ... + iZone.Clean(); + iSignal.Clean(); + SpecifiedClean(supports); + SpecifiedClean(resistances); +} + +// +void HandleLookupSignal(XOHCL &bar) +{ + // + bool has = + bar.IsValid(); + if (!has) + { + return; + } + + // + XBoxZone iZone; + XSignal iSignal; + string iName = NULL; + bool isBullish = false; + bool isBearish = false; + int barIndex = bar.Index(); + double iPrice = EMPTY_VALUE; + XFIMAConditions fimaConditions; + ENUM_X_PRICE iPriceType = X_PRICE_NONE; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + int cIDX = 0; + int pIDX = cIDX + 1; + + // + // Check for a Cross ... + + // + // fima2Signaller.fimaHelper.Update(barIndex); + has = fima2Signaller.fimaHelper.GetConditions( + fimaConditions, + barIndex, + 5 // + ); + + // + double cSlowMA = fimaConditions.maSlowBuffer[cIDX]; + double pSlowMA = fimaConditions.maSlowBuffer[pIDX]; + + // + double cMAUpper = fimaConditions.maBandUpperBuffer[cIDX]; + double cMALower = fimaConditions.maBandLowerBuffer[cIDX]; + + // + double pMAUpper = fimaConditions.maBandUpperBuffer[pIDX]; + double pMALower = fimaConditions.maBandLowerBuffer[pIDX]; + + // + bool isCrossedOver = cSlowMA > cMALower && + pSlowMA < pMALower; + + // + bool isCrossedUnder = cSlowMA < cMAUpper && + cSlowMA > pMAUpper; + + // + has = isCrossedOver || + isCrossedUnder; + if (!has) + { + // + isBullish = false; + isBearish = false; + iDir = X_DIRECTION_NONE; + } + + // + if (has) + { + // + isBullish = isCrossedOver; + isBearish = isCrossedUnder; + } + + // + iDir = (isBullish && !isBearish) + ? X_DIRECTION_BULLISH + : (isBearish && !isBullish) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(iDir); + if (has) + { + Print("Conditions Detected ..."); + } + + // + // Cleanup Resources ... + fimaConditions.Clean(); +} + +// \ No newline at end of file diff --git a/Documents/BKP/x-saherelm.xfima.helper copy.mq5 b/Documents/BKP/x-saherelm.xfima.helper copy.mq5 new file mode 100644 index 00000000..00457858 --- /dev/null +++ b/Documents/BKP/x-saherelm.xfima.helper copy.mq5 @@ -0,0 +1,3820 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCXFIMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.x-helper.class.mq5" +#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" +#include "../Libraries/x-saherelm.x-poi.lib.mq5" + +// +// Definitions ... + +// +// Buffers ... +enum ENUM_XFIMA_BUFFERS +{ + XFIMA_MA_FAST_LINE = 0, + XFIMA_MA_FAST_COLOR_LINE = 1, + XFIMA_MA_FAST_STATE_LINE = 19, + XFIMA_MA_SLOW_LINE = 2, + XFIMA_MA_SLOW_COLOR_LINE = 3, + XFIMA_MA_SLOW_STATE_LINE = 20, + XFIMA_SAR_LINE = 4, + XFIMA_SAR_COLOR_LINE = 5, + XFIMA_SAR_STATE_LINE = 21, + XFIMA_PEAK_LINE = 6, + XFIMA_VALE_LINE = 7, + XFIMA_FIBO_UPPER_LINE = 8, + XFIMA_FIBO_MIDDLE_LINE = 9, + XFIMA_FIBO_LOWER_LINE = 10, + XFIMA_ZIGZAG_LINE = 11, + XFIMA_MA_BAND_UPPER_LINE = 12, + XFIMA_MA_BAND_LOWER_LINE = 13, + XFIMA_ZIGZAG_HIGHS_LINE = 30, + XFIMA_ZIGZAG_HIGHS_TIME_LINE = 31, + XFIMA_ZIGZAG_LOWS_LINE = 32, + XFIMA_ZIGZAG_LOWS_TIME_LINE = 33, + // + XFIMA_HK_OPEN_LINE = 14, + XFIMA_HK_HIGH_LINE = 15, + XFIMA_HK_LOW_LINE = 16, + XFIMA_HK_CLOSE_LINE = 17, + XFIMA_HK_COLOR_LINE = 18, + // 19 Ma Fast State + // 20 Ma Slow State + // 21 Sar State + XFIMA_SC_HH_LINE = 22, + XFIMA_SC_LL_LINE = 23, + XFIMA_MC_HH_LINE = 24, + XFIMA_MC_LL_LINE = 25, + XFIMA_LC_HH_LINE = 26, + XFIMA_LC_LL_LINE = 27, + XFIMA_HC_HH_LINE = 28, + XFIMA_HC_LL_LINE = 29, + // 30 ZigZag Highs + // 31 ZigZag Highs Time + // 32 ZigZag Lows + // 33 ZigZag Lows Time +}; + +// +// Input Models ... +struct XFIMAInputs +{ + // + // Props ... + + // + // Calculation ... + ENUM_X_PERIOD_METHOD scMethod; // How to Find Short Period + ENUM_TIMEFRAMES scPeriod; // Short Period + ENUM_X_PERIOD_METHOD mcMethod; // How to Find Medium Period + ENUM_TIMEFRAMES mcPeriod; // Medium Period + ENUM_X_PERIOD_METHOD lcMethod; // How to Find Long Period + ENUM_TIMEFRAMES lcPeriod; // Long Period + ENUM_X_PERIOD_METHOD hcMethod; // How to Find Hind Period + ENUM_TIMEFRAMES hcPeriod; // Hind Period + ENUM_SERIESMODE upperMode; // Peak Method + ENUM_SERIESMODE lowerMode; // Vale Method + ENUM_X_FIBO_LEVELS fiboUpperZoneLevel; // Upper Zone Level + ENUM_X_FIBO_LEVELS fiboMiddleZoneLevel; // Upper Zone Level + ENUM_X_FIBO_LEVELS fiboLowerZoneLevel; // Lower Zone Level + double sarStep; // SAR Step + double sarMax; // SAR Maximum + ENUM_MA_METHOD maMethod; // MA Method + ENUM_APPLIED_PRICE maAppliedTo; // MA Applied To + int maFastLength; // Fast MA Length + int maSlowLength; // Slow MA Length + int maBandLength; // MA Band Length + int zigzagDepth; // ZigZag Depth + int zigzagDeviation; // ZigZag Deviation + int zigzagBackStep; // ZigZag Back Step + ENUM_X_PRICE zigzagUppersMode; // ZigZag High Detect Mode + ENUM_X_PRICE zigzagLowersMode; // ZigZag Low Detect Mode + + // + // Presentation ... + bool showPV; // Show PV + bool showHK; // Show HK + bool showSAR; // Show Sar + bool showMAFast; // Show MA Fast + bool showMASlow; // Show MA Slow + bool showMABand; // Show MA Band + bool showZigZag; // Show ZigZag + bool showFiboZone; // Show Fibo Zone + int startCalculationForLastBars; // Calculate Last n Bars + int sarArrowCode; // Parabolic Sar Arrow Code + int peakArrowCode; // Peaks Arrow Code + int valeArrowCode; // Vales Arrow Code + + // + // Constructor(s) ... + XFIMAInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + // Calculations ... + scMethod = X_PERIOD_AUTO; // How to Find Short Period + scPeriod = NULL; // Short Period + mcMethod = X_PERIOD_AUTO; // How to Find Medium Period + mcPeriod = NULL; // Medium Period + lcMethod = X_PERIOD_AUTO; // How to Find Long Period + lcPeriod = NULL; // Long Period + hcMethod = X_PERIOD_AUTO; // How to Find Hind Period + hcPeriod = NULL; // Hind Period + upperMode = MODE_HIGH; // Peak Method + lowerMode = MODE_LOW; // Vale Method + fiboUpperZoneLevel = X_FIBO_LEVEL_382; // Upper Zone Level + fiboMiddleZoneLevel = X_FIBO_LEVEL_500; // Upper Zone Level + fiboLowerZoneLevel = X_FIBO_LEVEL_618; // Lower Zone Level + sarStep = 0.02; // SAR Step + sarMax = 0.2; // SAR Maximum + maMethod = MODE_EMA; // MA Method + maAppliedTo = PRICE_CLOSE; // MA Applied To + maFastLength = 7; // Fast MA Length + maSlowLength = 20; // Slow MA Length + maBandLength = 7; // MA Band Length + zigzagDepth = 12; // ZigZag Depth + zigzagDeviation = 5; // ZigZag Deviation + zigzagBackStep = 3; // ZigZag Back Step + zigzagUppersMode = X_PRICE_HIGH; // ZigZag High Detect Mode + zigzagLowersMode = X_PRICE_LOW; // ZigZag Low Detect Mode + + // + // Presentation ... + showPV = true; // Show PV + showHK = true; // Show HK + showSAR = true; // Show Sar + showMAFast = true; // Show MA Fast + showMASlow = true; // Show MA Slow + showMABand = true; // Show MA Band + showZigZag = true; // Show ZigZag + showFiboZone = true; // Show Fibo Zone + startCalculationForLastBars = 1500; // Calculate Last n Bars + sarArrowCode = 159; // Parabolic Sar Arrow Code + peakArrowCode = 159; // Peaks Arrow Code + valeArrowCode = 159; // Vales Arrow Code + } + + // + // Hide all Visible Buffers ... + void Hide() + { + // + showPV = false; + showHK = false; + showSAR = false; + showMAFast = false; + showMASlow = false; + showMABand = false; + showZigZag = false; + showFiboZone = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + // MA ... + maFastLength >= 2 && + maSlowLength >= 2 && + maBandLength >= 2 && + maSlowLength > maFastLength && + // + // SAR ... + sarMax > 0 && + sarStep > 0 && + sarMax > sarStep && + // + // CYCLES ... + (IsSpecifiedValid(scMethod, scPeriod) && + IsSpecifiedValid(mcMethod, mcPeriod) && + IsSpecifiedValid(lcMethod, lcPeriod) && + IsSpecifiedValid(hcMethod, hcPeriod)) && + // + // ZIGZAG ... + zigzagDepth > 0 && + zigzagDeviation > 0 && + zigzagBackStep > 0 && + // + // Validate Upper Mode Detection ... + IsXValid(zigzagUppersMode) && + // + // Validate Lower Mode Detection ... + IsXValid(zigzagLowersMode) + // + ; + + // + return result; + } +}; + +// +// Conditions ... +struct XFIMAConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + datetime to; + datetime from; + XOHCL bars[]; + + // + // Buffers ... + double maFastBuffer[]; + double maFastColorBuffer[]; + double maFastStateBuffer[]; + double maSlowBuffer[]; + double maSlowColorBuffer[]; + double maSlowStateBuffer[]; + double maBandUpperBuffer[]; + double maBandLowerBuffer[]; + double sarBuffer[]; + double sarColorBuffer[]; + double sarStateBuffer[]; + double peakBuffer[]; + double valeBuffer[]; + double fiboUpperBuffer[]; + double fiboMiddleBuffer[]; + double fiboLowerBuffer[]; + double zigzagBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + double highsBuffer[]; + double highsTimeBuffer[]; + double lowsBuffer[]; + double lowsTimeBuffer[]; + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkLowBuffer[]; + double hkCloseBuffer[]; + double hkColorBuffer[]; + + // + // Conditions ... + + // + // Constructor ... + XFIMAConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + to = NULL; + from = NULL; + time = NULL; + symbol = NULL; + period = NULL; + + // + // Buffers ... + + // + SpecifiedClean(bars); + + // + SpecifiedClean(maFastBuffer); + SpecifiedClean(maFastColorBuffer); + SpecifiedClean(maFastStateBuffer); + SpecifiedClean(maSlowBuffer); + SpecifiedClean(maSlowColorBuffer); + SpecifiedClean(maSlowStateBuffer); + SpecifiedClean(maBandUpperBuffer); + SpecifiedClean(maBandLowerBuffer); + SpecifiedClean(sarBuffer); + SpecifiedClean(sarColorBuffer); + SpecifiedClean(sarStateBuffer); + SpecifiedClean(peakBuffer); + SpecifiedClean(valeBuffer); + SpecifiedClean(fiboUpperBuffer); + SpecifiedClean(fiboMiddleBuffer); + SpecifiedClean(fiboLowerBuffer); + SpecifiedClean(zigzagBuffer); + SpecifiedClean(sHHBuffer); + SpecifiedClean(sLLBuffer); + SpecifiedClean(mHHBuffer); + SpecifiedClean(mLLBuffer); + SpecifiedClean(lHHBuffer); + SpecifiedClean(lLLBuffer); + SpecifiedClean(hHHBuffer); + SpecifiedClean(hLLBuffer); + SpecifiedClean(highsBuffer); + SpecifiedClean(highsTimeBuffer); + SpecifiedClean(lowsBuffer); + SpecifiedClean(lowsTimeBuffer); + SpecifiedClean(hkOpenBuffer); + SpecifiedClean(hkHighBuffer); + SpecifiedClean(hkLowBuffer); + SpecifiedClean(hkCloseBuffer); + SpecifiedClean(hkColorBuffer); + + // + // Conditions ... + + // + ArraySetAsSeries(bars, true); + + // + ArraySetAsSeries(maFastBuffer, true); + ArraySetAsSeries(maFastColorBuffer, true); + ArraySetAsSeries(maFastStateBuffer, true); + ArraySetAsSeries(maSlowBuffer, true); + ArraySetAsSeries(maSlowColorBuffer, true); + ArraySetAsSeries(maSlowStateBuffer, true); + ArraySetAsSeries(maBandUpperBuffer, true); + ArraySetAsSeries(maBandLowerBuffer, true); + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(sarColorBuffer, true); + ArraySetAsSeries(sarStateBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); + ArraySetAsSeries(fiboUpperBuffer, true); + ArraySetAsSeries(fiboMiddleBuffer, true); + ArraySetAsSeries(fiboLowerBuffer, true); + ArraySetAsSeries(zigzagBuffer, false); // Fix this ... + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + ArraySetAsSeries(hHHBuffer, true); + ArraySetAsSeries(hLLBuffer, true); + ArraySetAsSeries(highsBuffer, true); + ArraySetAsSeries(highsTimeBuffer, true); + ArraySetAsSeries(lowsBuffer, true); + ArraySetAsSeries(lowsTimeBuffer, true); + ArraySetAsSeries(hkOpenBuffer, true); + ArraySetAsSeries(hkHighBuffer, true); + ArraySetAsSeries(hkLowBuffer, true); + ArraySetAsSeries(hkCloseBuffer, true); + ArraySetAsSeries(hkColorBuffer, true); + + // + ZeroMemory(this); + } + + /** + * Generate Conditions Scores ... + * + * @param bullishScore: Double, Directional Scores Reference ... + * @param bearishScore: Double, Directional Scores Reference ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + } + + /** + * Generate Summary String for Represent Conditions State ... + * + * @param onlyCommons: Boolean, Just Generate Only Commons Conditions ... + * @param onlyConditions: Boolean, Just Generate Only Conditions ... + * @param includeScores: Boolean, Attach Scores Representations on Result ... + * @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ... + * @param separator: String, Separate Lines ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + return ""; + } + + /** + * Retrieve Unique Tag Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + return GetToken(this); + } +}; + +// +// Class ... +class XCXFIMAHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCXFIMAHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCXFIMAHelper() + { + } + + // + // Tools ... + + // + // Initialize Helper Cleass ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XFIMAInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xfima", + "", // Calculation ... + mInputs.scMethod, + mInputs.scPeriod, + mInputs.mcMethod, + mInputs.mcPeriod, + mInputs.lcMethod, + mInputs.lcPeriod, + mInputs.hcMethod, + mInputs.hcPeriod, + mInputs.upperMode, + mInputs.lowerMode, + mInputs.fiboUpperZoneLevel, + mInputs.fiboMiddleZoneLevel, + mInputs.fiboLowerZoneLevel, + mInputs.sarStep, + mInputs.sarMax, + mInputs.maMethod, + mInputs.maAppliedTo, + mInputs.maFastLength, + mInputs.maSlowLength, + mInputs.maBandLength, + mInputs.zigzagDepth, + mInputs.zigzagDeviation, + mInputs.zigzagBackStep, + mInputs.zigzagUppersMode, + mInputs.zigzagLowersMode, + "", // Presentation ... + mInputs.showPV, + mInputs.showHK, + mInputs.showSAR, + mInputs.showMAFast, + mInputs.showMASlow, + mInputs.showMABand, + mInputs.showZigZag, + mInputs.showFiboZone, + mInputs.startCalculationForLastBars, + mInputs.sarArrowCode, + mInputs.peakArrowCode, + mInputs.valeArrowCode + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XFIMAInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XFIMAInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs // + ); + } + + // + // Tools ... + + // + bool GetConditions( + XFIMAConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + // Filling Bars ... + int barsCount = GetBars( + conditions.bars, + mSymbol, + mPeriod, + barIndex, + loopback // + ); + result = barsCount == loopback; + if (!result) + { + // + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + conditions.to = conditions.bars[0].time; + conditions.from = conditions.bars[ArraySize(conditions.bars) - 1].time; + + // + int zIndex = barIndex; + + // + // Buffers ... + + // + CopyMAFast( + zIndex, + loopback, + conditions.maFastBuffer // + ); + + // + CopyMAFastState( + zIndex, + loopback, + conditions.maFastStateBuffer // + ); + + // + CopyMASlow( + zIndex, + loopback, + conditions.maSlowBuffer // + ); + + // + CopyMASlowState( + zIndex, + loopback, + conditions.maSlowStateBuffer // + ); + + // + CopyMABandUpper( + zIndex, + loopback, + conditions.maBandUpperBuffer // + ); + + // + CopyMABandLower( + zIndex, + loopback, + conditions.maBandLowerBuffer // + ); + + // + CopySar( + zIndex, + loopback, + conditions.sarBuffer // + ); + + // + CopySarState( + zIndex, + loopback, + conditions.sarStateBuffer // + ); + + // + CopyPeak( + zIndex, + loopback, + conditions.peakBuffer // + ); + + // + CopyVale( + zIndex, + loopback, + conditions.valeBuffer // + ); + + // + CopyFiboUpper( + zIndex, + loopback, + conditions.fiboUpperBuffer // + ); + + // + CopyFiboMiddle( + zIndex, + loopback, + conditions.fiboMiddleBuffer // + ); + + // + CopyFiboLower( + zIndex, + loopback, + conditions.fiboLowerBuffer // + ); + + // + CopyZigZag( + zIndex, + loopback, + conditions.zigzagBuffer // + ); + + // + CopySHH( + zIndex, + loopback, + conditions.sHHBuffer // + ); + + // + CopySLL( + zIndex, + loopback, + conditions.sLLBuffer // + ); + + // + CopyMHH( + zIndex, + loopback, + conditions.mHHBuffer // + ); + + // + CopyMLL( + zIndex, + loopback, + conditions.mLLBuffer // + ); + + // + CopyLHH( + zIndex, + loopback, + conditions.lHHBuffer // + ); + + // + CopyLLL( + zIndex, + loopback, + conditions.lLLBuffer // + ); + + // + CopyHHH( + zIndex, + loopback, + conditions.hHHBuffer // + ); + + // + CopyHLL( + zIndex, + loopback, + conditions.hLLBuffer // + ); + + // + CopyHKOpen( + zIndex, + loopback, + conditions.hkOpenBuffer // + ); + + // + CopyHKHigh( + zIndex, + loopback, + conditions.hkHighBuffer // + ); + + // + CopyHKLow( + zIndex, + loopback, + conditions.hkLowBuffer // + ); + + // + CopyHKClose( + zIndex, + loopback, + conditions.hkCloseBuffer // + ); + + // + CopyHKColor( + zIndex, + loopback, + conditions.hkColorBuffer // + ); + + // + // Conditions ... + + // + return result; + } + + // + // Pivot Actions ... + + /** + * Check Specified Bar has MA Cross or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ... + * + * @return ( bool ) + */ + bool HasMACross( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + double validCrossDiffMultiplier = 1 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0); + + // + double fast[]; + double slow[]; + double upper[]; + double lower[]; + int count = ReadMAValues( + fast, + slow, + upper, + lower, + barIndex, + 2 // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + bool notEmpty = + NotEmptyZero(fast[0]) && + NotEmptyZero(fast[1]) && + NotEmptyZero(slow[0]) && + NotEmptyZero(slow[1]); + + // + isBullish = + notEmpty && + fast[0] > slow[0] && + fast[1] < slow[1]; + + // + isBearish = + notEmpty && + fast[0] < slow[0] && + fast[1] > slow[1]; + + // + result = + isBullish || + isBearish; + + // + // Validate Direction Change ... + if (result && + validCrossDiffMultiplier > 0) + { + // + double _points = GetPoints(GetSymbol()); + double diff = MathAbs(fast[0] - slow[0]); + + // + result = diff >= (validCrossDiffMultiplier * _points); + } + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(fast); + XClean(slow); + XClean(upper); + XClean(lower); + + // + return result; + } + + /** + * Check Specified Bar has HK Switch or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool HasHKSwitch( + ENUM_X_DIRECTION &dir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + double low[]; + double open[]; + double high[]; + double close[]; + int count = ReadHKBars( + open, + high, + low, + close, + barIndex, + 2 // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + bool notEmpty = + NotEmptyZero(open[0]) && + NotEmptyZero(open[1]) && + NotEmptyZero(close[0]) && + NotEmptyZero(close[1]); + + // + isBullish = + notEmpty && + open[0] < close[0] && + open[1] > close[1]; + + // + isBearish = + notEmpty && + open[0] > close[0] && + open[1] < close[1]; + + // + result = + isBullish || + isBearish; + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(low); + XClean(open); + XClean(high); + XClean(close); + + // + return result; + } + + /** + * Check Specified Bar has SAR Switch or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool HasSARSwitch( + ENUM_X_DIRECTION &dir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + double sars[]; + int count = CopyBuffer( + mHandler, + XFIMA_SAR_STATE_LINE, + barIndex, + 2, + sars // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + isBullish = + sars[0] >= 1 && + sars[1] <= -1; + + // + isBearish = + sars[0] <= -1 && + sars[1] >= 1; + + // + result = + isBullish || + isBearish; + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(sars); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * + * @return ( int ) + */ + int ExtractPVPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500, + int validationLength = 0 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validationLength = NormalizeInt(validationLength, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + bool lookupPeaks = true; + bool lookupVales = true; + + // + XOHCL iBar; + XPivot iPivot; + bool has = false; + int idx = barIndex - 1; + int samePeaksCount = 0; + int sameValesCount = 0; + double tmpPeaksBuffer[]; + double tmpValesBuffer[]; + string symbol = GetSymbol(); + double iPValue = EMPTY_VALUE; + double iVValue = EMPTY_VALUE; + double pPValue = EMPTY_VALUE; + double pVValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + if (!has) + { + continue; + } + + // + // Detecting ... + + // + // Peak ... + if (lookupPeaks) + { + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_PEAK_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpPeaksBuffer // Buffer ... + ); + ArraySetAsSeries(tmpPeaksBuffer, true); + + // + // Reading Values ... + iPValue = tmpPeaksBuffer[0]; + pPValue = tmpPeaksBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iPValue)) + { + // + // Check New Peak ... + has = + !NotEmptyZero(pPValue) + ? true + : iPValue != pPValue; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + iPValue == iBar.high + ? X_PIVOT_TYPE_PEAK + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // Check Validation Length ... + has = + has && + (validationLength <= 0 + ? true + : samePeaksCount >= validationLength); + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iPValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + samePeaksCount = 0; + } + else if (iPValue == pPValue) + { + samePeaksCount++; + } + } + } + + // + // Vale ... + if (lookupVales) + { + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_VALE_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpValesBuffer // Buffer ... + ); + ArraySetAsSeries(tmpValesBuffer, true); + + // + // Reading Values ... + iVValue = tmpValesBuffer[0]; + pVValue = tmpValesBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iVValue)) + { + // + // Check New Vale ... + has = + !NotEmptyZero(pVValue) + ? true + : iVValue != pVValue; + if (has) + { + // + // Calculate and Validate Type ... + // Vales Only Valid when Confirmed by Bar Low ... + iType = + iVValue == iBar.low + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // Check Validation Length ... + has = + has && + (validationLength <= 0 + ? true + : sameValesCount >= validationLength); + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iVValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + sameValesCount = 0; + } + else if (iVValue == pVValue) + { + sameValesCount++; + } + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractMAPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + double validCrossDiffMultiplier = 1, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + double fast[]; + double slow[]; + XPivot iPivot; + int count = 0; + double upper[]; + double lower[]; + bool has = false; + int idx = barIndex - 1; + datetime iPivotTime = NULL; + string symbol = GetSymbol(); + double iFValue = EMPTY_VALUE; + double pFValue = EMPTY_VALUE; + double iSValue = EMPTY_VALUE; + double pSValue = EMPTY_VALUE; + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + double iSelectedValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iPivot.Clean(); + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Reading Buffer ... + count = ReadMAValues( + fast, + slow, + upper, + lower, + idx, + 2 // + ); + has = IsValidSize(count); + + // + // Reading Values ... + + // + iFValue = fast[0]; + pFValue = fast[1]; + + // + iSValue = slow[0]; + pSValue = slow[1]; + + // + // Validate Value ... + has = + HasMACross( + iDir, + idx, + validCrossDiffMultiplier // + ) && + NotEmptyZero(iFValue) && + NotEmptyZero(iSValue) && + NotEmptyZero(pFValue) && + NotEmptyZero(pSValue); + if (has) + { + // + // Check Direction Changed ... + isSwitchedToBullish = IsXBullish(iDir); + isSwitchedToBearish = IsXBearish(iDir); + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + if (has) + { + // + iPivotTime = GetBarTime( + symbol, + period, + idx // + ); + + // + // Select Value based on Pivot Type ... + iSelectedValue = IsXPeak(iType) + ? MathMax(iFValue, iSValue) + : MathMin(iFValue, iSValue); + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iSelectedValue, + iPivotTime, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractHKPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + double low[]; + double open[]; + XPivot iPivot; + int count = 0; + double high[]; + double close[]; + bool has = false; + int idx = barIndex - 1; + datetime iPivotTime = NULL; + string symbol = GetSymbol(); + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + double iSelectedValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iPivot.Clean(); + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Reading Buffer ... + count = ReadHKBars( + open, + high, + low, + close, + idx, + 2 // + ); + has = IsValidSize(count); + + // + // Validate Value ... + has = + HasHKSwitch( + iDir, + idx // + ) && + NotEmptyZero(open[0]) && + NotEmptyZero(open[1]) && + NotEmptyZero(close[0]) && + NotEmptyZero(close[1]); + if (has) + { + // + // Check Direction Changed ... + isSwitchedToBullish = IsXBullish(iDir); + isSwitchedToBearish = IsXBearish(iDir); + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + if (has) + { + // + iPivotTime = GetBarTime( + symbol, + period, + idx // + ); + + // + // Select Value based on Pivot Type ... + iSelectedValue = IsXPeak(iType) + ? MathMax(open[0], close[0]) + : MathMin(open[0], close[0]); + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iSelectedValue, + iPivotTime, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractSARPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + XOHCL iBar; + XOHCL pBar; + XPivot iPivot; + bool has = false; + double tmpSarBuffer[]; + int idx = barIndex - 1; + string symbol = GetSymbol(); + double iValue = EMPTY_VALUE; + double pValue = EMPTY_VALUE; + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + has = + has && + iBar.GetPreviousBar(pBar); + if (!has) + { + continue; + } + + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_SAR_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpSarBuffer // Buffer ... + ); + ArraySetAsSeries(tmpSarBuffer, true); + + // + // Reading Values ... + iValue = tmpSarBuffer[0]; + pValue = tmpSarBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iValue)) + { + // + // Check Sar Direction Changed ... + isSwitchedToBullish = iValue < iBar.low && + pValue > pBar.high; + isSwitchedToBearish = iValue > iBar.high && + pValue < pBar.low; + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // TODO: we can also Add other Validations Here ... + + // + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractZigZagPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + XOHCL iBar; + XPivot iPivot; + bool has = false; + int idx = barIndex - 1; + double tmpZigZagBuffer[]; + double iValue = EMPTY_VALUE; + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + if (!has) + { + continue; + } + + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_ZIGZAG_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 1, // Number of Requirements ... + tmpZigZagBuffer // Buffer ... + ); + ArraySetAsSeries(tmpZigZagBuffer, true); + + // + // Read and Validate Value ... + iValue = tmpZigZagBuffer[0]; + has = NotEmptyZero(iValue); + if (!has) + { + // + iBar.Clean(); + SpecifiedClean(tmpZigZagBuffer); + continue; + } + + // + // Calculate and Validate Type ... + iType = + iValue == iBar.high + ? X_PIVOT_TYPE_PEAK + : iValue == iBar.low + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + if (!has) + { + // + iBar.Clean(); + SpecifiedClean(tmpZigZagBuffer); + continue; + } + + // + // Calculate and Validate Dir ... + iDir = + IsXVale(iType) + ? X_DIRECTION_BULLISH + : IsXPeak(iType) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(iDir); + if (!has) + { + // + iBar.Clean(); + SpecifiedClean(tmpZigZagBuffer); + continue; + } + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + return result; + } + + /** + * Extract Validated Zones ... + * + * @param zones: XBoxZone, collection reference to holds results ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFZones: int, required Number of Zones ... + * @param breakValidLength: int, Breake Validation Length of Zones ... + * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... + * @param shadowMultiplier: double a Shadow Multiplier for Validation ... + * @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ... + * @param validationLength: int, Validation Length of Zones ... + * @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ... + * + * @return ( int ) + */ + int ExtractHKZones( + XBoxZone &zones[], + int barIndex = 0, + int requiredNumberOFZones = 50, + int breakValidLength = 3, + bool validateFakeBreakes = true, + double shadowMultiplier = 3, + double validationStrength = 1, + int validationLength = 21, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(zones); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validationLength = NormalizeInt(validationLength, 7); + shadowMultiplier = NormalizeDouble(shadowMultiplier, 1); + validationStrength = NormalizeDouble(validationStrength, 1); + requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100); + + // + // Reading Values ... + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + double minAllowedStrength = (validationStrength * GetPoints(symbol)); + + // + int count = 0; + XBoxZone zone; + double hkLows[]; + bool has = false; + double hkOpens[]; + double hkHighs[]; + double hkCloses[]; + int start = barIndex; + bool isBullish = false; + bool isBearish = false; + double up = EMPTY_VALUE; + double down = EMPTY_VALUE; + double body = EMPTY_VALUE; + double range = EMPTY_VALUE; + bool lowShadowPassed = false; + bool highShadowPassed = false; + double lowShadow = EMPTY_VALUE; + double highShadow = EMPTY_VALUE; + double startHKLow = EMPTY_VALUE; + double startHKOpen = EMPTY_VALUE; + double startHKHigh = EMPTY_VALUE; + double startHKClose = EMPTY_VALUE; + ENUM_X_DIRECTION dir = X_DIRECTION_NONE; + int end = start + maxAllowedLoopbackLength; + for (int i = start; i < end; i++) + { + // + // Cleanup ... + zone.Clean(); + dir = X_DIRECTION_NONE; + + // + // Reading HK Buffesr ... + count = ReadHKBars( + hkOpens, + hkHighs, + hkLows, + hkCloses, + i, + 1 // + ); + has = IsValidSize(count); + if (!has) + { + continue; + } + + // + // Initialized Start Bar ... + if (i == start) + { + // + startHKLow = hkLows[0]; + startHKOpen = hkOpens[0]; + startHKHigh = hkHighs[0]; + startHKClose = hkCloses[0]; + } + + // + // Check Direction ... + isBullish = hkOpens[0] < hkCloses[0]; + isBearish = hkOpens[0] > hkCloses[0]; + dir = + (isBullish && !isBearish) + ? X_DIRECTION_BULLISH + : (isBearish && !isBullish) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(dir); + if (!has) + { + continue; + } + + // + // Calculate Requirements for Processing ... + up = isBullish + ? hkCloses[0] + : hkOpens[0]; + down = isBullish + ? hkOpens[0] + : hkCloses[0]; + body = MathAbs(up - down); + range = hkHighs[0] - hkLows[0]; + highShadow = hkHighs[0] - up; + lowShadow = down - hkLows[0]; + + // + // Detecting Shadows ... + + // + // Low Shadow ... + lowShadowPassed = lowShadow >= (shadowMultiplier * highShadow); + + // + // High Shadow ... + highShadowPassed = highShadow >= (shadowMultiplier * lowShadow); + + // + has = (lowShadowPassed && !highShadowPassed) || + (highShadowPassed && !lowShadowPassed); + if (!has) + { + continue; + } + + // + // Filling Zone ... + + // + zone.symbol = symbol; + zone.period = period; + zone.from = GetBarTime( + zone.symbol, + zone.period, + i // + ); + zone.dir = lowShadowPassed + ? X_DIRECTION_BULLISH + : highShadowPassed + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + zone.upper = + IsXBullish(zone.dir) + ? down + : IsXBearish(zone.dir) + ? hkHighs[0] + : EMPTY_VALUE; + + // + zone.lower = + IsXBullish(zone.dir) + ? hkLows[0] + : IsXBearish(zone.dir) + ? up + : EMPTY_VALUE; + + // + zone.to = TimeCurrent(); + zone.type = "XHK_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance" + : "") + + "_" + ToXString(TimeToSeconds(zone.from)); + + // + // Validate ... + has = + zone.IsValid() && + HasDirection(zone.dir) && + NotEmptyZero(zone.upper) && + NotEmptyZero(zone.lower) && + (zone.IsBullish() + ? startHKLow > zone.upper + : startHKHigh < zone.lower) && + (zone.upper - zone.lower) >= minAllowedStrength && + ValidateHKZone(zone, validationLength, breakValidLength, validateFakeBreakes); + if (has) + { + // + AddIfNotExists( + zone, + zones // + ); + } + + // + // Cleanup Resources ... + zone.Clean(); + + // + // Validating ... + result = ArraySize(zones); + has = IsValidSize(result) && + result >= requiredNumberOFZones; + if (has) + { + break; + } + } + + // + // Cleanup Resources ... + zone.Clean(); + SpecifiedClean(hkLows); + SpecifiedClean(hkOpens); + SpecifiedClean(hkHighs); + SpecifiedClean(hkCloses); + + // + return result; + } + + // + // Values Retrievers ... + + // + // Fast MA ... + + // + double GetMAFast( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MA_FAST_LINE, + barIndex // + ); + } + + // + int CopyMAFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MA_FAST_LINE, + start, + count, + asSeries // + ); + } + + // + // Fast MA State ... + + // + double GetMAFastState( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MA_FAST_STATE_LINE, + barIndex // + ); + } + + // + int CopyMAFastState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MA_FAST_STATE_LINE, + start, + count, + asSeries // + ); + } + + // + // Slow MA ... + + // + double GetMASlow( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MA_SLOW_LINE, + barIndex // + ); + } + + // + int CopyMASlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MA_SLOW_LINE, + start, + count, + asSeries // + ); + } + + // + // Slow MA State ... + + // + double GetMASlowState( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MA_SLOW_STATE_LINE, + barIndex // + ); + } + + // + int CopyMASlowState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MA_SLOW_STATE_LINE, + start, + count, + asSeries // + ); + } + + // + // Upper MA ... + + // + double GetMABandUpper( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MA_BAND_UPPER_LINE, + barIndex // + ); + } + + // + int CopyMABandUpper( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MA_BAND_UPPER_LINE, + start, + count, + asSeries // + ); + } + + // + // Lower MA ... + + // + double GetMABandLower( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MA_BAND_LOWER_LINE, + barIndex // + ); + } + + // + int CopyMABandLower( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MA_BAND_LOWER_LINE, + start, + count, + asSeries // + ); + } + + // + // SAR ... + + // + double GetSar( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_SAR_LINE, + barIndex // + ); + } + + // + int CopySar( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_SAR_LINE, + start, + count, + asSeries // + ); + } + + // + // SAR State ... + + // + double GetSarState( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_SAR_STATE_LINE, + barIndex // + ); + } + + // + int CopySarState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_SAR_STATE_LINE, + start, + count, + asSeries // + ); + } + + // + // PEAK ... + + // + double GetPeak( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_PEAK_LINE, + barIndex // + ); + } + + // + int CopyPeak( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_PEAK_LINE, + start, + count, + asSeries // + ); + } + + // + // VALE ... + + // + double GetVale( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_VALE_LINE, + barIndex // + ); + } + + // + int CopyVale( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_VALE_LINE, + start, + count, + asSeries // + ); + } + + // + // FIBO Zone ... + + // + // FIBO Upper ... + + // + double GetFiboUpper( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_FIBO_UPPER_LINE, + barIndex // + ); + } + + // + int CopyFiboUpper( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_FIBO_UPPER_LINE, + start, + count, + asSeries // + ); + } + + // + // FIBO Middle ... + + // + double GetFiboMiddle( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_FIBO_MIDDLE_LINE, + barIndex // + ); + } + + // + int CopyFiboMiddle( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_FIBO_MIDDLE_LINE, + start, + count, + asSeries // + ); + } + + // + // FIBO Lower ... + + // + double GetFiboLower( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_FIBO_LOWER_LINE, + barIndex // + ); + } + + // + int CopyFiboLower( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_FIBO_LOWER_LINE, + start, + count, + asSeries // + ); + } + + // + // ZigZag ... + + // + double GetZigZag( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_ZIGZAG_LINE, + barIndex // + ); + } + + // + int CopyZigZag( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_ZIGZAG_LINE, + start, + count, + asSeries // + ); + } + + // + // CYCLES Range ... + + // + // SHORT ... + + // + // HH ... + + // + double GetSHH( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_SC_HH_LINE, + barIndex // + ); + } + + // + int CopySHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_SC_HH_LINE, + start, + count, + asSeries // + ); + } + + // + // LL ... + + // + double GetSLL( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_SC_LL_LINE, + barIndex // + ); + } + + // + int CopySLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_SC_LL_LINE, + start, + count, + asSeries // + ); + } + + // + // MEDIUM ... + + // + // HH ... + + // + double GetMHH( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MC_HH_LINE, + barIndex // + ); + } + + // + int CopyMHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MC_HH_LINE, + start, + count, + asSeries // + ); + } + + // + // LL ... + + // + double GetMLL( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_MC_LL_LINE, + barIndex // + ); + } + + // + int CopyMLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_MC_LL_LINE, + start, + count, + asSeries // + ); + } + + // + // LONG ... + + // + // HH ... + + // + double GetLHH( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_LC_HH_LINE, + barIndex // + ); + } + + // + int CopyLHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_LC_HH_LINE, + start, + count, + asSeries // + ); + } + + // + // LL ... + + // + double GetLLL( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_LC_LL_LINE, + barIndex // + ); + } + + // + int CopyLLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_LC_LL_LINE, + start, + count, + asSeries // + ); + } + + // + // HIND ... + + // + // HH ... + + // + double GetHHH( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_HC_HH_LINE, + barIndex // + ); + } + + // + int CopyHHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_HC_HH_LINE, + start, + count, + asSeries // + ); + } + + // + // LL ... + + // + double GetHLL( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_HC_LL_LINE, + barIndex // + ); + } + + // + int CopyHLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_HC_LL_LINE, + start, + count, + asSeries // + ); + } + + // + // XHK ... + + // + // XHK Open ... + + // + double GetHKOpen( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_HK_OPEN_LINE, + barIndex // + ); + } + + // + int CopyHKOpen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_HK_OPEN_LINE, + start, + count, + asSeries // + ); + } + + // + // XHK High ... + + // + double GetHKHigh( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_HK_HIGH_LINE, + barIndex // + ); + } + + // + int CopyHKHigh( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_HK_HIGH_LINE, + start, + count, + asSeries // + ); + } + + // + // XHK Low ... + + // + double GetHKLow( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_HK_LOW_LINE, + barIndex // + ); + } + + // + int CopyHKLow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_HK_LOW_LINE, + start, + count, + asSeries // + ); + } + + // + // XHK Close ... + + // + double GetHKClose( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_HK_CLOSE_LINE, + barIndex // + ); + } + + // + int CopyHKClose( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_HK_CLOSE_LINE, + start, + count, + asSeries // + ); + } + + // + // XHK Color ... + + // + double GetHKColor( + int barIndex // Bar Index + ) + { + // + return ReadValue( + (int)XFIMA_HK_COLOR_LINE, + barIndex // + ); + } + + // + int CopyHKColor( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag + ) + { + // + return ReadValues( + buffer, + (int)XFIMA_HK_COLOR_LINE, + start, + count, + asSeries // + ); + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + XFIMAInputs mInputs; // Inputs ... + + // + // XHK Helper ... + + // + int ReadHKBars( + double &open[], + double &high[], + double &low[], + double &close[], + int barIndex = 0, + int count = 1 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + // Normalize ... + count = NormalizeInt(count, 1); + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + // Open ... + CopyBuffer( + mHandler, + XFIMA_HK_OPEN_LINE, + barIndex, + count, + open // + ); + + // + // High ... + CopyBuffer( + mHandler, + XFIMA_HK_HIGH_LINE, + barIndex, + count, + high // + ); + + // + // Low ... + CopyBuffer( + mHandler, + XFIMA_HK_LOW_LINE, + barIndex, + count, + low // + ); + + // + // Close ... + CopyBuffer( + mHandler, + XFIMA_HK_CLOSE_LINE, + barIndex, + count, + close // + ); + + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + + // + // Min Number of Array Sizes ... + result = MathMin(ArraySize(open), ArraySize(high)); + result = MathMin(result, ArraySize(close)); + result = MathMin(result, ArraySize(low)); + + // + return result; + } + + /** + * Validate HK Zone ... + * + * @param zone: XBoxZone, reference to Specified Zone ... + * @param validationLength: int, Validation Length of Zones ... + * @param breakValidLength: int, Break Validation Length of Zones ... + * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... + * + * @return ( bool ) + */ + bool ValidateHKZone( + XBoxZone &zone, + int validationLength = 1, + int breakValidLength = 3, + bool validateFakeBreakes = true // + ) + { + // + bool result = false; + + // + // Normalize ... + validationLength = NormalizeInt(validationLength, 1); + breakValidLength = NormalizeInt(breakValidLength, 2); + + // + // Validate ... + result = zone.IsValid(); + if (!result) + { + return result; + } + + // + // Requirements ... + double low[]; + double open[]; + double high[]; + int count = 0; + double close[]; + + // + int start = zone.FromIndex() + 1; + int end = start + validationLength; + + // + // Validate Before ... + for (int i = start; i < end; i++) + { + // + // Reading HK ... + count = ReadHKBars( + open, + high, + low, + close, + i, + 1 // + ); + result = IsValidSize(count); + if (!result) + { + break; + } + + // + result = zone.IsBullish() + ? low[0] > zone.lower + : high[0] < zone.upper; + if (!result) + { + break; + } + } + + // + // Validating After ... + if (result) + { + // + start = zone.ToIndex() + 1; + count = zone.FromIndex() - start; + end = start + count; + for (int i = start; i < end; i++) + { + // + // Reading HK ... + count = ReadHKBars( + open, + high, + low, + close, + i, + 1 // + ); + result = IsValidSize(count); + if (!result) + { + break; + } + + // + result = zone.IsBullish() + ? low[0] > zone.lower + : high[0] < zone.upper; + if (!result) + { + // + // Check For Fake Breake ... + if (validateFakeBreakes && breakValidLength > 0) + { + // + result = i - 1 >= 0; + if (result) + { + // + for (int j = i - 1; j >= zone.ToIndex(); j--) + { + // + // Reading HK ... + count = ReadHKBars( + open, + high, + low, + close, + j, + 1 // + ); + result = IsValidSize(count); + if (!result) + { + break; + } + + // + result = zone.IsBullish() + ? close[0] > zone.upper + : close[0] < zone.lower; + if (result) + { + // + result = MathAbs(j - i) <= breakValidLength; + if (result) + { + break; + } + } + } + } + } + + // + if (!result) + { + break; + } + } + } + } + + // + // Cleanup Resource ... + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + return result; + } + + // + int ReadMAValues( + double &fast[], + double &slow[], + double &upper[], + double &lower[], + int barIndex = 0, + int count = 0 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + // Normalize ... + count = NormalizeInt(count, 1); + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + CopyBuffer( + mHandler, + XFIMA_MA_FAST_LINE, + barIndex, + count, + fast // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_SLOW_LINE, + barIndex, + count, + slow // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_BAND_UPPER_LINE, + barIndex, + count, + upper // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_BAND_LOWER_LINE, + barIndex, + count, + lower // + ); + + // + ArraySetAsSeries(fast, true); + ArraySetAsSeries(slow, true); + ArraySetAsSeries(upper, true); + ArraySetAsSeries(lower, true); + + // + result = MathMin(ArraySize(fast), ArraySize(slow)); + result = MathMin(result, ArraySize(upper)); + result = MathMin(result, ArraySize(lower)); + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/x-saherelm.xfima.helper.mq5 b/Documents/BKP/x-saherelm.xfima.helper.mq5 new file mode 100644 index 00000000..f9033b99 --- /dev/null +++ b/Documents/BKP/x-saherelm.xfima.helper.mq5 @@ -0,0 +1,4974 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCXFIMAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.x-helper.class.mq5" +#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" +#include "../Libraries/x-saherelm.x-poi.lib.mq5" + +// +// Definitions ... + +// +// Buffers ... +enum ENUM_XFIMA_BUFFERS +{ + XFIMA_MA_FAST_LINE = 0, + XFIMA_MA_FAST_COLOR_LINE = 1, + XFIMA_MA_FAST_STATE_LINE = 19, + XFIMA_MA_SLOW_LINE = 2, + XFIMA_MA_SLOW_COLOR_LINE = 3, + XFIMA_MA_SLOW_STATE_LINE = 20, + XFIMA_SAR_LINE = 4, + XFIMA_SAR_COLOR_LINE = 5, + XFIMA_SAR_STATE_LINE = 21, + XFIMA_PEAK_LINE = 6, + XFIMA_VALE_LINE = 7, + XFIMA_FIBO_UPPER_LINE = 8, + XFIMA_FIBO_MIDDLE_LINE = 9, + XFIMA_FIBO_LOWER_LINE = 10, + XFIMA_ZIGZAG_LINE = 11, + XFIMA_MA_BAND_UPPER_LINE = 12, + XFIMA_MA_BAND_LOWER_LINE = 13, + XFIMA_ZIGZAG_HIGHS_LINE = 30, + XFIMA_ZIGZAG_HIGHS_TIME_LINE = 31, + XFIMA_ZIGZAG_LOWS_LINE = 32, + XFIMA_ZIGZAG_LOWS_TIME_LINE = 33, + // + XFIMA_HK_OPEN_LINE = 14, + XFIMA_HK_HIGH_LINE = 15, + XFIMA_HK_LOW_LINE = 16, + XFIMA_HK_CLOSE_LINE = 17, + XFIMA_HK_COLOR_LINE = 18, + // 19 Ma Fast State + // 20 Ma Slow State + // 21 Sar State + XFIMA_SC_HH_LINE = 22, + XFIMA_SC_LL_LINE = 23, + XFIMA_MC_HH_LINE = 24, + XFIMA_MC_LL_LINE = 25, + XFIMA_LC_HH_LINE = 26, + XFIMA_LC_LL_LINE = 27, + XFIMA_HC_HH_LINE = 28, + XFIMA_HC_LL_LINE = 29, + // 30 ZigZag Highs + // 31 ZigZag Highs Time + // 32 ZigZag Lows + // 33 ZigZag Lows Time +}; + +// +// Input Models ... +struct XFIMAInputs +{ + // + // Props ... + + // + // Calculation ... + ENUM_X_PERIOD_METHOD scMethod; // How to Find Short Period + ENUM_TIMEFRAMES scPeriod; // Short Period + ENUM_X_PERIOD_METHOD mcMethod; // How to Find Medium Period + ENUM_TIMEFRAMES mcPeriod; // Medium Period + ENUM_X_PERIOD_METHOD lcMethod; // How to Find Long Period + ENUM_TIMEFRAMES lcPeriod; // Long Period + ENUM_X_PERIOD_METHOD hcMethod; // How to Find Hind Period + ENUM_TIMEFRAMES hcPeriod; // Hind Period + ENUM_SERIESMODE upperMode; // Peak Method + ENUM_SERIESMODE lowerMode; // Vale Method + ENUM_X_FIBO_LEVELS fiboUpperZoneLevel; // Upper Zone Level + ENUM_X_FIBO_LEVELS fiboMiddleZoneLevel; // Upper Zone Level + ENUM_X_FIBO_LEVELS fiboLowerZoneLevel; // Lower Zone Level + double sarStep; // SAR Step + double sarMax; // SAR Maximum + ENUM_MA_METHOD maMethod; // MA Method + ENUM_APPLIED_PRICE maAppliedTo; // MA Applied To + int maFastLength; // Fast MA Length + int maSlowLength; // Slow MA Length + int maBandLength; // MA Band Length + int zigzagDepth; // ZigZag Depth + int zigzagDeviation; // ZigZag Deviation + int zigzagBackStep; // ZigZag Back Step + ENUM_X_PRICE zigzagUppersMode; // ZigZag High Detect Mode + ENUM_X_PRICE zigzagLowersMode; // ZigZag Low Detect Mode + + // + // Presentation ... + bool showPV; // Show PV + bool showHK; // Show HK + bool showSAR; // Show Sar + bool showMAFast; // Show MA Fast + bool showMASlow; // Show MA Slow + bool showMABand; // Show MA Band + bool showZigZag; // Show ZigZag + bool showFiboZone; // Show Fibo Zone + int startCalculationForLastBars; // Calculate Last n Bars + int sarArrowCode; // Parabolic Sar Arrow Code + int peakArrowCode; // Peaks Arrow Code + int valeArrowCode; // Vales Arrow Code + + // + // Constructor(s) ... + XFIMAInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + // Calculations ... + scMethod = X_PERIOD_AUTO; // How to Find Short Period + scPeriod = NULL; // Short Period + mcMethod = X_PERIOD_AUTO; // How to Find Medium Period + mcPeriod = NULL; // Medium Period + lcMethod = X_PERIOD_AUTO; // How to Find Long Period + lcPeriod = NULL; // Long Period + hcMethod = X_PERIOD_AUTO; // How to Find Hind Period + hcPeriod = NULL; // Hind Period + upperMode = MODE_HIGH; // Peak Method + lowerMode = MODE_LOW; // Vale Method + fiboUpperZoneLevel = X_FIBO_LEVEL_382; // Upper Zone Level + fiboMiddleZoneLevel = X_FIBO_LEVEL_500; // Upper Zone Level + fiboLowerZoneLevel = X_FIBO_LEVEL_618; // Lower Zone Level + sarStep = 0.02; // SAR Step + sarMax = 0.2; // SAR Maximum + maMethod = MODE_EMA; // MA Method + maAppliedTo = PRICE_CLOSE; // MA Applied To + maFastLength = 7; // Fast MA Length + maSlowLength = 20; // Slow MA Length + maBandLength = 7; // MA Band Length + zigzagDepth = 12; // ZigZag Depth + zigzagDeviation = 5; // ZigZag Deviation + zigzagBackStep = 3; // ZigZag Back Step + zigzagUppersMode = X_PRICE_HIGH; // ZigZag High Detect Mode + zigzagLowersMode = X_PRICE_LOW; // ZigZag Low Detect Mode + + // + // Presentation ... + showPV = true; // Show PV + showHK = true; // Show HK + showSAR = true; // Show Sar + showMAFast = true; // Show MA Fast + showMASlow = true; // Show MA Slow + showMABand = true; // Show MA Band + showZigZag = true; // Show ZigZag + showFiboZone = true; // Show Fibo Zone + startCalculationForLastBars = 1500; // Calculate Last n Bars + sarArrowCode = 159; // Parabolic Sar Arrow Code + peakArrowCode = 159; // Peaks Arrow Code + valeArrowCode = 159; // Vales Arrow Code + } + + // + // Hide all Visible Buffers ... + void Hide() + { + // + showPV = false; + showHK = false; + showSAR = false; + showMAFast = false; + showMASlow = false; + showMABand = false; + showZigZag = false; + showFiboZone = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + // MA ... + maFastLength >= 2 && + maSlowLength >= 2 && + maBandLength >= 2 && + maSlowLength > maFastLength && + // + // SAR ... + sarMax > 0 && + sarStep > 0 && + sarMax > sarStep && + // + // CYCLES ... + (IsSpecifiedValid(scMethod, scPeriod) && + IsSpecifiedValid(mcMethod, mcPeriod) && + IsSpecifiedValid(lcMethod, lcPeriod) && + IsSpecifiedValid(hcMethod, hcPeriod)) && + // + // ZIGZAG ... + zigzagDepth > 0 && + zigzagDeviation > 0 && + zigzagBackStep > 0 && + // + // Validate Upper Mode Detection ... + IsXValid(zigzagUppersMode) && + // + // Validate Lower Mode Detection ... + IsXValid(zigzagLowersMode) + // + ; + + // + return result; + } +}; + +// +// Conditions ... +struct XFIMAConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + datetime to; + datetime from; + XOHCL bars[]; + + // + // Buffers ... + double maFastBuffer[]; + double maFastColorBuffer[]; + double maFastStateBuffer[]; + double maSlowBuffer[]; + double maSlowColorBuffer[]; + double maSlowStateBuffer[]; + double maBandUpperBuffer[]; + double maBandLowerBuffer[]; + double sarBuffer[]; + double sarColorBuffer[]; + double sarStateBuffer[]; + double peakBuffer[]; + double valeBuffer[]; + double fiboUpperBuffer[]; + double fiboMiddleBuffer[]; + double fiboLowerBuffer[]; + double zigzagBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + double highsBuffer[]; + double highsTimeBuffer[]; + double lowsBuffer[]; + double lowsTimeBuffer[]; + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkLowBuffer[]; + double hkCloseBuffer[]; + double hkColorBuffer[]; + + // + // Conditions ... + + // + // Constructor ... + XFIMAConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + to = NULL; + from = NULL; + time = NULL; + symbol = NULL; + period = NULL; + + // + // Buffers ... + + // + SpecifiedClean(bars); + + // + SpecifiedClean(maFastBuffer); + SpecifiedClean(maFastColorBuffer); + SpecifiedClean(maFastStateBuffer); + SpecifiedClean(maSlowBuffer); + SpecifiedClean(maSlowColorBuffer); + SpecifiedClean(maSlowStateBuffer); + SpecifiedClean(maBandUpperBuffer); + SpecifiedClean(maBandLowerBuffer); + SpecifiedClean(sarBuffer); + SpecifiedClean(sarColorBuffer); + SpecifiedClean(sarStateBuffer); + SpecifiedClean(peakBuffer); + SpecifiedClean(valeBuffer); + SpecifiedClean(fiboUpperBuffer); + SpecifiedClean(fiboMiddleBuffer); + SpecifiedClean(fiboLowerBuffer); + SpecifiedClean(zigzagBuffer); + SpecifiedClean(sHHBuffer); + SpecifiedClean(sLLBuffer); + SpecifiedClean(mHHBuffer); + SpecifiedClean(mLLBuffer); + SpecifiedClean(lHHBuffer); + SpecifiedClean(lLLBuffer); + SpecifiedClean(hHHBuffer); + SpecifiedClean(hLLBuffer); + SpecifiedClean(highsBuffer); + SpecifiedClean(highsTimeBuffer); + SpecifiedClean(lowsBuffer); + SpecifiedClean(lowsTimeBuffer); + SpecifiedClean(hkOpenBuffer); + SpecifiedClean(hkHighBuffer); + SpecifiedClean(hkLowBuffer); + SpecifiedClean(hkCloseBuffer); + SpecifiedClean(hkColorBuffer); + + // + // Conditions ... + + // + ArraySetAsSeries(bars, true); + + // + ArraySetAsSeries(maFastBuffer, true); + ArraySetAsSeries(maFastColorBuffer, true); + ArraySetAsSeries(maFastStateBuffer, true); + ArraySetAsSeries(maSlowBuffer, true); + ArraySetAsSeries(maSlowColorBuffer, true); + ArraySetAsSeries(maSlowStateBuffer, true); + ArraySetAsSeries(maBandUpperBuffer, true); + ArraySetAsSeries(maBandLowerBuffer, true); + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(sarColorBuffer, true); + ArraySetAsSeries(sarStateBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); + ArraySetAsSeries(fiboUpperBuffer, true); + ArraySetAsSeries(fiboMiddleBuffer, true); + ArraySetAsSeries(fiboLowerBuffer, true); + ArraySetAsSeries(zigzagBuffer, false); // Fix this ... + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + ArraySetAsSeries(hHHBuffer, true); + ArraySetAsSeries(hLLBuffer, true); + ArraySetAsSeries(highsBuffer, true); + ArraySetAsSeries(highsTimeBuffer, true); + ArraySetAsSeries(lowsBuffer, true); + ArraySetAsSeries(lowsTimeBuffer, true); + ArraySetAsSeries(hkOpenBuffer, true); + ArraySetAsSeries(hkHighBuffer, true); + ArraySetAsSeries(hkLowBuffer, true); + ArraySetAsSeries(hkCloseBuffer, true); + ArraySetAsSeries(hkColorBuffer, true); + + // + ZeroMemory(this); + } + + /** + * Generate Conditions Scores ... + * + * @param bullishScore: Double, Directional Scores Reference ... + * @param bearishScore: Double, Directional Scores Reference ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + } + + /** + * Generate Summary String for Represent Conditions State ... + * + * @param onlyCommons: Boolean, Just Generate Only Commons Conditions ... + * @param onlyConditions: Boolean, Just Generate Only Conditions ... + * @param includeScores: Boolean, Attach Scores Representations on Result ... + * @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ... + * @param separator: String, Separate Lines ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + return ""; + } + + /** + * Retrieve Unique Tag Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + return GetToken(this); + } +}; + +// +// Class ... +class XCXFIMAHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Buffers ... + double maFastBuffer[]; + double maFastColorBuffer[]; + double maFastStateBuffer[]; + double maSlowBuffer[]; + double maSlowColorBuffer[]; + double maSlowStateBuffer[]; + double maBandUpperBuffer[]; + double maBandLowerBuffer[]; + double sarBuffer[]; + double sarColorBuffer[]; + double sarStateBuffer[]; + double peakBuffer[]; + double valeBuffer[]; + double fiboUpperBuffer[]; + double fiboMiddleBuffer[]; + double fiboLowerBuffer[]; + double zigzagBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + double highsBuffer[]; + double highsTimeBuffer[]; + double lowsBuffer[]; + double lowsTimeBuffer[]; + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkLowBuffer[]; + double hkCloseBuffer[]; + double hkColorBuffer[]; + + // + // Constructors ... + XCXFIMAHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCXFIMAHelper() + { + } + + // + // Tools ... + + // + // Initialize Helper Cleass ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XFIMAInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + ArraySetAsSeries(maFastBuffer, true); + ArraySetAsSeries(maFastColorBuffer, true); + ArraySetAsSeries(maFastStateBuffer, true); + ArraySetAsSeries(maSlowBuffer, true); + ArraySetAsSeries(maSlowColorBuffer, true); + ArraySetAsSeries(maSlowStateBuffer, true); + ArraySetAsSeries(maBandUpperBuffer, true); + ArraySetAsSeries(maBandLowerBuffer, true); + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(sarColorBuffer, true); + ArraySetAsSeries(sarStateBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); + ArraySetAsSeries(fiboUpperBuffer, true); + ArraySetAsSeries(fiboMiddleBuffer, true); + ArraySetAsSeries(fiboLowerBuffer, true); + ArraySetAsSeries(zigzagBuffer, false); // TODO: FIX This ... + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + ArraySetAsSeries(hHHBuffer, true); + ArraySetAsSeries(hLLBuffer, true); + ArraySetAsSeries(highsBuffer, true); + ArraySetAsSeries(highsTimeBuffer, true); + ArraySetAsSeries(lowsBuffer, true); + ArraySetAsSeries(lowsTimeBuffer, true); + ArraySetAsSeries(hkOpenBuffer, true); + ArraySetAsSeries(hkHighBuffer, true); + ArraySetAsSeries(hkLowBuffer, true); + ArraySetAsSeries(hkCloseBuffer, true); + ArraySetAsSeries(hkColorBuffer, true); + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xfima", + "", // Calculation ... + mInputs.scMethod, + mInputs.scPeriod, + mInputs.mcMethod, + mInputs.mcPeriod, + mInputs.lcMethod, + mInputs.lcPeriod, + mInputs.hcMethod, + mInputs.hcPeriod, + mInputs.upperMode, + mInputs.lowerMode, + mInputs.fiboUpperZoneLevel, + mInputs.fiboMiddleZoneLevel, + mInputs.fiboLowerZoneLevel, + mInputs.sarStep, + mInputs.sarMax, + mInputs.maMethod, + mInputs.maAppliedTo, + mInputs.maFastLength, + mInputs.maSlowLength, + mInputs.maBandLength, + mInputs.zigzagDepth, + mInputs.zigzagDeviation, + mInputs.zigzagBackStep, + mInputs.zigzagUppersMode, + mInputs.zigzagLowersMode, + "", // Presentation ... + mInputs.showPV, + mInputs.showHK, + mInputs.showSAR, + mInputs.showMAFast, + mInputs.showMASlow, + mInputs.showMABand, + mInputs.showZigZag, + mInputs.showFiboZone, + mInputs.startCalculationForLastBars, + mInputs.sarArrowCode, + mInputs.peakArrowCode, + mInputs.valeArrowCode + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XFIMAInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XFIMAInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs // + ); + } + + // + // Tools ... + + // + void Update( + int barIndex // Bar Index + ) + { + Calculate(barIndex); + } + + // + void Free() override + { + Cleanup(10); + } + + // + bool GetConditions( + XFIMAConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + // Filling Bars ... + int barsCount = GetBars( + conditions.bars, + mSymbol, + mPeriod, + barIndex, + loopback // + ); + result = barsCount == loopback; + if (!result) + { + // + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + conditions.to = conditions.bars[0].time; + conditions.from = conditions.bars[ArraySize(conditions.bars) - 1].time; + + // + int zIndex = barIndex; + + // + // Buffers ... + + // + CopyMAFast( + zIndex, + loopback, + conditions.maFastBuffer // + ); + + // + CopyMAFastState( + zIndex, + loopback, + conditions.maFastStateBuffer // + ); + + // + CopyMASlow( + zIndex, + loopback, + conditions.maSlowBuffer // + ); + + // + CopyMASlowState( + zIndex, + loopback, + conditions.maSlowStateBuffer // + ); + + // + CopyMABandUpper( + zIndex, + loopback, + conditions.maBandUpperBuffer // + ); + + // + CopyMABandLower( + zIndex, + loopback, + conditions.maBandLowerBuffer // + ); + + // + CopySar( + zIndex, + loopback, + conditions.sarBuffer // + ); + + // + CopySarState( + zIndex, + loopback, + conditions.sarStateBuffer // + ); + + // + CopyPeak( + zIndex, + loopback, + conditions.peakBuffer // + ); + + // + CopyVale( + zIndex, + loopback, + conditions.valeBuffer // + ); + + // + CopyFiboUpper( + zIndex, + loopback, + conditions.fiboUpperBuffer // + ); + + // + CopyFiboMiddle( + zIndex, + loopback, + conditions.fiboMiddleBuffer // + ); + + // + CopyFiboLower( + zIndex, + loopback, + conditions.fiboLowerBuffer // + ); + + // + CopyZigZag( + zIndex, + loopback, + conditions.zigzagBuffer // + ); + + // + CopySHH( + zIndex, + loopback, + conditions.sHHBuffer // + ); + + // + CopySLL( + zIndex, + loopback, + conditions.sLLBuffer // + ); + + // + CopyMHH( + zIndex, + loopback, + conditions.mHHBuffer // + ); + + // + CopyMLL( + zIndex, + loopback, + conditions.mLLBuffer // + ); + + // + CopyLHH( + zIndex, + loopback, + conditions.lHHBuffer // + ); + + // + CopyLLL( + zIndex, + loopback, + conditions.lLLBuffer // + ); + + // + CopyHHH( + zIndex, + loopback, + conditions.hHHBuffer // + ); + + // + CopyHLL( + zIndex, + loopback, + conditions.hLLBuffer // + ); + + // + CopyHKOpen( + zIndex, + loopback, + conditions.hkOpenBuffer // + ); + + // + CopyHKHigh( + zIndex, + loopback, + conditions.hkHighBuffer // + ); + + // + CopyHKLow( + zIndex, + loopback, + conditions.hkLowBuffer // + ); + + // + CopyHKClose( + zIndex, + loopback, + conditions.hkCloseBuffer // + ); + + // + CopyHKColor( + zIndex, + loopback, + conditions.hkColorBuffer // + ); + + // + // Conditions ... + + // + return result; + } + + // + // Pivot Actions ... + + /** + * Check Specified Bar has MA Cross or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ... + * + * @return ( bool ) + */ + bool HasMACross( + ENUM_X_DIRECTION &dir, + int barIndex = 0, + double validCrossDiffMultiplier = 1 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0); + + // + double fast[]; + double slow[]; + double upper[]; + double lower[]; + int count = ReadMAValues( + fast, + slow, + upper, + lower, + barIndex, + 2 // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + bool notEmpty = + NotEmptyZero(fast[0]) && + NotEmptyZero(fast[1]) && + NotEmptyZero(slow[0]) && + NotEmptyZero(slow[1]); + + // + isBullish = + notEmpty && + fast[0] > slow[0] && + fast[1] < slow[1]; + + // + isBearish = + notEmpty && + fast[0] < slow[0] && + fast[1] > slow[1]; + + // + result = + isBullish || + isBearish; + + // + // Validate Direction Change ... + if (result && + validCrossDiffMultiplier > 0) + { + // + double _points = GetPoints(GetSymbol()); + double diff = MathAbs(fast[0] - slow[0]); + + // + result = diff >= (validCrossDiffMultiplier * _points); + } + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(fast); + XClean(slow); + XClean(upper); + XClean(lower); + + // + return result; + } + + /** + * Check Specified Bar has HK Switch or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool HasHKSwitch( + ENUM_X_DIRECTION &dir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + double low[]; + double open[]; + double high[]; + double close[]; + int count = ReadHKBars( + open, + high, + low, + close, + barIndex, + 2 // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + bool notEmpty = + NotEmptyZero(open[0]) && + NotEmptyZero(open[1]) && + NotEmptyZero(close[0]) && + NotEmptyZero(close[1]); + + // + isBullish = + notEmpty && + open[0] < close[0] && + open[1] > close[1]; + + // + isBearish = + notEmpty && + open[0] > close[0] && + open[1] < close[1]; + + // + result = + isBullish || + isBearish; + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(low); + XClean(open); + XClean(high); + XClean(close); + + // + return result; + } + + /** + * Check Specified Bar has SAR Switch or not ... + * + * @param dir: reference for holds cross Direction ... + * @param barIndex: int, Specified Bar Index ... + * + * @return ( bool ) + */ + bool HasSARSwitch( + ENUM_X_DIRECTION &dir, + int barIndex = 0 // + ) + { + // + bool result = false; + + // + // Prepare ... + dir = X_DIRECTION_NONE; + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + double sars[]; + int count = CopyBuffer( + mHandler, + XFIMA_SAR_STATE_LINE, + barIndex, + 2, + sars // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + // Validate Readed Values ... + result = IsValidSize(count) && count >= 2; + if (result) + { + // + // Detect Direction Change ... + + // + isBullish = + sars[0] >= 1 && + sars[1] <= -1; + + // + isBearish = + sars[0] <= -1 && + sars[1] >= 1; + + // + result = + isBullish || + isBearish; + } + + // + if (result) + { + // + // Setting Direction ... + dir = + isBullish + ? X_DIRECTION_BULLISH + : isBearish + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + } + + // + // Cleanup Resources ... + XClean(sars); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ... + * + * @return ( int ) + */ + int ExtractPVPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500, + int validationLength = 0 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validationLength = NormalizeInt(validationLength, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + bool lookupPeaks = true; + bool lookupVales = true; + + // + XOHCL iBar; + XPivot iPivot; + bool has = false; + int idx = barIndex - 1; + int samePeaksCount = 0; + int sameValesCount = 0; + double tmpPeaksBuffer[]; + double tmpValesBuffer[]; + string symbol = GetSymbol(); + double iPValue = EMPTY_VALUE; + double iVValue = EMPTY_VALUE; + double pPValue = EMPTY_VALUE; + double pVValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + if (!has) + { + continue; + } + + // + // Detecting ... + + // + // Peak ... + if (lookupPeaks) + { + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_PEAK_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpPeaksBuffer // Buffer ... + ); + ArraySetAsSeries(tmpPeaksBuffer, true); + + // + // Reading Values ... + iPValue = tmpPeaksBuffer[0]; + pPValue = tmpPeaksBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iPValue)) + { + // + // Check New Peak ... + has = + !NotEmptyZero(pPValue) + ? true + : iPValue != pPValue; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + iPValue == iBar.high + ? X_PIVOT_TYPE_PEAK + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // Check Validation Length ... + has = + has && + (validationLength <= 0 + ? true + : samePeaksCount >= validationLength); + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iPValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + samePeaksCount = 0; + } + else if (iPValue == pPValue) + { + samePeaksCount++; + } + } + } + + // + // Vale ... + if (lookupVales) + { + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_VALE_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpValesBuffer // Buffer ... + ); + ArraySetAsSeries(tmpValesBuffer, true); + + // + // Reading Values ... + iVValue = tmpValesBuffer[0]; + pVValue = tmpValesBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iVValue)) + { + // + // Check New Vale ... + has = + !NotEmptyZero(pVValue) + ? true + : iVValue != pVValue; + if (has) + { + // + // Calculate and Validate Type ... + // Vales Only Valid when Confirmed by Bar Low ... + iType = + iVValue == iBar.low + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // Check Validation Length ... + has = + has && + (validationLength <= 0 + ? true + : sameValesCount >= validationLength); + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iVValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + sameValesCount = 0; + } + else if (iVValue == pVValue) + { + sameValesCount++; + } + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpPeaksBuffer); + SpecifiedClean(tmpValesBuffer); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractMAPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + double validCrossDiffMultiplier = 1, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + double fast[]; + double slow[]; + XPivot iPivot; + int count = 0; + double upper[]; + double lower[]; + bool has = false; + int idx = barIndex - 1; + datetime iPivotTime = NULL; + string symbol = GetSymbol(); + double iFValue = EMPTY_VALUE; + double pFValue = EMPTY_VALUE; + double iSValue = EMPTY_VALUE; + double pSValue = EMPTY_VALUE; + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + double iSelectedValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iPivot.Clean(); + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Reading Buffer ... + count = ReadMAValues( + fast, + slow, + upper, + lower, + idx, + 2 // + ); + has = IsValidSize(count); + + // + // Reading Values ... + + // + iFValue = fast[0]; + pFValue = fast[1]; + + // + iSValue = slow[0]; + pSValue = slow[1]; + + // + // Validate Value ... + has = + HasMACross( + iDir, + idx, + validCrossDiffMultiplier // + ) && + NotEmptyZero(iFValue) && + NotEmptyZero(iSValue) && + NotEmptyZero(pFValue) && + NotEmptyZero(pSValue); + if (has) + { + // + // Check Direction Changed ... + isSwitchedToBullish = IsXBullish(iDir); + isSwitchedToBearish = IsXBearish(iDir); + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + if (has) + { + // + iPivotTime = GetBarTime( + symbol, + period, + idx // + ); + + // + // Select Value based on Pivot Type ... + iSelectedValue = IsXPeak(iType) + ? MathMax(iFValue, iSValue) + : MathMin(iFValue, iSValue); + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iSelectedValue, + iPivotTime, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractHKPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + double low[]; + double open[]; + XPivot iPivot; + int count = 0; + double high[]; + double close[]; + bool has = false; + int idx = barIndex - 1; + datetime iPivotTime = NULL; + string symbol = GetSymbol(); + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + double iSelectedValue = EMPTY_VALUE; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iPivot.Clean(); + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Reading Buffer ... + count = ReadHKBars( + open, + high, + low, + close, + idx, + 2 // + ); + has = IsValidSize(count); + + // + // Validate Value ... + has = + HasHKSwitch( + iDir, + idx // + ) && + NotEmptyZero(open[0]) && + NotEmptyZero(open[1]) && + NotEmptyZero(close[0]) && + NotEmptyZero(close[1]); + if (has) + { + // + // Check Direction Changed ... + isSwitchedToBullish = IsXBullish(iDir); + isSwitchedToBearish = IsXBearish(iDir); + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + if (has) + { + // + iPivotTime = GetBarTime( + symbol, + period, + idx // + ); + + // + // Select Value based on Pivot Type ... + iSelectedValue = IsXPeak(iType) + ? MathMax(open[0], close[0]) + : MathMin(open[0], close[0]); + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iSelectedValue, + iPivotTime, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iPivot.Clean(); + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractSARPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + XOHCL iBar; + XOHCL pBar; + XPivot iPivot; + bool has = false; + double tmpSarBuffer[]; + int idx = barIndex - 1; + string symbol = GetSymbol(); + double iValue = EMPTY_VALUE; + double pValue = EMPTY_VALUE; + bool isSwitchedToBullish = false; + bool isSwitchedToBearish = false; + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + has = + has && + iBar.GetPreviousBar(pBar); + if (!has) + { + continue; + } + + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_SAR_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 2, // Number of Requirements ... + tmpSarBuffer // Buffer ... + ); + ArraySetAsSeries(tmpSarBuffer, true); + + // + // Reading Values ... + iValue = tmpSarBuffer[0]; + pValue = tmpSarBuffer[1]; + + // + // Validate Value ... + if (NotEmptyZero(iValue)) + { + // + // Check Sar Direction Changed ... + isSwitchedToBullish = iValue < iBar.low && + pValue > pBar.high; + isSwitchedToBearish = iValue > iBar.high && + pValue < pBar.low; + has = + isSwitchedToBullish || + isSwitchedToBearish; + if (has) + { + // + // Calculate and Validate Type ... + // Peaks Only Valid when Confirmed by Bar High ... + iType = + isSwitchedToBearish + ? X_PIVOT_TYPE_PEAK + : isSwitchedToBullish + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + + // + // Calculate and Validate Dir ... + iDir = IsXPeak(iType) + ? X_DIRECTION_BEARISH + : IsXVale(iType) + ? X_DIRECTION_BULLISH + : X_DIRECTION_NONE; + has = has && + HasDirection(iDir); + + // + // TODO: we can also Add other Validations Here ... + + // + if (has) + { + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + } + + // + // Cleanup Resources ... + iPivot.Clean(); + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + pBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpSarBuffer); + + // + return result; + } + + /** + * Extract Specified Kind of Pivots ... + * + * @param pivots: XPivot, refrence Collection to hold Extracted pivots ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ... + * @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ... + * + * @return ( int ) + */ + int ExtractZigZagPivots( + XPivot &pivots[], + int barIndex = 0, + int requiredNumberOFPivots = 50, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(pivots); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + XOHCL iBar; + XPivot iPivot; + bool has = false; + int idx = barIndex - 1; + double tmpZigZagBuffer[]; + double iValue = EMPTY_VALUE; + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE; + int maxAllowed = barIndex + maxAllowedLoopbackLength - 1; + while (idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots) + { + // + idx++; + + // + // Prepare ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + // Ignore First Item ... + if (idx == barIndex) + { + continue; + } + + // + // Initialize Bar ... + has = iBar.Init( + symbol, + period, + idx // + ); + if (!has) + { + continue; + } + + // + // Reading Buffer ... + CopyBuffer( + mHandler, // Handler ... + XFIMA_ZIGZAG_LINE, // Handler Buffer Number ... + idx, // Bar Index ... + 1, // Number of Requirements ... + tmpZigZagBuffer // Buffer ... + ); + ArraySetAsSeries(tmpZigZagBuffer, true); + + // + // Read and Validate Value ... + iValue = tmpZigZagBuffer[0]; + has = NotEmptyZero(iValue); + if (!has) + { + // + iBar.Clean(); + SpecifiedClean(tmpZigZagBuffer); + continue; + } + + // + // Calculate and Validate Type ... + iType = + iValue == iBar.high + ? X_PIVOT_TYPE_PEAK + : iValue == iBar.low + ? X_PIVOT_TYPE_VALE + : X_PIVOT_TYPE_NONE; + has = IsXValid(iType); + if (!has) + { + // + iBar.Clean(); + SpecifiedClean(tmpZigZagBuffer); + continue; + } + + // + // Calculate and Validate Dir ... + iDir = + IsXVale(iType) + ? X_DIRECTION_BULLISH + : IsXPeak(iType) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(iDir); + if (!has) + { + // + iBar.Clean(); + SpecifiedClean(tmpZigZagBuffer); + continue; + } + + // + // Initialize and Validate Pivot ... + has = iPivot.Init( + iValue, + iBar.time, + symbol, + iDir, + period, + iType // + ); + if (has) + { + // + // Add Pivot to Collection only if not Exists ... + AddIfNotExists( + iPivot, + pivots // + ); + } + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + // Check Moving Forward Condition ... + has = + idx < maxAllowed && + ArraySize(pivots) < requiredNumberOFPivots; + if (!has) + { + break; + } + } + + // + result = ArraySize(pivots); + + // + // Cleanup Resources ... + iBar.Clean(); + iPivot.Clean(); + SpecifiedClean(tmpZigZagBuffer); + + // + return result; + } + + /** + * Extract Validated Zones ... + * + * @param zones: XBoxZone, collection reference to holds results ... + * @param barIndex: int, Specified Bar Index ... + * @param requiredNumberOFZones: int, required Number of Zones ... + * @param breakValidLength: int, Breake Validation Length of Zones ... + * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... + * @param shadowMultiplier: double a Shadow Multiplier for Validation ... + * @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ... + * @param validationLength: int, Validation Length of Zones ... + * @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ... + * + * @return ( int ) + */ + int ExtractHKZones( + XBoxZone &zones[], + int barIndex = 0, + int requiredNumberOFZones = 50, + int breakValidLength = 3, + bool validateFakeBreakes = true, + double shadowMultiplier = 3, + double validationStrength = 1, + int validationLength = 21, + int maxAllowedLoopbackLength = 1500 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(zones); + + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + validationLength = NormalizeInt(validationLength, 7); + shadowMultiplier = NormalizeDouble(shadowMultiplier, 1); + validationStrength = NormalizeDouble(validationStrength, 1); + requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5); + maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100); + + // + // Reading Values ... + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + double minAllowedStrength = (validationStrength * GetPoints(symbol)); + + // + int count = 0; + XBoxZone zone; + double hkLows[]; + bool has = false; + double hkOpens[]; + double hkHighs[]; + double hkCloses[]; + int start = barIndex; + bool isBullish = false; + bool isBearish = false; + double up = EMPTY_VALUE; + double down = EMPTY_VALUE; + double body = EMPTY_VALUE; + double range = EMPTY_VALUE; + bool lowShadowPassed = false; + bool highShadowPassed = false; + double lowShadow = EMPTY_VALUE; + double highShadow = EMPTY_VALUE; + double startHKLow = EMPTY_VALUE; + double startHKOpen = EMPTY_VALUE; + double startHKHigh = EMPTY_VALUE; + double startHKClose = EMPTY_VALUE; + ENUM_X_DIRECTION dir = X_DIRECTION_NONE; + int end = start + maxAllowedLoopbackLength; + for (int i = start; i < end; i++) + { + // + // Cleanup ... + zone.Clean(); + dir = X_DIRECTION_NONE; + + // + // Reading HK Buffesr ... + count = ReadHKBars( + hkOpens, + hkHighs, + hkLows, + hkCloses, + i, + 1 // + ); + has = IsValidSize(count); + if (!has) + { + continue; + } + + // + // Initialized Start Bar ... + if (i == start) + { + // + startHKLow = hkLows[0]; + startHKOpen = hkOpens[0]; + startHKHigh = hkHighs[0]; + startHKClose = hkCloses[0]; + } + + // + // Check Direction ... + isBullish = hkOpens[0] < hkCloses[0]; + isBearish = hkOpens[0] > hkCloses[0]; + dir = + (isBullish && !isBearish) + ? X_DIRECTION_BULLISH + : (isBearish && !isBullish) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(dir); + if (!has) + { + continue; + } + + // + // Calculate Requirements for Processing ... + up = isBullish + ? hkCloses[0] + : hkOpens[0]; + down = isBullish + ? hkOpens[0] + : hkCloses[0]; + body = MathAbs(up - down); + range = hkHighs[0] - hkLows[0]; + highShadow = hkHighs[0] - up; + lowShadow = down - hkLows[0]; + + // + // Detecting Shadows ... + + // + // Low Shadow ... + lowShadowPassed = lowShadow >= (shadowMultiplier * highShadow); + + // + // High Shadow ... + highShadowPassed = highShadow >= (shadowMultiplier * lowShadow); + + // + has = (lowShadowPassed && !highShadowPassed) || + (highShadowPassed && !lowShadowPassed); + if (!has) + { + continue; + } + + // + // Filling Zone ... + + // + zone.symbol = symbol; + zone.period = period; + zone.from = GetBarTime( + zone.symbol, + zone.period, + i // + ); + zone.dir = lowShadowPassed + ? X_DIRECTION_BULLISH + : highShadowPassed + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + + // + zone.upper = + IsXBullish(zone.dir) + ? down + : IsXBearish(zone.dir) + ? hkHighs[0] + : EMPTY_VALUE; + + // + zone.lower = + IsXBullish(zone.dir) + ? hkLows[0] + : IsXBearish(zone.dir) + ? up + : EMPTY_VALUE; + + // + zone.to = TimeCurrent(); + zone.type = "XHK_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance" + : "") + + "_" + ToXString(TimeToSeconds(zone.from)); + + // + // Validate ... + has = + zone.IsValid() && + HasDirection(zone.dir) && + NotEmptyZero(zone.upper) && + NotEmptyZero(zone.lower) && + (zone.IsBullish() + ? startHKLow > zone.upper + : startHKHigh < zone.lower) && + (zone.upper - zone.lower) >= minAllowedStrength && + ValidateHKZone(zone, validationLength, breakValidLength, validateFakeBreakes); + if (has) + { + // + AddIfNotExists( + zone, + zones // + ); + } + + // + // Cleanup Resources ... + zone.Clean(); + + // + // Validating ... + result = ArraySize(zones); + has = IsValidSize(result) && + result >= requiredNumberOFZones; + if (has) + { + break; + } + } + + // + // Cleanup Resources ... + zone.Clean(); + SpecifiedClean(hkLows); + SpecifiedClean(hkOpens); + SpecifiedClean(hkHighs); + SpecifiedClean(hkCloses); + + // + return result; + } + + // + // Values Retrievers ... + + // + // Fast MA ... + + // + double GetMAFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(maFastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return maFastBuffer[barIndex]; + } + + // + int CopyMAFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + maFastBuffer, + buffer, + forceClean + // + ); + } + + // + // Fast MA State ... + + // + double GetMAFastState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(maFastStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return maFastStateBuffer[barIndex]; + } + + // + int CopyMAFastState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + maFastStateBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow MA ... + + // + double GetMASlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(maSlowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return maSlowBuffer[barIndex]; + } + + // + int CopyMASlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + maSlowBuffer, + buffer, + forceClean + // + ); + } + + // + // Slow MA State ... + + // + double GetMASlowState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(maSlowStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return maSlowStateBuffer[barIndex]; + } + + // + int CopyMASlowState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + maSlowStateBuffer, + buffer, + forceClean + // + ); + } + + // + // Upper MA ... + + // + double GetMABandUpper( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(maBandUpperBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return maBandUpperBuffer[barIndex]; + } + + // + int CopyMABandUpper( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + maBandUpperBuffer, + buffer, + forceClean + // + ); + } + + // + // Lower MA ... + + // + double GetMABandLower( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(maBandLowerBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return maBandLowerBuffer[barIndex]; + } + + // + int CopyMABandLower( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + maBandLowerBuffer, + buffer, + forceClean + // + ); + } + + // + // SAR ... + + // + double GetSar( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sarBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sarBuffer[barIndex]; + } + + // + int CopySar( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sarBuffer, + buffer, + forceClean + // + ); + } + + // + // SAR State ... + + // + double GetSarState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sarStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sarStateBuffer[barIndex]; + } + + // + int CopySarState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sarStateBuffer, + buffer, + forceClean + // + ); + } + + // + // PEAK ... + + // + double GetPeak( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(peakBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return peakBuffer[barIndex]; + } + + // + int CopyPeak( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + peakBuffer, + buffer, + forceClean + // + ); + } + + // + // VALE ... + + // + double GetVale( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(valeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return valeBuffer[barIndex]; + } + + // + int CopyVale( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + valeBuffer, + buffer, + forceClean + // + ); + } + + // + // FIBO Zone ... + + // + // FIBO Upper ... + + // + double GetFiboUpper( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(fiboUpperBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fiboUpperBuffer[barIndex]; + } + + // + int CopyFiboUpper( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + fiboUpperBuffer, + buffer, + forceClean + // + ); + } + + // + // FIBO Middle ... + + // + double GetFiboMiddle( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(fiboMiddleBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fiboMiddleBuffer[barIndex]; + } + + // + int CopyFiboMiddle( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + fiboMiddleBuffer, + buffer, + forceClean + // + ); + } + + // + // FIBO Lower ... + + // + double GetFiboLower( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(fiboLowerBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fiboLowerBuffer[barIndex]; + } + + // + int CopyFiboLower( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + fiboLowerBuffer, + buffer, + forceClean + // + ); + } + + // + // ZigZag ... + + // + double GetZigZag( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Calculate(barIndex); + SpecifiedClean(zigzagBuffer); + + // + CopyBuffer( + mHandler, + XFIMA_ZIGZAG_LINE, + barIndex, + 1, + zigzagBuffer // + ); + + // + int count = ArraySize(zigzagBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return zigzagBuffer[barIndex]; + } + + // + int CopyZigZag( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + // Calculate(start); + SpecifiedClean(zigzagBuffer); + + // + CopyBuffer( + mHandler, + XFIMA_ZIGZAG_LINE, + start, + 0, + zigzagBuffer // + ); + + // + // Copy Items ... + return Copy( + 0, + count, + zigzagBuffer, + buffer, + forceClean + // + ); + } + + // + // CYCLES Range ... + + // + // SHORT ... + + // + // HH ... + + // + double GetSHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sHHBuffer[barIndex]; + } + + // + int CopySHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetSLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sLLBuffer[barIndex]; + } + + // + int CopySLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + sLLBuffer, + buffer, + forceClean + // + ); + } + + // + // MEDIUM ... + + // + // HH ... + + // + double GetMHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mHHBuffer[barIndex]; + } + + // + int CopyMHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + mHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetMLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mLLBuffer[barIndex]; + } + + // + int CopyMLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + mLLBuffer, + buffer, + forceClean + // + ); + } + + // + // LONG ... + + // + // HH ... + + // + double GetLHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(lHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lHHBuffer[barIndex]; + } + + // + int CopyLHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + lHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetLLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(lLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lLLBuffer[barIndex]; + } + + // + int CopyLLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + lLLBuffer, + buffer, + forceClean + // + ); + } + + // + // HIND ... + + // + // HH ... + + // + double GetHHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hHHBuffer[barIndex]; + } + + // + int CopyHHH( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetHLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hLLBuffer[barIndex]; + } + + // + int CopyHLL( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hLLBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK ... + + // + // XHK Open ... + + // + double GetHKOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkOpenBuffer[barIndex]; + } + + // + int CopyHKOpen( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkOpenBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK High ... + + // + double GetHKHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkHighBuffer[barIndex]; + } + + // + int CopyHKHigh( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkHighBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK Low ... + + // + double GetHKLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkLowBuffer[barIndex]; + } + + // + int CopyHKLow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkLowBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK Close ... + + // + double GetHKClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkCloseBuffer[barIndex]; + } + + // + int CopyHKClose( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK Color ... + + // + double GetHKColor( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkColorBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkColorBuffer[barIndex]; + } + + // + int CopyHKColor( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + hkColorBuffer, + buffer, + forceClean + // + ); + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + XFIMAInputs mInputs; // Inputs ... + + // + // Buffers ... + // Define in Public ... + + // + void Calculate( + int barIndex = 0, + int maxRequiredBars = 100 // + ) + { + // + // Buffers ... + if (barIndex < 0) + { + barIndex = 0; + } + + // + CopyBuffer( + mHandler, + XFIMA_MA_FAST_LINE, + barIndex, + maxRequiredBars, + maFastBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_FAST_COLOR_LINE, + barIndex, + maxRequiredBars, + maFastColorBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_FAST_STATE_LINE, + barIndex, + maxRequiredBars, + maFastStateBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_SLOW_LINE, + barIndex, + maxRequiredBars, + maSlowBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_SLOW_COLOR_LINE, + barIndex, + maxRequiredBars, + maSlowColorBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_SLOW_STATE_LINE, + barIndex, + maxRequiredBars, + maSlowStateBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_BAND_UPPER_LINE, + barIndex, + maxRequiredBars, + maBandUpperBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_BAND_LOWER_LINE, + barIndex, + maxRequiredBars, + maBandLowerBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_SAR_LINE, + barIndex, + maxRequiredBars, + sarBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_SAR_COLOR_LINE, + barIndex, + maxRequiredBars, + sarColorBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_SAR_STATE_LINE, + barIndex, + maxRequiredBars, + sarStateBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_PEAK_LINE, + barIndex, + maxRequiredBars, + peakBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_VALE_LINE, + barIndex, + maxRequiredBars, + valeBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_FIBO_UPPER_LINE, + barIndex, + maxRequiredBars, + fiboUpperBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_FIBO_MIDDLE_LINE, + barIndex, + maxRequiredBars, + fiboMiddleBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_FIBO_LOWER_LINE, + barIndex, + maxRequiredBars, + fiboLowerBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_ZIGZAG_LINE, + barIndex, + maxRequiredBars, + zigzagBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_SC_HH_LINE, + barIndex, + maxRequiredBars, + sHHBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_SC_LL_LINE, + barIndex, + maxRequiredBars, + sLLBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MC_HH_LINE, + barIndex, + maxRequiredBars, + mHHBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MC_LL_LINE, + barIndex, + maxRequiredBars, + mLLBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_LC_HH_LINE, + barIndex, + maxRequiredBars, + lHHBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_LC_LL_LINE, + barIndex, + maxRequiredBars, + lLLBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_HC_HH_LINE, + barIndex, + maxRequiredBars, + hHHBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_HC_LL_LINE, + barIndex, + maxRequiredBars, + hLLBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_ZIGZAG_HIGHS_LINE, + barIndex, + maxRequiredBars, + highsBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_ZIGZAG_HIGHS_TIME_LINE, + barIndex, + maxRequiredBars, + highsTimeBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_ZIGZAG_LOWS_LINE, + barIndex, + maxRequiredBars, + lowsBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_ZIGZAG_LOWS_TIME_LINE, + barIndex, + maxRequiredBars, + lowsTimeBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_HK_OPEN_LINE, + barIndex, + maxRequiredBars, + hkOpenBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_HK_HIGH_LINE, + barIndex, + maxRequiredBars, + hkHighBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_HK_LOW_LINE, + barIndex, + maxRequiredBars, + hkLowBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_HK_CLOSE_LINE, + barIndex, + maxRequiredBars, + hkCloseBuffer // + ); + + // + CopyBuffer( + mHandler, + XFIMA_HK_COLOR_LINE, + barIndex, + maxRequiredBars, + hkColorBuffer // + ); + } + + // + void Cleanup( + int maxAllowed = 100 // + ) + { + // + CleanupArray( + maFastBuffer, + maxAllowed // + ); + + // + CleanupArray( + maFastColorBuffer, + maxAllowed // + ); + + // + CleanupArray( + maFastStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + maSlowBuffer, + maxAllowed // + ); + + // + CleanupArray( + maSlowColorBuffer, + maxAllowed // + ); + + // + CleanupArray( + maSlowStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + maBandUpperBuffer, + maxAllowed // + ); + + // + CleanupArray( + maBandLowerBuffer, + maxAllowed // + ); + + // + CleanupArray( + sarBuffer, + maxAllowed // + ); + + // + CleanupArray( + sarColorBuffer, + maxAllowed // + ); + + // + CleanupArray( + sarStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + peakBuffer, + maxAllowed // + ); + + // + CleanupArray( + valeBuffer, + maxAllowed // + ); + + // + CleanupArray( + fiboUpperBuffer, + maxAllowed // + ); + + // + CleanupArray( + fiboMiddleBuffer, + maxAllowed // + ); + + // + CleanupArray( + fiboLowerBuffer, + maxAllowed // + ); + + // + CleanupArray( + zigzagBuffer, + maxAllowed // + ); + + // + CleanupArray( + sHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + sLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + mHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + mLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + lHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + lLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + hHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + hLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + highsBuffer, + maxAllowed // + ); + + // + CleanupArray( + highsTimeBuffer, + maxAllowed // + ); + + // + CleanupArray( + lowsBuffer, + maxAllowed // + ); + + // + CleanupArray( + lowsTimeBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkOpenBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkHighBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkLowBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkCloseBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkColorBuffer, + maxAllowed // + ); + } + + // + // XHK Helper ... + + // + int ReadHKBars( + double &open[], + double &high[], + double &low[], + double &close[], + int barIndex = 0, + int count = 1 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + // Normalize ... + count = NormalizeInt(count, 1); + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + // Open ... + CopyBuffer( + mHandler, + XFIMA_HK_OPEN_LINE, + barIndex, + count, + open // + ); + + // + // High ... + CopyBuffer( + mHandler, + XFIMA_HK_HIGH_LINE, + barIndex, + count, + high // + ); + + // + // Low ... + CopyBuffer( + mHandler, + XFIMA_HK_LOW_LINE, + barIndex, + count, + low // + ); + + // + // Close ... + CopyBuffer( + mHandler, + XFIMA_HK_CLOSE_LINE, + barIndex, + count, + close // + ); + + // + ArraySetAsSeries(low, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(close, true); + + // + // Min Number of Array Sizes ... + result = MathMin(ArraySize(open), ArraySize(high)); + result = MathMin(result, ArraySize(close)); + result = MathMin(result, ArraySize(low)); + + // + return result; + } + + /** + * Validate HK Zone ... + * + * @param zone: XBoxZone, reference to Specified Zone ... + * @param validationLength: int, Validation Length of Zones ... + * @param breakValidLength: int, Break Validation Length of Zones ... + * @param validateFakeBreakes: bool, Validation Fake Breaked Zones ... + * + * @return ( bool ) + */ + bool ValidateHKZone( + XBoxZone &zone, + int validationLength = 1, + int breakValidLength = 3, + bool validateFakeBreakes = true // + ) + { + // + bool result = false; + + // + // Normalize ... + validationLength = NormalizeInt(validationLength, 1); + breakValidLength = NormalizeInt(breakValidLength, 2); + + // + // Validate ... + result = zone.IsValid(); + if (!result) + { + return result; + } + + // + // Requirements ... + double low[]; + double open[]; + double high[]; + int count = 0; + double close[]; + + // + int start = zone.FromIndex() + 1; + int end = start + validationLength; + + // + // Validate Before ... + for (int i = start; i < end; i++) + { + // + // Reading HK ... + count = ReadHKBars( + open, + high, + low, + close, + i, + 1 // + ); + result = IsValidSize(count); + if (!result) + { + break; + } + + // + result = zone.IsBullish() + ? low[0] > zone.lower + : high[0] < zone.upper; + if (!result) + { + break; + } + } + + // + // Validating After ... + if (result) + { + // + start = zone.ToIndex() + 1; + count = zone.FromIndex() - start; + end = start + count; + for (int i = start; i < end; i++) + { + // + // Reading HK ... + count = ReadHKBars( + open, + high, + low, + close, + i, + 1 // + ); + result = IsValidSize(count); + if (!result) + { + break; + } + + // + result = zone.IsBullish() + ? low[0] > zone.lower + : high[0] < zone.upper; + if (!result) + { + // + // Check For Fake Breake ... + if (validateFakeBreakes && breakValidLength > 0) + { + // + result = i - 1 >= 0; + if (result) + { + // + for (int j = i - 1; j >= zone.ToIndex(); j--) + { + // + // Reading HK ... + count = ReadHKBars( + open, + high, + low, + close, + j, + 1 // + ); + result = IsValidSize(count); + if (!result) + { + break; + } + + // + result = zone.IsBullish() + ? close[0] > zone.upper + : close[0] < zone.lower; + if (result) + { + // + result = MathAbs(j - i) <= breakValidLength; + if (result) + { + break; + } + } + } + } + } + + // + if (!result) + { + break; + } + } + } + } + + // + // Cleanup Resource ... + SpecifiedClean(low); + SpecifiedClean(open); + SpecifiedClean(high); + SpecifiedClean(close); + + // + return result; + } + + // + int ReadMAValues( + double &fast[], + double &slow[], + double &upper[], + double &lower[], + int barIndex = 0, + int count = 0 // + ) + { + // + int result = 0; + + // + // Prepare ... + SpecifiedClean(fast); + SpecifiedClean(slow); + SpecifiedClean(upper); + SpecifiedClean(lower); + + // + // Normalize ... + count = NormalizeInt(count, 1); + barIndex = NormalizeInt(barIndex, 0); + + // + // Validate ... + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + CopyBuffer( + mHandler, + XFIMA_MA_FAST_LINE, + barIndex, + count, + fast // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_SLOW_LINE, + barIndex, + count, + slow // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_BAND_UPPER_LINE, + barIndex, + count, + upper // + ); + + // + CopyBuffer( + mHandler, + XFIMA_MA_BAND_LOWER_LINE, + barIndex, + count, + lower // + ); + + // + ArraySetAsSeries(fast, true); + ArraySetAsSeries(slow, true); + ArraySetAsSeries(upper, true); + ArraySetAsSeries(lower, true); + + // + result = MathMin(ArraySize(fast), ArraySize(slow)); + result = MathMin(result, ArraySize(upper)); + result = MathMin(result, ArraySize(lower)); + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/x-saherelm.xfima.signaller.class copy.mq5 b/Documents/BKP/x-saherelm.xfima.signaller.class copy.mq5 new file mode 100644 index 00000000..89475e93 --- /dev/null +++ b/Documents/BKP/x-saherelm.xfima.signaller.class copy.mq5 @@ -0,0 +1,1697 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class +// ------------------------------------------------- +// Name: XCXFIMASignaller ... +// Description: XFIMA Signaller Class ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFIMA Signaller Class" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.x-signaller.class.mq5" +#include "../../Helpers/x-saherelm.xfima.helper.mq5" +#include "../Classes/x-saherelm.xfima.x-poi.detector.class.mq5" +#include "../Classes/x-saherelm.xfima.x-poi.drawer.class.mq5" + +// +// Implementation ... + +// +// Base XFIMA base Signaller ... +class XCXFIMABaseSignaller : public XCBaseSignaller +{ + // + // Public ... + public: + // + // Props ... + + // + XFIMAInputs fimaInputs; // XFIMA Inputs ... + XCXFIMAHelper *fimaHelper; // XFIMA Indicator Helper ... + XCXFIMAPOIDrawer *poiDrawer; // XFIMA POI Drawer ... + XCXFIMAPOIDetector *poiDetector; // XFIMA POI Detector ... + + // + // Constructor ... + XCXFIMABaseSignaller( + string _name, // Name ... + string _symbol, // Symbol ... + ENUM_TIMEFRAMES _period, // Period ... + XFIMAInputs &_fimaInputs, // XFIMAInputs ... + bool _processAllTicks = false, // Process All Ticks ... + double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... + double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... + double _defaultSignalVolume = 0.01 // Default Signal Volume ... + ) : XCBaseSignaller(_name, + _symbol, + _period, + _processAllTicks, + _defaultSignalR2R, + _defaultSignalRiskInPoint, + _defaultSignalVolume // + ) + { + // + // Instantiating XFIMA Indicator Helper Class ... + if (_fimaInputs.IsValid()) + { + // + fimaHelper = new XCXFIMAHelper(); + bool isInited = fimaHelper.Init( + _symbol, + _period, + _fimaInputs // + ); + if (isInited) + { + fimaInputs = _fimaInputs; + } + else + { + // + delete fimaHelper; + ZeroMemory(fimaHelper); + } + } + + // + poiDrawer = new XCXFIMAPOIDrawer(); + poiDetector = new XCXFIMAPOIDetector(fimaHelper); + } + + // + // Deconstructor ... + ~XCXFIMABaseSignaller() + { + Destroy(); + } + + // + // Overrides ... + + // + // Actions ... + + /** + * Destroy ... + */ + void Destroy() + { + // + BeforeDestroy(); + + // + fimaInputs.Clean(); + + // + delete fimaHelper; + ZeroMemory(fimaHelper); + + // + delete poiDrawer; + ZeroMemory(poiDrawer); + + // + delete poiDetector; + ZeroMemory(poiDetector); + } + + // + // Virtuals ... + + /** + * Before Destroy ... + */ + void virtual BeforeDestroy() + { + } + + /** + * Processing Tick ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessTick(int barIndex = 0) + { + } + + /** + * Processing New Bar ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessNewBar(int barIndex = 0) + { + } + + /** + * Check Guards Based on MarketConditions ... + * + * @param guards: XGuard[] + * @param barIndex: int + * + * @return ( int ) + */ + int virtual CheckForGuard( + XGuard &guards[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + SpecifiedClean(guards); + + // + result = ArraySize(guards); + + // + return result; + } + + /** + * Check Additional Validations on Childs Instances ... + * + * @return ( bool virtual ) + */ + bool virtual CheckAdditionslSignallerValidations() + { + // + bool result = false; + + // + // Validate Fima Helper Requirements ... + result = fimaInputs.IsValid() && + fimaHelper != NULL && + poiDetector != NULL; + + // + return result; + } + + /** + * Normalizing Signal by Signaller Custom Props ... + * + * @param signal: XSignal ... + */ + void virtual NormalizeSignal(XSignal &signal) + { + } + + // + // Protected ... + protected: + // + + // + // Protected Actions ... + + /** + * Check Specified Bar has Pattern or not ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param name: string, reference to holds Detected Patterns Name ... + * @param dir: ENUM_X_DIRECTION, reference to holds Detected Patterns Direction ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool HasPattern( + XOHCL &bar, + string &patternName, + ENUM_X_DIRECTION &patternDir, + XFIMAMarketStructure &structure // + ) + { + // + bool result = false; + + // + // Prepare ... + patternName = NULL; + patternDir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Check Required Pattern Exists ... + bool hasPinnedBar = HasDirection(structure.pinnedDir); + bool hasEngulfedBar = HasDirection(structure.engulfedDir); + bool hasFlagPattern = HasDirection(structure.flagPatternDir); + bool hasStarPattern = HasDirection(structure.starPatternDir); + bool hasRisingPattern = HasDirection(structure.risingPatternDir); + bool hasPiercingPattern = HasDirection(structure.piercingPatternDir); + bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir); + + // + // Check Bar Pattern Exists ... + // and Select Pattern Direction and Price and Price Type ... + result = hasPinnedBar || + hasEngulfedBar || + hasFlagPattern || + hasStarPattern || + hasSignalKeyBar || + hasRisingPattern || + hasPiercingPattern; + + // + if (result) + { + // + if (hasPinnedBar) + { + // + patternDir = structure.pinnedDir; + patternName = "XPinned_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasEngulfedBar) + { + // + patternDir = structure.engulfedDir; + patternName = "XEngulfed_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasFlagPattern) + { + // + patternDir = structure.flagPatternDir; + patternName = "XFlag_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasStarPattern) + { + // + patternDir = structure.starPatternDir; + patternName = "XStar_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasSignalKeyBar) + { + // + patternDir = structure.risingPatternDir; + patternName = "XRising_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasRisingPattern) + { + // + patternDir = structure.piercingPatternDir; + patternName = "XPiercing_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasPiercingPattern) + { + // + patternDir = structure.signalKeyBarPatternDir; + patternName = "XSignalKey_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + } + + // + result = + result && + IsXValid(patternName) && + HasDirection(patternDir); + + // + return result; + } + + /** + * Validate a Pattern based on MA Band ... + * + * @param bar: XOHCL, reference to Pattern Bar ... + * @param patternName: string, detected pattern's name ... + * @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ... + * @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * + * @return ( bool ) + */ + bool ValidatePatternBasedOnMABand( + XOHCL &bar, + string patternName, + ENUM_X_DIRECTION patternDir, + XFIMAConditions &fimaConditions // + ) + { + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + IsXValid(patternName) && + HasDirection(patternDir); + if (!result) + { + return result; + } + + // + // Define Requirements ... + bool isBullish = false; + bool isBearish = false; + double iPrice = EMPTY_VALUE; + double iPriceEdge = EMPTY_VALUE; + ENUM_X_PRICE iPriceType = X_PRICE_NONE; + ENUM_X_PRICE iPriceEdgeType = X_PRICE_NONE; + + // + // Calculating Price and Price Types ... + + // + isBullish = IsXBullish(patternDir); + isBearish = IsXBearish(patternDir); + + // + iPriceType = isBullish + ? X_PRICE_DOWN + : X_PRICE_UP; + + // + iPriceEdgeType = isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + iPrice = bar.GetPrice(iPriceType); + iPriceEdge = bar.GetPrice(iPriceEdgeType); + + // + // Validate ... + result = + NotEmptyZero(iPrice) && + IsXValid(iPriceType) && + NotEmptyZero(iPriceEdge) && + IsXValid(iPriceEdgeType) && + ((isBullish && !isBearish) || + (isBearish && !isBullish)); + if (!result) + { + return result; + } + + // + // Validate Pattern based on MA Band ... + + // + // Retrieve MA Band for Validation ... + double iMABandUpper = fimaConditions.maBandUpperBuffer[0]; + double iMABandLower = fimaConditions.maBandLowerBuffer[0]; + + // + // Validate by Edge Price ... + result = + NotEmptyZero(iMABandUpper) && + NotEmptyZero(iMABandLower) && + (isBullish + ? iPriceEdge < iMABandLower + : iPriceEdge > iMABandUpper); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Private ... + private: + // +}; + +// +// XFIMA Strategy 1 Signaller Class ... +class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller +{ + // + // Public ... + public: + // + // Props ... + int fvgLookupLenght; // Maximum Lenght for Looking up FVG before Crosses + + // + // Constructor ... + XCXFIMAStrategy1Signaller( + string _symbol, // Symbol ... + ENUM_TIMEFRAMES _period, // Period ... + XFIMAInputs &_fimaInputs, // XFIMAInputs ... + bool _processAllTicks = false, // Process All Ticks ... + double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... + double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... + double _defaultSignalVolume = 0.01 // Default Signal Volume ... + ) : XCXFIMABaseSignaller("XFIMA1", + _symbol, + _period, + _fimaInputs, + _processAllTicks, + _defaultSignalR2R, + _defaultSignalRiskInPoint, + _defaultSignalVolume // + ) + { + // + fvgLookupLenght = 5; + } + + // + // Overrides ... + + /** + * Processing Tick ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessTick(int barIndex = 0) + { + } + + /** + * Processing New Bar ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessNewBar(int barIndex = 0) + { + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + XOHCL bar; + XSignal signal; + bool has = false; + int cIdx = barIndex + 1; + int pIdx = cIdx + 1; + ENUM_X_DIRECTION signalDir = X_DIRECTION_NONE; + + // + // Initialize Bar as CBar ... + has = bar.Init( + symbol, + period, + cIdx // + ); + if (!has) + { + // + bar.Clean(); + return; + } + + // + // Retrieve Conditions ... + XFIMAConditions fimaConditions; + has = fimaHelper.GetConditions( + fimaConditions, + barIndex, + 10 // Loopback ... + ); + if (!has) + { + // + bar.Clean(); + fimaConditions.Clean(); + + // + return; + } + + // + // Analyse Conditions for Finding Signal ... + + // + // TODO: Remove this ... + + // + bool isFastCrossedOverSlow = + fimaConditions.maFastBuffer[cIdx] > fimaConditions.maSlowBuffer[cIdx] && + fimaConditions.maFastBuffer[pIdx] < fimaConditions.maSlowBuffer[pIdx]; + + // + bool isFastCrossedUnderSlow = + fimaConditions.maFastBuffer[cIdx] < fimaConditions.maSlowBuffer[cIdx] && + fimaConditions.maFastBuffer[pIdx] > fimaConditions.maSlowBuffer[pIdx]; + + // + has = + isFastCrossedOverSlow || + isFastCrossedUnderSlow; + if (has) + { + // + // Do Conditions Validating ... + // TODO: Igmore All Validations for Testing Purposes ... + + // + // Validate MA Positions ... + double iFastMa = fimaConditions.maFastBuffer[cIdx]; + double iSlowMa = fimaConditions.maSlowBuffer[cIdx]; + double iFiboUpper = fimaConditions.fiboUpperBuffer[cIdx]; + double iFiboLower = fimaConditions.fiboLowerBuffer[cIdx]; + + // + // Checking Has FVG ... + XBoxZone fvg; + ENUM_X_DIRECTION fvgDir; + bool hasFVG = patternDetector.HasFVG( + bar, + fvgDir, + fvg, + fvgLookupLenght // + ); + + // + // Checking Crossed On Shadow ... + + // + bool isCrossedOverHappensOnShadow = + isFastCrossedOverSlow && + iFastMa <= bar.GetDown() && + iFastMa >= bar.low; + + // + bool isCrossedUnderHappensOnShadow = + isFastCrossedUnderSlow && + iFastMa <= bar.high && + iFastMa >= bar.GetUp(); + + // + // Bullish Validation ... + bool isBullish = + // + // Has Cross ... + isFastCrossedOverSlow + // + // && + // // + // // Cross Places Based on Fibo ... + // MathMax(iFastMa, iSlowMa) < iFiboLower + // // + // && + // // + // ( + // // + // // Checking FVG ... + // (hasFVG && + // fvg.IsBullish()) + // // + // || + // // + // // Checking Crossed Place ... + // isCrossedOverHappensOnShadow + // // + // ) + // // + ; + + // + // Bearish Validation ... + bool isBearish = + // + // Has Cross ... + isFastCrossedUnderSlow + // + // && + // // + // // Cross Places Based on Fibo ... + // MathMin(iFastMa, iSlowMa) > iFiboUpper + // // + // && + // // + // ( + // // + // // Checking FVG ... + // (hasFVG && + // fvg.IsBearish()) + // // + // || + // // + // // Checking Crossed Place ... + // isCrossedUnderHappensOnShadow + // // + // ) + // // + ; + + // + has = + (isBullish && !isBearish) || + (isBearish && !isBullish); + if (has) + { + // + signalDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + } + } + + // + // Check Signal Founded ... + has = HasDirection(signalDir); + if (has) + { + // + // Prepare Founded Signal ... + XTarget targets[]; + has = PrepareSignal( + signal, + signalDir, + targets // + ); + if (has) + { + // + // Notify On Signal Event ... + NotifySignalEventListeners(signal); + } + } + + // + // Cleanup Resources ... + bar.Clean(); + signal.Clean(); + fimaConditions.Clean(); + } + + /** + * Check Guards Based on MarketConditions ... + * + * @param guards: XGuard[] + * @param barIndex: int + * + * @return ( int ) + */ + int virtual CheckForGuard( + XGuard &guards[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + SpecifiedClean(guards); + + // + result = ArraySize(guards); + + // + return result; + } + + // + // Private ... + private: + // + // Props ... + + // + // Lookup FVG ... + bool LookupFVG( + XOHCL &bar, + ENUM_X_DIRECTION &dir, + XBoxZone &fvgBox // + ) + { + // + bool result = false; + + // + return result; + } + + // +}; + +// +// XFIMA Strategy 2 Signaller Class ... +class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller +{ + // + // Public ... + public: + // + // Props ... + XFIMAPatternDetectorConfig analyserConfig; + + // + // Constructor ... + XCXFIMAStrategy2Signaller( + string _symbol, // Symbol ... + ENUM_TIMEFRAMES _period, // Period ... + XFIMAInputs &_fimaInputs, // XFIMAInputs ... + bool _processAllTicks = false, // Process All Ticks ... + double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... + double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... + double _defaultSignalVolume = 0.01 // Default Signal Volume ... + ) : XCXFIMABaseSignaller("XFIMA2", + _symbol, + _period, + _fimaInputs, + _processAllTicks, + _defaultSignalR2R, + _defaultSignalRiskInPoint, + _defaultSignalVolume // + ) + { + // + // Configure Detector ... + // + analyserConfig.Default(); + analyserConfig.validMACrossDiffMultiplier = 4; + + // + analyserConfig.FullDetect(); + } + + // + // Deconstructor ... + ~XCXFIMAStrategy2Signaller() + { + // + Destroy(); + + // + analyserConfig.Clean(); + } + + // + // Overrides ... + + /** + * Processing Tick ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessTick(int barIndex = 0) + { + } + + /** + * Processing New Bar ... + * + * @param barIndex: int, Specified Bar Index ... + */ + virtual void ProcessNewBar(int barIndex = 0) + { + // + // Normalize ... + barIndex = NormalizeInt(barIndex, 0); + + // + XOHCL iBar; + int count = 0; + XBoxZone iZone; + XSignal iSignal; + bool has = false; + XTarget targets[]; + string iName = NULL; + XBoxZone supports[]; + XBoxZone resistances[]; + bool isBullish = false; + bool isBearish = false; + int numberOfPivots = 25; + XFIMAConditions iFIMAConditions; + XFIMAMarketStructure iStructure; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + XPivot pvPivots[]; + string pvTrendName = "XXIFMA2PVTrend"; + CChartObjectTrend *pvTrendLine = NULL; + ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE; + + // + XPivot zgPivots[]; + string zgTrendName = "XFIMA2ZGTrend"; + CChartObjectTrend *zgTrendLine = NULL; + ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE; + + // + // Initialize Bar as CBar ... + has = iBar.Init( + symbol, + period, + barIndex // + ); + if (!has) + { + // + iBar.Clean(); + return; + } + + // + // Retrieve Conditions ... + has = fimaHelper.GetConditions( + iFIMAConditions, + barIndex, + 10 // Loopback ... + ); + if (!has) + { + // + iBar.Clean(); + iFIMAConditions.Clean(); + + // + return; + } + + // + // Analyse Market ... + poiDetector.AnalyseMarket( + iBar, + iStructure, + analyserConfig // + ); + + // + // Collect Support and Resistance Zones and Validate by them ... + + // + // PV Trend Line ... + bool hasPVAnalysis = iStructure.pvAnalysis.IsValid(); + if (hasPVAnalysis) + { + // + // Support ... + XBoxZone supportBox; + has = iStructure.pvAnalysis.HasSupportBox(supportBox); + if (has) + { + // + supportBox.to = iBar.time; + AddIfNotExists( + supportBox, + supports // + ); + } + + // + // Resistance ... + XBoxZone resistanceBox; + has = iStructure.pvAnalysis.HasResistanceBox(resistanceBox); + if (has) + { + // + resistanceBox.to = iBar.time; + AddIfNotExists( + resistanceBox, + supports // + ); + } + + // + // Pivots ... + XPivot pivots[]; + count = poiDetector.ExtractPVPivots( + pivots, + barIndex, + numberOfPivots // + ); + has = IsValidSize(count); + + // + // Sort ... + Sort( + pivots, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Remove Newest ... + ArrayRemove( + pivots, + 0, + 1 // + ); + + // + // Check Trend ... + if (has) + { + // + XPivot highs[]; + int highsCount = ExtractPivots( + highs, + pivots, + X_PIVOT_TYPE_PEAK // + ); + Sort( + highs, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + XPivot lows[]; + int lowsCount = ExtractPivots( + lows, + pivots, + X_PIVOT_TYPE_VALE // + ); + Sort( + lows, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Check Highs and Lows ... + has = IsValidSize(lowsCount) && + IsValidSize(highsCount) && + lowsCount >= 2 && + highsCount >= 2; + if (has) + { + // + // Try to Get Market Strucutre ... + + // + bool hasLowerHigh = highs[0].value < highs[1].value; + bool hasLowerLow = lows[0].value < lows[1].value; + + // + bool hasHigherHigh = highs[0].value > highs[1].value; + bool hasHigherLow = lows[0].value > lows[1].value; + + // + pvTrend = + (hasHigherHigh && + hasHigherLow) + ? X_DIRECTION_BULLISH + : (hasLowerHigh && + hasLowerLow) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(pvTrend); + if (has) + { + // + // Select Swings for Trend Line ... + XOHCL tmpBar; + int llIDX = -1; + int hhIDX = -1; + datetime toTime = NULL; + datetime fromTime = NULL; + double toPrice = EMPTY_VALUE; + color trendColor = CLR_NONE; + double fromPrice = EMPTY_VALUE; + if (IsSpecifiedBullish(pvTrend)) + { + // + llIDX = GetLowest(lows); + hhIDX = GetHighest(lows); + + // + trendColor = clrAqua; + + // + toTime = lows[hhIDX].time; + toPrice = lows[hhIDX].value; + + // + fromTime = lows[llIDX].time; + fromPrice = lows[llIDX].value; + } + else + { + // + llIDX = GetLowest(highs); + hhIDX = GetHighest(highs); + + // + trendColor = clrMagenta; + + // + toTime = highs[llIDX].time; + toPrice = highs[llIDX].value; + + // + fromTime = highs[hhIDX].time; + fromPrice = highs[hhIDX].value; + } + + // + // Check Requirements for Trend ... + has = + NotEmptyZero(toPrice) && + NotEmptyZero(fromPrice) && + IsSpecifiedValid(toTime) && + IsSpecifiedValid(fromTime); + if (has) + { + // + has = poiDrawer.DrawTrendLine( + fromPrice, + fromTime, + toPrice, + toTime, + pvTrendLine, + pvTrendName, + true // Ray Right ... + ); + if (has) + { + pvTrendLine.Color(trendColor); + } + } + + // + // Cleanup Resources ... + tmpBar.Clean(); + } + + // + if (!has) + { + SpecifiedClean(pivots); + } + } + + // + // Cleanup Resources ... + SpecifiedClean(lows); + SpecifiedClean(highs); + } + + // + has = HasChild(pivots); + if (has) + { + // + Copy( + pivots, + pvPivots // + ); + } + + // + // Cleanup Resources ... + SpecifiedClean(pivots); + } + + // + // ZigZag Trend Line ... + bool hasZGAnalysis = iStructure.zigzagAnalysis.IsValid(); + if (hasZGAnalysis) + { + // + // Support ... + XBoxZone supportBox; + has = iStructure.zigzagAnalysis.HasSupportBox(supportBox); + if (has) + { + // + supportBox.to = iBar.time; + AddIfNotExists( + supportBox, + supports // + ); + } + + // + // Resistance ... + XBoxZone resistanceBox; + has = iStructure.zigzagAnalysis.HasResistanceBox(resistanceBox); + if (has) + { + // + resistanceBox.to = iBar.time; + AddIfNotExists( + resistanceBox, + supports // + ); + } + + // + // Pivots ... + XPivot pivots[]; + count = poiDetector.ExtractZigZagPivots( + pivots, + barIndex, + numberOfPivots // + ); + has = IsValidSize(count); + + // + // Sort ... + Sort( + pivots, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Remove Newest ... + ArrayRemove( + pivots, + 0, + 1 // + ); + + // + // Check Trend ... + if (has) + { + // + XPivot highs[]; + int highsCount = ExtractPivots( + highs, + pivots, + X_PIVOT_TYPE_PEAK // + ); + Sort( + highs, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + XPivot lows[]; + int lowsCount = ExtractPivots( + lows, + pivots, + X_PIVOT_TYPE_VALE // + ); + Sort( + lows, + X_SORT_BY_DATE, + X_DIRECTION_BEARISH // + ); + + // + // Check Highs and Lows ... + has = IsValidSize(lowsCount) && + IsValidSize(highsCount) && + lowsCount >= 2 && + highsCount >= 2; + if (has) + { + // + // Try to Get Market Strucutre ... + + // + bool hasLowerHigh = highs[0].value < highs[1].value; + bool hasLowerLow = lows[0].value < lows[1].value; + + // + bool hasHigherHigh = highs[0].value > highs[1].value; + bool hasHigherLow = lows[0].value > lows[1].value; + + // + zgTrend = + (hasHigherHigh && + hasHigherLow) + ? X_DIRECTION_BULLISH + : (hasLowerHigh && + hasLowerLow) + ? X_DIRECTION_BEARISH + : X_DIRECTION_NONE; + has = HasDirection(zgTrend); + if (has) + { + // + // Select Swings for Trend Line ... + XOHCL tmpBar; + int llIDX = -1; + int hhIDX = -1; + datetime toTime = NULL; + datetime fromTime = NULL; + double toPrice = EMPTY_VALUE; + color trendColor = CLR_NONE; + double fromPrice = EMPTY_VALUE; + if (IsSpecifiedBullish(zgTrend)) + { + // + llIDX = GetLowest(lows); + hhIDX = GetHighest(lows); + + // + trendColor = clrAqua; + + // + toTime = lows[hhIDX].time; + toPrice = lows[hhIDX].value; + + // + fromTime = lows[llIDX].time; + fromPrice = lows[llIDX].value; + } + else + { + // + llIDX = GetLowest(highs); + hhIDX = GetHighest(highs); + + // + trendColor = clrMagenta; + + // + toTime = highs[llIDX].time; + toPrice = highs[llIDX].value; + + // + fromTime = highs[hhIDX].time; + fromPrice = highs[hhIDX].value; + } + + // + // Check Requirements for Trend ... + has = + NotEmptyZero(toPrice) && + NotEmptyZero(fromPrice) && + IsSpecifiedValid(toTime) && + IsSpecifiedValid(fromTime); + if (has) + { + // + has = poiDrawer.DrawTrendLine( + fromPrice, + fromTime, + toPrice, + toTime, + zgTrendLine, + zgTrendName, + true // Ray Right ... + ); + if (has) + { + zgTrendLine.Color(trendColor); + } + } + + // + // Cleanup Resources ... + tmpBar.Clean(); + } + + // + if (!has) + { + SpecifiedClean(pivots); + } + } + + // + // Cleanup Resources ... + SpecifiedClean(lows); + SpecifiedClean(highs); + } + + // + has = HasChild(pivots); + if (has) + { + // + Copy( + pivots, + zgPivots // + ); + } + + // + // Cleanup Resources ... + SpecifiedClean(pivots); + } + + // + // Support ... + bool hasSupport = iStructure.support.IsValid(); + if (hasSupport) + { + // + iStructure.support.to = iBar.time; + AddIfNotExists( + iStructure.support, + supports // + ); + } + + // + // Resistance ... + bool hasResistance = iStructure.resistance.IsValid(); + if (hasResistance) + { + // + iStructure.resistance.to = iBar.time; + AddIfNotExists( + iStructure.resistance, + resistances // + ); + } + + // + // Disable Signallers ... + has = false; + + // + // Strategy 1 ... + // Works on Support or Resistances Areas ... + // has = Strategy1HasSignal( + // iBar, + // iZone, + // supports, + // resistances, + // iDir, + // iStructure, + // iFIMAConditions // + // ); + + // + // Strategy 2 ... + // Works on MA Crosses ... + has = Strategy2HasSignal( + iBar, + iZone, + supports, + resistances, + iDir, + iStructure, + iFIMAConditions // + ); + + // + has = HasDirection(iDir); + if (has) + { + // + isBullish = IsXBullish(iDir); + isBearish = IsXBearish(iDir); + + // + // TODO: Provided SL ... + double _point = GetPoints(iBar.symbol); + double slAddition = 5 * _point; + double slPrice = + isBullish + ? iZone.lower - slAddition + : iZone.upper + slAddition; + + // + // Prepare Founded Signal ... + has = PrepareSignal( + iSignal, + iDir, + targets, + 0, // Use Default R2R ... + slPrice, // Provided Price for SL ... + 0 // Specified Risk in Point .... + ); + if (has) + { + // + // Notify On Signal Event ... + NotifySignalEventListeners(iSignal); + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + iZone.Clean(); + iSignal.Clean(); + iStructure.Clean(); + iFIMAConditions.Clean(); + SpecifiedClean(targets); + SpecifiedClean(pvPivots); + SpecifiedClean(zgPivots); + SpecifiedClean(supports); + SpecifiedClean(resistances); + } + + /** + * Check Guards Based on MarketConditions ... + * + * @param guards: XGuard[] + * @param barIndex: int + * + * @return ( int ) + */ + int virtual CheckForGuard( + XGuard &guards[], + int barIndex = 0 // + ) + { + // + int result = 0; + + // + SpecifiedClean(guards); + + // + result = ArraySize(guards); + + // + return result; + } + + // + // Private ... + private: + // + // Props ... + + // + // Implementing Strategies ... + + /** + * Check Bar Has Signal Based on Strategy 1 ... + * + * @param bar: XOHCL, reference to Bar ... + * @param iZone: XBoxZone, reference to holds affected zone ... + * @param supports: XBoxZone, array reference to Provide Exists Supports ... + * @param resistances: XBoxZone, array reference to Provide Exists Resistances ... + * @param iDir: ENUM_X_DIRECTION, detected Signal's direction ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * + * @return ( bool ) + */ + bool Strategy1HasSignal( + XOHCL &bar, + XBoxZone &iZone, + XBoxZone &supports[], + XBoxZone &resistances[], + ENUM_X_DIRECTION &iDir, + XFIMAMarketStructure &structure, + XFIMAConditions &conditions // + ) + { + // + bool result = false; + + // + // Prepare ... + iZone.Clean(); + iDir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Check Pattern Exists ... + string patternName = NULL; + ENUM_X_DIRECTION patternDir = X_DIRECTION_NONE; + result = HasPattern( + bar, + patternName, + patternDir, + structure // + ); + if (!result) + { + return result; + } + + // + // Validate Pattern Based on MA Band ... + result = ValidatePatternBasedOnMABand( + bar, + patternName, + patternDir, + conditions // + ); + if (!result) + { + return result; + } + + // + // Check Affected Zone ... + // Select a Support or Resistance ... + int insideZoneIDX = -1; + result = + (IsXBullish(patternDir) + ? HasInside( + insideZoneIDX, + bar, + supports // + ) + : IsXBearish(patternDir) + ? HasInside( + insideZoneIDX, + bar, + resistances // + ) + : false // + ); + if (!result) + { + return result; + } + + // + // Filling Affected Zone ... + // and Validate it ... + if (IsXBullish(patternDir)) + { + iZone = supports[insideZoneIDX]; + } + else if (IsXBearish(patternDir)) + { + iZone = resistances[insideZoneIDX]; + } + result = iZone.IsValid(); + if (!result) + { + return result; + } + + // + // Validate affected Zone based on Pattern's Bar ... + result = IsXBullish(patternDir) + ? bar.high > iZone.upper + : IsXBearish(patternDir) + ? bar.low < iZone.lower + : false; + if (result) + { + iDir = patternDir; + } + + // + // Cleanup Resources ... + if (!result) + { + iZone.Clean(); + } + + // + return result; + } + + /** + * Check Bar Has Signal Based on Strategy 1 ... + * + * @param bar: XOHCL, reference to Bar ... + * @param iZone: XBoxZone, reference to holds affected zone ... + * @param supports: XBoxZone, array reference to Provide Exists Supports ... + * @param resistances: XBoxZone, array reference to Provide Exists Resistances ... + * @param iDir: ENUM_X_DIRECTION, detected Signal's direction ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * @param conditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * + * @return ( bool ) + */ + bool Strategy2HasSignal( + XOHCL &bar, + XBoxZone &iZone, + XBoxZone &supports[], + XBoxZone &resistances[], + ENUM_X_DIRECTION &iDir, + XFIMAMarketStructure &structure, + XFIMAConditions &conditions // + ) + { + // + bool result = false; + + // + // Prepare ... + iZone.Clean(); + iDir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Detect Specified MA Cross ... + result = HasDirection(structure.maCrossDir); + + // + // Validate Conditions ... + + // + // Prepare iZone ... + iZone.to = bar.time; + iZone.from = GetBarTime( + bar.symbol, + bar.period, + bar.Index() + 2 // + ); + iZone.symbol = bar.symbol; + iZone.period = bar.period; + iZone.dir = structure.maCrossDir; + iZone.lower = bar.FindLowest(2, MODE_LOW); + iZone.upper = bar.FindHighest(2, MODE_HIGH); + iZone.type = name + "_" + ToXString(structure.maCrossDir); + + // + // Check Result ... + result = iZone.IsValid(); + if (result) + { + iDir = structure.maCrossDir; + } + + // + // Cleanup Resources ... + if (!result) + { + iZone.Clean(); + } + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Experts/x-saherelm.xfima.backtester.ea.mq5 b/Experts/x-saherelm.xfima.backtester.ea.mq5 index d336bf3a..bcb897d0 100644 --- a/Experts/x-saherelm.xfima.backtester.ea.mq5 +++ b/Experts/x-saherelm.xfima.backtester.ea.mq5 @@ -146,7 +146,6 @@ XCBackTesterEA *eaExpert; // EA Expert ... // // Registered Signallers ... XCXFIMAStrategy1Signaller *fima1Signaller; // XFIMA1 Signaller ... -XCXFIMAStrategy2Signaller *fima2Signaller; // XFIMA2 Signaller ... // XFIMAMarketStructure marketStructure; // POI Analysis Result ... @@ -322,23 +321,9 @@ int OnInit() ); fima1Signaller.AddOnSignalEventHandler(OnSignalTriggered); - // - // XFIMA2 Signaller ... - fima2Signaller = new XCXFIMAStrategy2Signaller( - _Symbol, - _Period, - fimaInputs, - eaProcessAllTicks, // Process All Ticks ... - eaSignallerR2R, // Signaller Risk to Reward Ratio ... - eaSignallerRiskInPoint, // Default Risk In Points ... - eaSignallerVolume // Defaul Volume ... - ); - fima2Signaller.AddOnSignalEventHandler(OnSignalTriggered); - // isInited = - fima1Signaller.IsValid() && - fima2Signaller.IsValid(); + fima1Signaller.IsValid(); if (!isInited) { // @@ -427,10 +412,6 @@ void OnDeinit(const int reason) delete fima1Signaller; ZeroMemory(fima1Signaller); - // - delete fima2Signaller; - ZeroMemory(fima2Signaller); - // delete eaExpert; ZeroMemory(eaExpert); @@ -459,8 +440,7 @@ void OnTick() int barIndex = 1; // - // fima1Signaller.OnTick(barIndex); - fima2Signaller.OnTick(barIndex); + fima1Signaller.OnTick(barIndex); // // AnalyseMarket(barIndex); @@ -624,7 +604,7 @@ void OnSignalTriggered(XSignal &signal) // // Draw Signal on Chart ... XCSignalObject *iSignalObj; - bool has = fima2Signaller.poiDrawer.DrawSignal( + bool has = fima1Signaller.poiDrawer.DrawSignal( signal, iSignalObj, 7 // @@ -823,8 +803,8 @@ void AnalyseMarket(int barIndex = 0) barIndex = NormalizeInt(barIndex, 0); // - string symbol = fima2Signaller.symbol; - ENUM_TIMEFRAMES period = fima2Signaller.period; + string symbol = fima1Signaller.symbol; + ENUM_TIMEFRAMES period = fima1Signaller.period; // // Retrieve Signal Bar ... @@ -922,998 +902,14 @@ void AnalyseMarket(int barIndex = 0) // // Analyse Market on Signalling Bar ... - fima2Signaller.poiDetector.AnalyseMarket( + fima1Signaller.poiDetector.AnalyseMarket( bar, marketStructure, detectorConfig // ); - // - XFIMASIgballer2First(bar); - // HandleLookupSignal(bar); - // bar.Clean(); } -// -// Handle Signal Looking Up ... -// Register it as XFIMA Signaller 2 ... -void XFIMASIgballer2First(XOHCL &bar) -{ - // - bool has = - bar.IsValid(); - if (!has) - { - return; - } - - // - XBoxZone iZone; - XSignal iSignal; - string iName = NULL; - XBoxZone supports[]; - XBoxZone resistances[]; - bool isBullish = false; - int barIndex = bar.Index(); - double iPrice = EMPTY_VALUE; - ENUM_X_PRICE iPriceType = X_PRICE_NONE; - ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; - - // - // Check Required Pattern Exists ... - bool hasPinnedBar = HasDirection(marketStructure.pinnedDir); - bool hasEngulfedBar = HasDirection(marketStructure.engulfedDir); - bool hasFlagPattern = HasDirection(marketStructure.flagPatternDir); - bool hasStarPattern = HasDirection(marketStructure.starPatternDir); - bool hasRisingPattern = HasDirection(marketStructure.risingPatternDir); - bool hasPiercingPattern = HasDirection(marketStructure.piercingPatternDir); - bool hasSignalKeyBar = HasDirection(marketStructure.signalKeyBarPatternDir); - - // - // PV Trend Line ... - string pvTrendName = "XPVTrend"; - CChartObjectTrend *pvTrendLine = NULL; - ENUM_X_DIRECTION pvTrend = X_DIRECTION_NONE; - - // - // ZigZag Trend Line ... - string zgTrendName = "XZGTrend"; - CChartObjectTrend *zgTrendLine = NULL; - ENUM_X_DIRECTION zgTrend = X_DIRECTION_NONE; - - // - // Check PV Analysis ... - bool hasPVAnalysis = marketStructure.pvAnalysis.IsValid(); - if (hasPVAnalysis) - { - // - // Support ... - XBoxZone supportBox; - XCBoxObject *iSupportObj; - has = marketStructure.pvAnalysis.HasSupportBox(supportBox); - if (has) - { - // - supportBox.to = bar.time; - AddIfNotExists( - supportBox, - supports // - ); - has = fima2Signaller.poiDrawer.DrawBox( - supportBox, - iSupportObj, - true, // Ignore At ... - supportBox.type // Name ... - ); - if (has) - { - // - XPOIStyle iStyle; - fima2Signaller.poiDrawer.GetBoxStyle( - iStyle, - supportBox.dir // - ); - fima2Signaller.poiDrawer.ApplyBoxStyle( - iSupportObj, - iStyle // - ); - iStyle.Clean(); - } - } - - // - // Resistance ... - XBoxZone resistanceBox; - XCBoxObject *iResistanceObj; - has = marketStructure.pvAnalysis.HasResistanceBox(resistanceBox); - if (has) - { - // - resistanceBox.to = bar.time; - AddIfNotExists( - resistanceBox, - supports // - ); - has = fima2Signaller.poiDrawer.DrawBox( - resistanceBox, - iResistanceObj, - true, // Ignore At ... - resistanceBox.type // Name ... - ); - if (has) - { - // - XPOIStyle iStyle; - fima2Signaller.poiDrawer.GetBoxStyle( - iStyle, - resistanceBox.dir // - ); - fima2Signaller.poiDrawer.ApplyBoxStyle( - iResistanceObj, - iStyle // - ); - iStyle.Clean(); - } - } - - // - // Pivots ... - XPivot pivots[]; - int pivotsCount = fima2Signaller.poiDetector.ExtractPVPivots( - pivots, - barIndex, - 50 // - ); - has = IsValidSize(pivotsCount); - - // - // Sort ... - Sort( - pivots, - X_SORT_BY_DATE, - X_DIRECTION_BEARISH // - ); - - // - // Remove Newest ... - ArrayRemove( - pivots, - 0, - 1 // - ); - - // - // Check Trend ... - if (has) - { - // - XPivot highs[]; - int highsCount = ExtractPivots( - highs, - pivots, - X_PIVOT_TYPE_PEAK // - ); - Sort( - highs, - X_SORT_BY_DATE, - X_DIRECTION_BEARISH // - ); - - // - XPivot lows[]; - int lowsCount = ExtractPivots( - lows, - pivots, - X_PIVOT_TYPE_VALE // - ); - Sort( - lows, - X_SORT_BY_DATE, - X_DIRECTION_BEARISH // - ); - - // - // Check Highs and Lows ... - has = IsValidSize(lowsCount) && - IsValidSize(highsCount) && - lowsCount >= 2 && - highsCount >= 2; - if (has) - { - // - // Try to Get Market Strucutre ... - - // - bool hasLowerHigh = highs[0].value < highs[1].value; - bool hasLowerLow = lows[0].value < lows[1].value; - - // - bool hasHigherHigh = highs[0].value > highs[1].value; - bool hasHigherLow = lows[0].value > lows[1].value; - - // - pvTrend = - (hasHigherHigh && - hasHigherLow) - ? X_DIRECTION_BULLISH - : (hasLowerHigh && - hasLowerLow) - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - has = HasDirection(pvTrend); - if (has) - { - // - // Select Swings for Trend Line ... - XOHCL tmpBar; - int llIDX = -1; - int hhIDX = -1; - datetime toTime = NULL; - datetime fromTime = NULL; - double toPrice = EMPTY_VALUE; - color trendColor = CLR_NONE; - double fromPrice = EMPTY_VALUE; - if (IsSpecifiedBullish(pvTrend)) - { - // - llIDX = GetLowest(lows); - hhIDX = GetHighest(lows); - - // - trendColor = clrAqua; - - // - toTime = lows[hhIDX].time; - toPrice = lows[hhIDX].value; - - // - fromTime = lows[llIDX].time; - fromPrice = lows[llIDX].value; - } - else - { - // - llIDX = GetLowest(highs); - hhIDX = GetHighest(highs); - - // - trendColor = clrMagenta; - - // - toTime = highs[llIDX].time; - toPrice = highs[llIDX].value; - - // - fromTime = highs[hhIDX].time; - fromPrice = highs[hhIDX].value; - } - - // - // Check Requirements for Trend ... - has = - NotEmptyZero(toPrice) && - NotEmptyZero(fromPrice) && - IsSpecifiedValid(toTime) && - IsSpecifiedValid(fromTime); - if (has) - { - // - has = fima2Signaller.poiDrawer.DrawTrendLine( - fromPrice, - fromTime, - toPrice, - toTime, - pvTrendLine, - pvTrendName, - true // Ray Right ... - ); - if (has) - { - pvTrendLine.Color(trendColor); - } - } - - // - // Cleanup Resources ... - tmpBar.Clean(); - } - - // - if (!has) - { - SpecifiedClean(pivots); - } - } - - // - // Cleanup Resources ... - SpecifiedClean(lows); - SpecifiedClean(highs); - } - - // - // Draw Pivots ... - has = HasChild(pivots); - if (has) - { - // - CArrayObj *drawnPivots = new CArrayObj(); - pivotsCount = fima2Signaller.poiDrawer.DrawPivots( - pivots, - drawnPivots // - ); - } - - // - // Cleanup Resources ... - SpecifiedClean(pivots); - } - - // - // Check ZigZag Analysis ... - bool hasZGAnalysis = marketStructure.zigzagAnalysis.IsValid(); - if (hasZGAnalysis) - { - // - // Support ... - XBoxZone supportBox; - XCBoxObject *iSupportObj; - has = marketStructure.zigzagAnalysis.HasSupportBox(supportBox); - if (has) - { - // - supportBox.to = bar.time; - AddIfNotExists( - supportBox, - supports // - ); - has = fima2Signaller.poiDrawer.DrawBox( - supportBox, - iSupportObj, - true, // Ignore At ... - supportBox.type // Name ... - ); - if (has) - { - // - XPOIStyle iStyle; - fima2Signaller.poiDrawer.GetBoxStyle( - iStyle, - supportBox.dir // - ); - fima2Signaller.poiDrawer.ApplyBoxStyle( - iSupportObj, - iStyle // - ); - iStyle.Clean(); - } - } - - // - // Resistance ... - XBoxZone resistanceBox; - XCBoxObject *iResistanceObj; - has = marketStructure.zigzagAnalysis.HasResistanceBox(resistanceBox); - if (has) - { - // - resistanceBox.to = bar.time; - AddIfNotExists( - resistanceBox, - supports // - ); - has = fima2Signaller.poiDrawer.DrawBox( - resistanceBox, - iResistanceObj, - true, // Ignore At ... - resistanceBox.type // Name ... - ); - if (has) - { - // - XPOIStyle iStyle; - fima2Signaller.poiDrawer.GetBoxStyle( - iStyle, - resistanceBox.dir // - ); - fima2Signaller.poiDrawer.ApplyBoxStyle( - iResistanceObj, - iStyle // - ); - iStyle.Clean(); - } - } - - // - // Pivots ... - XPivot pivots[]; - int pivotsCount = fima2Signaller.poiDetector.ExtractZigZagPivots( - pivots, - barIndex, - 10 // - ); - has = IsValidSize(pivotsCount); - - // - // Sort ... - Sort( - pivots, - X_SORT_BY_DATE, - X_DIRECTION_BEARISH // - ); - - // - // Remove Newest ... - ArrayRemove( - pivots, - 0, - 1 // - ); - - // - // Check Trend ... - if (has) - { - // - XPivot highs[]; - int highsCount = ExtractPivots( - highs, - pivots, - X_PIVOT_TYPE_PEAK // - ); - Sort( - highs, - X_SORT_BY_DATE, - X_DIRECTION_BEARISH // - ); - - // - XPivot lows[]; - int lowsCount = ExtractPivots( - lows, - pivots, - X_PIVOT_TYPE_VALE // - ); - Sort( - lows, - X_SORT_BY_DATE, - X_DIRECTION_BEARISH // - ); - - // - // Check Highs and Lows ... - has = IsValidSize(lowsCount) && - IsValidSize(highsCount) && - lowsCount >= 2 && - highsCount >= 2; - if (has) - { - // - // Try to Get Market Strucutre ... - - // - bool hasLowerHigh = highs[0].value < highs[1].value; - bool hasLowerLow = lows[0].value < lows[1].value; - - // - bool hasHigherHigh = highs[0].value > highs[1].value; - bool hasHigherLow = lows[0].value > lows[1].value; - - // - zgTrend = - (hasHigherHigh && - hasHigherLow) - ? X_DIRECTION_BULLISH - : (hasLowerHigh && - hasLowerLow) - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - has = HasDirection(zgTrend); - if (has) - { - // - // Select Swings for Trend Line ... - XOHCL tmpBar; - int llIDX = -1; - int hhIDX = -1; - datetime toTime = NULL; - datetime fromTime = NULL; - double toPrice = EMPTY_VALUE; - color trendColor = CLR_NONE; - double fromPrice = EMPTY_VALUE; - if (IsSpecifiedBullish(zgTrend)) - { - // - llIDX = GetLowest(lows); - hhIDX = GetHighest(lows); - - // - trendColor = clrAqua; - - // - toTime = lows[hhIDX].time; - toPrice = lows[hhIDX].value; - - // - fromTime = lows[llIDX].time; - fromPrice = lows[llIDX].value; - } - else - { - // - llIDX = GetLowest(highs); - hhIDX = GetHighest(highs); - - // - trendColor = clrMagenta; - - // - toTime = highs[llIDX].time; - toPrice = highs[llIDX].value; - - // - fromTime = highs[hhIDX].time; - fromPrice = highs[hhIDX].value; - } - - // - // Check Requirements for Trend ... - has = - NotEmptyZero(toPrice) && - NotEmptyZero(fromPrice) && - IsSpecifiedValid(toTime) && - IsSpecifiedValid(fromTime); - if (has) - { - // - has = fima2Signaller.poiDrawer.DrawTrendLine( - fromPrice, - fromTime, - toPrice, - toTime, - zgTrendLine, - zgTrendName, - true // Ray Right ... - ); - if (has) - { - zgTrendLine.Color(trendColor); - } - } - - // - // Cleanup Resources ... - tmpBar.Clean(); - } - - // - if (!has) - { - SpecifiedClean(pivots); - } - } - - // - // Cleanup Resources ... - SpecifiedClean(lows); - SpecifiedClean(highs); - } - - // - // Draw Pivots ... - has = HasChild(pivots); - if (has) - { - // - CArrayObj *drawnPivots = new CArrayObj(); - pivotsCount = fima2Signaller.poiDrawer.DrawPivots( - pivots, - drawnPivots // - ); - } - - // - // Cleanup Resources ... - SpecifiedClean(pivots); - } - - // - // Support ... - bool hasSupport = marketStructure.support.IsValid(); - if (hasSupport) - { - // - AddIfNotExists( - marketStructure.support, - supports // - ); - - // - XCBoxObject *iObj; - has = fima2Signaller.poiDrawer.DrawBox( - marketStructure.support, - iObj); - if (has) - { - } - } - - // - // Resistance ... - bool hasResistance = marketStructure.resistance.IsValid(); - if (hasResistance) - { - // - AddIfNotExists( - marketStructure.resistance, - resistances // - ); - - // - XCBoxObject *iObj; - has = fima2Signaller.poiDrawer.DrawBox( - marketStructure.resistance, - iObj); - if (has) - { - } - } - - // - // Check Bar Pattern Exists ... - has = hasPinnedBar || - hasEngulfedBar || - hasFlagPattern || - hasStarPattern || - hasSignalKeyBar || - hasRisingPattern || - hasPiercingPattern; - - // - // Select Pattern Direction and Price and Price Type ... - if (has) - { - // - if (hasPinnedBar) - { - // - iDir = marketStructure.pinnedDir; - iName = "pinned" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasEngulfedBar) - { - // - iDir = marketStructure.engulfedDir; - iName = "engulfed" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasFlagPattern) - { - // - iDir = marketStructure.flagPatternDir; - iName = "flagPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasStarPattern) - { - // - iDir = marketStructure.starPatternDir; - iName = "starPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasSignalKeyBar) - { - // - iDir = marketStructure.risingPatternDir; - iName = "risingPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasRisingPattern) - { - // - iDir = marketStructure.piercingPatternDir; - iName = "piercingPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasPiercingPattern) - { - // - iDir = marketStructure.signalKeyBarPatternDir; - iName = "signalKeyBarPattern" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time)); - } - - // - isBullish = IsSpecifiedBullish(iDir); - - // - // Retrieve Price Type for Validate ... - iPriceType = isBullish - ? X_PRICE_LOW - : X_PRICE_HIGH; - iPrice = bar.GetPrice(iPriceType); - - // - has = HasDirection(iDir); - } - - // - // Validate Patterns based on MA Band ... - if (has) - { - // - // Retrieve MA Band for Validation ... - double iMABandUpper = fima2Signaller.fimaHelper.GetMABandUpper(barIndex); - double iMABandLower = fima2Signaller.fimaHelper.GetMABandLower(barIndex); - - // - // Validate ... - has = isBullish - ? iPrice < iMABandLower - : iPrice > iMABandUpper; - } - - // - // Select a Zone which Price inside it ... - - // - // Validate Happens in Zone ... - int insideZoneIDX = -1; - has = has && - (isBullish - ? HasInside( - insideZoneIDX, - bar, - supports // - ) - : HasInside( - insideZoneIDX, - bar, - resistances // - )); - - // - // Validate Selected Inside Zone ... - // whith Bars Edge ... - has = IsValidIndex(insideZoneIDX); - if (has) - { - // - if (isBullish) - { - iZone = supports[insideZoneIDX]; - } - else - { - iZone = resistances[insideZoneIDX]; - } - - // - has = isBullish - ? bar.high > supports[insideZoneIDX].upper - : bar.low < resistances[insideZoneIDX].lower; - } - - // - // Checking Liquidities ... - - // - // Draw Selected and Validated Bar and Selected Zone ... - if (has) - { - // - int iWidth = 1; - int iCode = 159; - color iClr = isBullish - ? clrYellow - : clrDarkOrange; - ENUM_ARROW_ANCHOR iAnchor = isBullish - ? ANCHOR_TOP - : ANCHOR_BOTTOM; - - // - XCBoxObject *iZoneObj; - XCBarArrowObject *iPatternObj; - - // - has = fima2Signaller.poiDrawer.DrawBarArrow( - bar, - iPatternObj, - iPriceType, - iCode, - iClr, - iWidth, - iAnchor, - iName, - true, // Ignore Bar Tag ... - 10 // Threshold ... - ); - if (has) - { - } - - // - has = fima2Signaller.poiDrawer.DrawBox( - iZone, - iZoneObj, - true, // Ignore At ... - iZone.type // Name ... - ); - if (has) - { - // - XPOIStyle iStyle; - fima2Signaller.poiDrawer.GetBoxStyle( - iStyle, - iZone.dir // - ); - iStyle.width = 2; - iStyle.clr = iClr; - fima2Signaller.poiDrawer.ApplyBoxStyle( - iZoneObj, - iStyle // - ); - } - } - - // - // Preparing Signal ... - if (has) - { - // - iSignal.time = bar.time; - iSignal.provider = "XFima"; - iSignal.symbol = bar.symbol; - iSignal.period = bar.period; - iSignal.mode = X_ORDER_MODE_MARKET; - iSignal.entry = GetEntry(bar.symbol, iDir); - iSignal.type = isBullish - ? POSITION_TYPE_BUY - : POSITION_TYPE_SELL; - - // - iSignal.volume = 0.01; - - // - double _r2r = 2.0; - double _slDistanceInPoint = 5; - double _point = GetPoints(iSignal.symbol); - double _riskDistance = _slDistanceInPoint * _point; - double _risk = _riskDistance + MathAbs((isBullish ? iZone.lower : iZone.upper) - iSignal.entry); - double _reward = GetSpread(iSignal.symbol) + (_risk * _r2r); - - // - double sl = isBullish - ? iSignal.entry - _risk - : iSignal.entry + _risk; - double tp = isBullish - ? iSignal.entry + _reward - : iSignal.entry - _reward; - - // - iSignal.sl = sl; - iSignal.tp = tp; - - // - has = iSignal.IsValid(); - if (has) - { - // - XCSignalObject *iSignalObj; - has = fima2Signaller.poiDrawer.DrawSignal( - iSignal, - iSignalObj, - 7 // - ); - } - } - - // - // For Logging ... - if (has) - { - // - ENUM_X_SIGNAL_EXECUTION_RESULT eResult; - has = eaExpert.eaTrader.ExecuteSignal(iSignal, eResult); - Print("Detect a Potential Place for Price Movement: ", ToXString(iDir), ", Time: ", bar.time); - } - - // - // Cleanup Resources ... - iZone.Clean(); - iSignal.Clean(); - SpecifiedClean(supports); - SpecifiedClean(resistances); -} - -// -void HandleLookupSignal(XOHCL &bar) -{ - // - bool has = - bar.IsValid(); - if (!has) - { - return; - } - - // - XBoxZone iZone; - XSignal iSignal; - string iName = NULL; - bool isBullish = false; - bool isBearish = false; - int barIndex = bar.Index(); - double iPrice = EMPTY_VALUE; - XFIMAConditions fimaConditions; - ENUM_X_PRICE iPriceType = X_PRICE_NONE; - ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; - - // - int cIDX = 0; - int pIDX = cIDX + 1; - - // - // Check for a Cross ... - - // - // fima2Signaller.fimaHelper.Update(barIndex); - has = fima2Signaller.fimaHelper.GetConditions( - fimaConditions, - barIndex, - 5 // - ); - - // - double cSlowMA = fimaConditions.maSlowBuffer[cIDX]; - double pSlowMA = fimaConditions.maSlowBuffer[pIDX]; - - // - double cMAUpper = fimaConditions.maBandUpperBuffer[cIDX]; - double cMALower = fimaConditions.maBandLowerBuffer[cIDX]; - - // - double pMAUpper = fimaConditions.maBandUpperBuffer[pIDX]; - double pMALower = fimaConditions.maBandLowerBuffer[pIDX]; - - // - bool isCrossedOver = cSlowMA > cMALower && - pSlowMA < pMALower; - - // - bool isCrossedUnder = cSlowMA < cMAUpper && - cSlowMA > pMAUpper; - - // - has = isCrossedOver || - isCrossedUnder; - if (!has) - { - // - isBullish = false; - isBearish = false; - iDir = X_DIRECTION_NONE; - } - - // - if (has) - { - // - isBullish = isCrossedOver; - isBearish = isCrossedUnder; - } - - // - iDir = (isBullish && !isBearish) - ? X_DIRECTION_BULLISH - : (isBearish && !isBullish) - ? X_DIRECTION_BEARISH - : X_DIRECTION_NONE; - has = HasDirection(iDir); - if (has) - { - Print("Conditions Detected ..."); - } - - // - // Cleanup Resources ... - fimaConditions.Clean(); -} - // \ No newline at end of file diff --git a/Helpers/x-saherelm.xfima.helper.mq5 b/Helpers/x-saherelm.xfima.helper.mq5 index f9033b99..bbeddd4b 100644 --- a/Helpers/x-saherelm.xfima.helper.mq5 +++ b/Helpers/x-saherelm.xfima.helper.mq5 @@ -474,43 +474,6 @@ class XCXFIMAHelper : public XCBaseHelper // // Props ... - // - // Buffers ... - double maFastBuffer[]; - double maFastColorBuffer[]; - double maFastStateBuffer[]; - double maSlowBuffer[]; - double maSlowColorBuffer[]; - double maSlowStateBuffer[]; - double maBandUpperBuffer[]; - double maBandLowerBuffer[]; - double sarBuffer[]; - double sarColorBuffer[]; - double sarStateBuffer[]; - double peakBuffer[]; - double valeBuffer[]; - double fiboUpperBuffer[]; - double fiboMiddleBuffer[]; - double fiboLowerBuffer[]; - double zigzagBuffer[]; - double sHHBuffer[]; - double sLLBuffer[]; - double mHHBuffer[]; - double mLLBuffer[]; - double lHHBuffer[]; - double lLLBuffer[]; - double hHHBuffer[]; - double hLLBuffer[]; - double highsBuffer[]; - double highsTimeBuffer[]; - double lowsBuffer[]; - double lowsTimeBuffer[]; - double hkOpenBuffer[]; - double hkHighBuffer[]; - double hkLowBuffer[]; - double hkCloseBuffer[]; - double hkColorBuffer[]; - // // Constructors ... XCXFIMAHelper() @@ -549,42 +512,6 @@ class XCXFIMAHelper : public XCBaseHelper return result; } - // - ArraySetAsSeries(maFastBuffer, true); - ArraySetAsSeries(maFastColorBuffer, true); - ArraySetAsSeries(maFastStateBuffer, true); - ArraySetAsSeries(maSlowBuffer, true); - ArraySetAsSeries(maSlowColorBuffer, true); - ArraySetAsSeries(maSlowStateBuffer, true); - ArraySetAsSeries(maBandUpperBuffer, true); - ArraySetAsSeries(maBandLowerBuffer, true); - ArraySetAsSeries(sarBuffer, true); - ArraySetAsSeries(sarColorBuffer, true); - ArraySetAsSeries(sarStateBuffer, true); - ArraySetAsSeries(peakBuffer, true); - ArraySetAsSeries(valeBuffer, true); - ArraySetAsSeries(fiboUpperBuffer, true); - ArraySetAsSeries(fiboMiddleBuffer, true); - ArraySetAsSeries(fiboLowerBuffer, true); - ArraySetAsSeries(zigzagBuffer, false); // TODO: FIX This ... - ArraySetAsSeries(sHHBuffer, true); - ArraySetAsSeries(sLLBuffer, true); - ArraySetAsSeries(mHHBuffer, true); - ArraySetAsSeries(mLLBuffer, true); - ArraySetAsSeries(lHHBuffer, true); - ArraySetAsSeries(lLLBuffer, true); - ArraySetAsSeries(hHHBuffer, true); - ArraySetAsSeries(hLLBuffer, true); - ArraySetAsSeries(highsBuffer, true); - ArraySetAsSeries(highsTimeBuffer, true); - ArraySetAsSeries(lowsBuffer, true); - ArraySetAsSeries(lowsTimeBuffer, true); - ArraySetAsSeries(hkOpenBuffer, true); - ArraySetAsSeries(hkHighBuffer, true); - ArraySetAsSeries(hkLowBuffer, true); - ArraySetAsSeries(hkCloseBuffer, true); - ArraySetAsSeries(hkColorBuffer, true); - // mInputs = inputs; @@ -669,20 +596,6 @@ class XCXFIMAHelper : public XCBaseHelper // // Tools ... - // - void Update( - int barIndex // Bar Index - ) - { - Calculate(barIndex); - } - - // - void Free() override - { - Cleanup(10); - } - // bool GetConditions( XFIMAConditions &conditions, // @@ -972,17 +885,11 @@ class XCXFIMAHelper : public XCBaseHelper // double fast[]; + int fastCount = CopyMAFast(barIndex, 2, fast); + + // double slow[]; - double upper[]; - double lower[]; - int count = ReadMAValues( - fast, - slow, - upper, - lower, - barIndex, - 2 // - ); + int slowCount = CopyMASlow(barIndex, 2, slow); // bool isBullish = false; @@ -990,6 +897,7 @@ class XCXFIMAHelper : public XCBaseHelper // // Validate Readed Values ... + int count = MathMin(fastCount, slowCount); result = IsValidSize(count) && count >= 2; if (result) { @@ -1051,8 +959,6 @@ class XCXFIMAHelper : public XCBaseHelper // Cleanup Resources ... XClean(fast); XClean(slow); - XClean(upper); - XClean(lower); // return result; @@ -1083,18 +989,12 @@ class XCXFIMAHelper : public XCBaseHelper barIndex = NormalizeInt(barIndex, 0); // - double low[]; double open[]; - double high[]; + int openCount = CopyHKOpen(barIndex, 2, open); + + // double close[]; - int count = ReadHKBars( - open, - high, - low, - close, - barIndex, - 2 // - ); + int closeCount = CopyHKClose(barIndex, 2, close); // bool isBullish = false; @@ -1102,6 +1002,7 @@ class XCXFIMAHelper : public XCBaseHelper // // Validate Readed Values ... + int count = MathMin(openCount, closeCount); result = IsValidSize(count) && count >= 2; if (result) { @@ -1148,9 +1049,7 @@ class XCXFIMAHelper : public XCBaseHelper // // Cleanup Resources ... - XClean(low); XClean(open); - XClean(high); XClean(close); // @@ -1191,13 +1090,7 @@ class XCXFIMAHelper : public XCBaseHelper // double sars[]; - int count = CopyBuffer( - mHandler, - XFIMA_SAR_STATE_LINE, - barIndex, - 2, - sars // - ); + int count = CopySarState(barIndex, 2, sars); // bool isBullish = false; @@ -1604,8 +1497,6 @@ class XCXFIMAHelper : public XCBaseHelper double slow[]; XPivot iPivot; int count = 0; - double upper[]; - double lower[]; bool has = false; int idx = barIndex - 1; datetime iPivotTime = NULL; @@ -1629,11 +1520,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Prepare ... + XClean(fast); + XClean(slow); iPivot.Clean(); - SpecifiedClean(fast); - SpecifiedClean(slow); - SpecifiedClean(upper); - SpecifiedClean(lower); // // Ignore First Item ... @@ -1644,14 +1533,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Reading Buffer ... - count = ReadMAValues( - fast, - slow, - upper, - lower, - idx, - 2 // - ); + int fastCount = CopyMAFast(idx, 2, fast); + int slowCount = CopyMASlow(idx, 2, slow); + count = MathMin(fastCount, slowCount); has = IsValidSize(count); // @@ -1754,11 +1638,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Cleanup Resources ... + XClean(fast); + XClean(slow); iPivot.Clean(); - SpecifiedClean(fast); - SpecifiedClean(slow); - SpecifiedClean(upper); - SpecifiedClean(lower); // // Check Moving Forward Condition ... @@ -1776,11 +1658,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Cleanup Resources ... + XClean(fast); + XClean(slow); iPivot.Clean(); - SpecifiedClean(fast); - SpecifiedClean(slow); - SpecifiedClean(upper); - SpecifiedClean(lower); // return result; @@ -1824,11 +1704,9 @@ class XCXFIMAHelper : public XCBaseHelper } // - double low[]; double open[]; XPivot iPivot; int count = 0; - double high[]; double close[]; bool has = false; int idx = barIndex - 1; @@ -1849,11 +1727,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Prepare ... + XClean(open); + XClean(close); iPivot.Clean(); - SpecifiedClean(low); - SpecifiedClean(open); - SpecifiedClean(high); - SpecifiedClean(close); // // Ignore First Item ... @@ -1864,14 +1740,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Reading Buffer ... - count = ReadHKBars( - open, - high, - low, - close, - idx, - 2 // - ); + int openCount = CopyHKOpen(idx, 2, open); + int closeCount = CopyHKClose(idx, 2, close); + count = MathMin(openCount, closeCount); has = IsValidSize(count); // @@ -1962,11 +1833,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Cleanup Resources ... + XClean(open); + XClean(close); iPivot.Clean(); - SpecifiedClean(low); - SpecifiedClean(open); - SpecifiedClean(high); - SpecifiedClean(close); // // Check Moving Forward Condition ... @@ -1984,11 +1853,9 @@ class XCXFIMAHelper : public XCBaseHelper // // Cleanup Resources ... + XClean(open); + XClean(close); iPivot.Clean(); - SpecifiedClean(low); - SpecifiedClean(open); - SpecifiedClean(high); - SpecifiedClean(close); // return result; @@ -2440,17 +2307,17 @@ class XCXFIMAHelper : public XCBaseHelper // int count = 0; XBoxZone zone; - double hkLows[]; bool has = false; - double hkOpens[]; - double hkHighs[]; - double hkCloses[]; int start = barIndex; bool isBullish = false; bool isBearish = false; double up = EMPTY_VALUE; + double low = EMPTY_VALUE; + double open = EMPTY_VALUE; + double high = EMPTY_VALUE; double down = EMPTY_VALUE; double body = EMPTY_VALUE; + double close = EMPTY_VALUE; double range = EMPTY_VALUE; bool lowShadowPassed = false; bool highShadowPassed = false; @@ -2471,35 +2338,26 @@ class XCXFIMAHelper : public XCBaseHelper // // Reading HK Buffesr ... - count = ReadHKBars( - hkOpens, - hkHighs, - hkLows, - hkCloses, - i, - 1 // - ); - has = IsValidSize(count); - if (!has) - { - continue; - } + low = GetHKLow(i); + open = GetHKOpen(i); + high = GetHKHigh(i); + close = GetHKClose(i); // // Initialized Start Bar ... if (i == start) { // - startHKLow = hkLows[0]; - startHKOpen = hkOpens[0]; - startHKHigh = hkHighs[0]; - startHKClose = hkCloses[0]; + startHKLow = low; + startHKOpen = open; + startHKHigh = high; + startHKClose = close; } // // Check Direction ... - isBullish = hkOpens[0] < hkCloses[0]; - isBearish = hkOpens[0] > hkCloses[0]; + isBullish = open < close; + isBearish = open > close; dir = (isBullish && !isBearish) ? X_DIRECTION_BULLISH @@ -2515,15 +2373,15 @@ class XCXFIMAHelper : public XCBaseHelper // // Calculate Requirements for Processing ... up = isBullish - ? hkCloses[0] - : hkOpens[0]; + ? close + : open; down = isBullish - ? hkOpens[0] - : hkCloses[0]; + ? open + : close; body = MathAbs(up - down); - range = hkHighs[0] - hkLows[0]; - highShadow = hkHighs[0] - up; - lowShadow = down - hkLows[0]; + range = high - low; + highShadow = high - up; + lowShadow = down - low; // // Detecting Shadows ... @@ -2566,13 +2424,13 @@ class XCXFIMAHelper : public XCBaseHelper IsXBullish(zone.dir) ? down : IsXBearish(zone.dir) - ? hkHighs[0] + ? high : EMPTY_VALUE; // zone.lower = IsXBullish(zone.dir) - ? hkLows[0] + ? low : IsXBearish(zone.dir) ? up : EMPTY_VALUE; @@ -2622,10 +2480,6 @@ class XCXFIMAHelper : public XCBaseHelper // // Cleanup Resources ... zone.Clean(); - SpecifiedClean(hkLows); - SpecifiedClean(hkOpens); - SpecifiedClean(hkHighs); - SpecifiedClean(hkCloses); // return result; @@ -2643,46 +2497,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(maFastBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return maFastBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MA_FAST_LINE, + barIndex // + ); } // int CopyMAFast( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - maFastBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MA_FAST_LINE, + start, + count, + asSeries // ); } @@ -2695,46 +2530,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(maFastStateBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return maFastStateBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MA_FAST_STATE_LINE, + barIndex // + ); } // int CopyMAFastState( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - maFastStateBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MA_FAST_STATE_LINE, + start, + count, + asSeries // ); } @@ -2747,46 +2563,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(maSlowBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return maSlowBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MA_SLOW_LINE, + barIndex // + ); } // int CopyMASlow( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - maSlowBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MA_SLOW_LINE, + start, + count, + asSeries // ); } @@ -2799,46 +2596,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(maSlowStateBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return maSlowStateBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MA_SLOW_STATE_LINE, + barIndex // + ); } // int CopyMASlowState( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - maSlowStateBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MA_SLOW_STATE_LINE, + start, + count, + asSeries // ); } @@ -2851,46 +2629,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(maBandUpperBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return maBandUpperBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MA_BAND_UPPER_LINE, + barIndex // + ); } // int CopyMABandUpper( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - maBandUpperBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MA_BAND_UPPER_LINE, + start, + count, + asSeries // ); } @@ -2903,46 +2662,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(maBandLowerBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return maBandLowerBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MA_BAND_LOWER_LINE, + barIndex // + ); } // int CopyMABandLower( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - maBandLowerBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MA_BAND_LOWER_LINE, + start, + count, + asSeries // ); } @@ -2955,46 +2695,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(sarBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return sarBuffer[barIndex]; + return ReadValue( + (int)XFIMA_SAR_LINE, + barIndex // + ); } // int CopySar( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - sarBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_SAR_LINE, + start, + count, + asSeries // ); } @@ -3007,46 +2728,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(sarStateBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return sarStateBuffer[barIndex]; + return ReadValue( + (int)XFIMA_SAR_STATE_LINE, + barIndex // + ); } // int CopySarState( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - sarStateBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_SAR_STATE_LINE, + start, + count, + asSeries // ); } @@ -3059,46 +2761,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(peakBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return peakBuffer[barIndex]; + return ReadValue( + (int)XFIMA_PEAK_LINE, + barIndex // + ); } // int CopyPeak( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - peakBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_PEAK_LINE, + start, + count, + asSeries // ); } @@ -3111,46 +2794,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(valeBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return valeBuffer[barIndex]; + return ReadValue( + (int)XFIMA_VALE_LINE, + barIndex // + ); } // int CopyVale( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - valeBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_VALE_LINE, + start, + count, + asSeries // ); } @@ -3166,46 +2830,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(fiboUpperBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return fiboUpperBuffer[barIndex]; + return ReadValue( + (int)XFIMA_FIBO_UPPER_LINE, + barIndex // + ); } // int CopyFiboUpper( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - fiboUpperBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_FIBO_UPPER_LINE, + start, + count, + asSeries // ); } @@ -3218,46 +2863,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(fiboMiddleBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return fiboMiddleBuffer[barIndex]; + return ReadValue( + (int)XFIMA_FIBO_MIDDLE_LINE, + barIndex // + ); } // int CopyFiboMiddle( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - fiboMiddleBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_FIBO_MIDDLE_LINE, + start, + count, + asSeries // ); } @@ -3270,46 +2896,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(fiboLowerBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return fiboLowerBuffer[barIndex]; + return ReadValue( + (int)XFIMA_FIBO_LOWER_LINE, + barIndex // + ); } // int CopyFiboLower( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - fiboLowerBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_FIBO_LOWER_LINE, + start, + count, + asSeries // ); } @@ -3322,66 +2929,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - // Calculate(barIndex); - SpecifiedClean(zigzagBuffer); - - // - CopyBuffer( - mHandler, - XFIMA_ZIGZAG_LINE, - barIndex, - 1, - zigzagBuffer // + return ReadValue( + (int)XFIMA_ZIGZAG_LINE, + barIndex // ); - - // - int count = ArraySize(zigzagBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return zigzagBuffer[barIndex]; } // int CopyZigZag( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - // Calculate(start); - SpecifiedClean(zigzagBuffer); - - // - CopyBuffer( - mHandler, - XFIMA_ZIGZAG_LINE, - start, - 0, - zigzagBuffer // - ); - - // - // Copy Items ... - return Copy( - 0, - count, - zigzagBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_ZIGZAG_LINE, + start, + count, + asSeries // ); } @@ -3400,46 +2968,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(sHHBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return sHHBuffer[barIndex]; + return ReadValue( + (int)XFIMA_SC_HH_LINE, + barIndex // + ); } // int CopySHH( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - sHHBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_SC_HH_LINE, + start, + count, + asSeries // ); } @@ -3452,46 +3001,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(sLLBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return sLLBuffer[barIndex]; + return ReadValue( + (int)XFIMA_SC_LL_LINE, + barIndex // + ); } // int CopySLL( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - sLLBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_SC_LL_LINE, + start, + count, + asSeries // ); } @@ -3507,46 +3037,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(mHHBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return mHHBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MC_HH_LINE, + barIndex // + ); } // int CopyMHH( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - mHHBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MC_HH_LINE, + start, + count, + asSeries // ); } @@ -3559,46 +3070,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(mLLBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return mLLBuffer[barIndex]; + return ReadValue( + (int)XFIMA_MC_LL_LINE, + barIndex // + ); } // int CopyMLL( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - mLLBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_MC_LL_LINE, + start, + count, + asSeries // ); } @@ -3614,46 +3106,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(lHHBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return lHHBuffer[barIndex]; + return ReadValue( + (int)XFIMA_LC_HH_LINE, + barIndex // + ); } // int CopyLHH( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - lHHBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_LC_HH_LINE, + start, + count, + asSeries // ); } @@ -3666,46 +3139,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(lLLBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return lLLBuffer[barIndex]; + return ReadValue( + (int)XFIMA_LC_LL_LINE, + barIndex // + ); } // int CopyLLL( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - lLLBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_LC_LL_LINE, + start, + count, + asSeries // ); } @@ -3721,46 +3175,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(hHHBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return hHHBuffer[barIndex]; + return ReadValue( + (int)XFIMA_HC_HH_LINE, + barIndex // + ); } // int CopyHHH( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - hHHBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_HC_HH_LINE, + start, + count, + asSeries // ); } @@ -3773,46 +3208,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(hLLBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return hLLBuffer[barIndex]; + return ReadValue( + (int)XFIMA_HC_LL_LINE, + barIndex // + ); } // int CopyHLL( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - hLLBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_HC_LL_LINE, + start, + count, + asSeries // ); } @@ -3828,46 +3244,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(hkOpenBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return hkOpenBuffer[barIndex]; + return ReadValue( + (int)XFIMA_HK_OPEN_LINE, + barIndex // + ); } // int CopyHKOpen( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - hkOpenBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_HK_OPEN_LINE, + start, + count, + asSeries // ); } @@ -3880,46 +3277,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(hkHighBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return hkHighBuffer[barIndex]; + return ReadValue( + (int)XFIMA_HK_HIGH_LINE, + barIndex // + ); } // int CopyHKHigh( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - hkHighBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_HK_HIGH_LINE, + start, + count, + asSeries // ); } @@ -3932,46 +3310,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(hkLowBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return hkLowBuffer[barIndex]; + return ReadValue( + (int)XFIMA_HK_LOW_LINE, + barIndex // + ); } // int CopyHKLow( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - hkLowBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_HK_LOW_LINE, + start, + count, + asSeries // ); } @@ -3984,46 +3343,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(hkCloseBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return hkCloseBuffer[barIndex]; + return ReadValue( + (int)XFIMA_HK_CLOSE_LINE, + barIndex // + ); } // int CopyHKClose( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - hkCloseBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_HK_CLOSE_LINE, + start, + count, + asSeries // ); } @@ -4036,46 +3376,27 @@ class XCXFIMAHelper : public XCBaseHelper ) { // - if (barIndex < 0) - { - barIndex = 0; - } - - // - Calculate(barIndex); - - // - int count = ArraySize(hkColorBuffer); - if (barIndex >= count) - { - barIndex = count - 1; - } - - // - return hkColorBuffer[barIndex]; + return ReadValue( + (int)XFIMA_HK_COLOR_LINE, + barIndex // + ); } // int CopyHKColor( - int start, // Start - int count, // Number of Items for read - double &buffer[], // Dest Buffer - bool forceClean = true // Force To Clean buffer + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool asSeries = true // As Series Flag ) { // - // Update Calculations ... - Calculate(start); - - // - // Copy Items ... - return Copy( - 0, - count, - hkColorBuffer, + return ReadValues( buffer, - forceClean - // + (int)XFIMA_HK_COLOR_LINE, + start, + count, + asSeries // ); } @@ -4089,631 +3410,9 @@ class XCXFIMAHelper : public XCBaseHelper // Props ... XFIMAInputs mInputs; // Inputs ... - // - // Buffers ... - // Define in Public ... - - // - void Calculate( - int barIndex = 0, - int maxRequiredBars = 100 // - ) - { - // - // Buffers ... - if (barIndex < 0) - { - barIndex = 0; - } - - // - CopyBuffer( - mHandler, - XFIMA_MA_FAST_LINE, - barIndex, - maxRequiredBars, - maFastBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_FAST_COLOR_LINE, - barIndex, - maxRequiredBars, - maFastColorBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_FAST_STATE_LINE, - barIndex, - maxRequiredBars, - maFastStateBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_SLOW_LINE, - barIndex, - maxRequiredBars, - maSlowBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_SLOW_COLOR_LINE, - barIndex, - maxRequiredBars, - maSlowColorBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_SLOW_STATE_LINE, - barIndex, - maxRequiredBars, - maSlowStateBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_BAND_UPPER_LINE, - barIndex, - maxRequiredBars, - maBandUpperBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_BAND_LOWER_LINE, - barIndex, - maxRequiredBars, - maBandLowerBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_SAR_LINE, - barIndex, - maxRequiredBars, - sarBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_SAR_COLOR_LINE, - barIndex, - maxRequiredBars, - sarColorBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_SAR_STATE_LINE, - barIndex, - maxRequiredBars, - sarStateBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_PEAK_LINE, - barIndex, - maxRequiredBars, - peakBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_VALE_LINE, - barIndex, - maxRequiredBars, - valeBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_FIBO_UPPER_LINE, - barIndex, - maxRequiredBars, - fiboUpperBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_FIBO_MIDDLE_LINE, - barIndex, - maxRequiredBars, - fiboMiddleBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_FIBO_LOWER_LINE, - barIndex, - maxRequiredBars, - fiboLowerBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_ZIGZAG_LINE, - barIndex, - maxRequiredBars, - zigzagBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_SC_HH_LINE, - barIndex, - maxRequiredBars, - sHHBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_SC_LL_LINE, - barIndex, - maxRequiredBars, - sLLBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MC_HH_LINE, - barIndex, - maxRequiredBars, - mHHBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MC_LL_LINE, - barIndex, - maxRequiredBars, - mLLBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_LC_HH_LINE, - barIndex, - maxRequiredBars, - lHHBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_LC_LL_LINE, - barIndex, - maxRequiredBars, - lLLBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_HC_HH_LINE, - barIndex, - maxRequiredBars, - hHHBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_HC_LL_LINE, - barIndex, - maxRequiredBars, - hLLBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_ZIGZAG_HIGHS_LINE, - barIndex, - maxRequiredBars, - highsBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_ZIGZAG_HIGHS_TIME_LINE, - barIndex, - maxRequiredBars, - highsTimeBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_ZIGZAG_LOWS_LINE, - barIndex, - maxRequiredBars, - lowsBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_ZIGZAG_LOWS_TIME_LINE, - barIndex, - maxRequiredBars, - lowsTimeBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_HK_OPEN_LINE, - barIndex, - maxRequiredBars, - hkOpenBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_HK_HIGH_LINE, - barIndex, - maxRequiredBars, - hkHighBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_HK_LOW_LINE, - barIndex, - maxRequiredBars, - hkLowBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_HK_CLOSE_LINE, - barIndex, - maxRequiredBars, - hkCloseBuffer // - ); - - // - CopyBuffer( - mHandler, - XFIMA_HK_COLOR_LINE, - barIndex, - maxRequiredBars, - hkColorBuffer // - ); - } - - // - void Cleanup( - int maxAllowed = 100 // - ) - { - // - CleanupArray( - maFastBuffer, - maxAllowed // - ); - - // - CleanupArray( - maFastColorBuffer, - maxAllowed // - ); - - // - CleanupArray( - maFastStateBuffer, - maxAllowed // - ); - - // - CleanupArray( - maSlowBuffer, - maxAllowed // - ); - - // - CleanupArray( - maSlowColorBuffer, - maxAllowed // - ); - - // - CleanupArray( - maSlowStateBuffer, - maxAllowed // - ); - - // - CleanupArray( - maBandUpperBuffer, - maxAllowed // - ); - - // - CleanupArray( - maBandLowerBuffer, - maxAllowed // - ); - - // - CleanupArray( - sarBuffer, - maxAllowed // - ); - - // - CleanupArray( - sarColorBuffer, - maxAllowed // - ); - - // - CleanupArray( - sarStateBuffer, - maxAllowed // - ); - - // - CleanupArray( - peakBuffer, - maxAllowed // - ); - - // - CleanupArray( - valeBuffer, - maxAllowed // - ); - - // - CleanupArray( - fiboUpperBuffer, - maxAllowed // - ); - - // - CleanupArray( - fiboMiddleBuffer, - maxAllowed // - ); - - // - CleanupArray( - fiboLowerBuffer, - maxAllowed // - ); - - // - CleanupArray( - zigzagBuffer, - maxAllowed // - ); - - // - CleanupArray( - sHHBuffer, - maxAllowed // - ); - - // - CleanupArray( - sLLBuffer, - maxAllowed // - ); - - // - CleanupArray( - mHHBuffer, - maxAllowed // - ); - - // - CleanupArray( - mLLBuffer, - maxAllowed // - ); - - // - CleanupArray( - lHHBuffer, - maxAllowed // - ); - - // - CleanupArray( - lLLBuffer, - maxAllowed // - ); - - // - CleanupArray( - hHHBuffer, - maxAllowed // - ); - - // - CleanupArray( - hLLBuffer, - maxAllowed // - ); - - // - CleanupArray( - highsBuffer, - maxAllowed // - ); - - // - CleanupArray( - highsTimeBuffer, - maxAllowed // - ); - - // - CleanupArray( - lowsBuffer, - maxAllowed // - ); - - // - CleanupArray( - lowsTimeBuffer, - maxAllowed // - ); - - // - CleanupArray( - hkOpenBuffer, - maxAllowed // - ); - - // - CleanupArray( - hkHighBuffer, - maxAllowed // - ); - - // - CleanupArray( - hkLowBuffer, - maxAllowed // - ); - - // - CleanupArray( - hkCloseBuffer, - maxAllowed // - ); - - // - CleanupArray( - hkColorBuffer, - maxAllowed // - ); - } - // // XHK Helper ... - // - int ReadHKBars( - double &open[], - double &high[], - double &low[], - double &close[], - int barIndex = 0, - int count = 1 // - ) - { - // - int result = 0; - - // - // Prepare ... - SpecifiedClean(low); - SpecifiedClean(open); - SpecifiedClean(high); - SpecifiedClean(close); - - // - // Normalize ... - count = NormalizeInt(count, 1); - barIndex = NormalizeInt(barIndex, 0); - - // - // Validate ... - if (mHandler == INVALID_HANDLE) - { - return result; - } - - // - // Open ... - CopyBuffer( - mHandler, - XFIMA_HK_OPEN_LINE, - barIndex, - count, - open // - ); - - // - // High ... - CopyBuffer( - mHandler, - XFIMA_HK_HIGH_LINE, - barIndex, - count, - high // - ); - - // - // Low ... - CopyBuffer( - mHandler, - XFIMA_HK_LOW_LINE, - barIndex, - count, - low // - ); - - // - // Close ... - CopyBuffer( - mHandler, - XFIMA_HK_CLOSE_LINE, - barIndex, - count, - close // - ); - - // - ArraySetAsSeries(low, true); - ArraySetAsSeries(open, true); - ArraySetAsSeries(high, true); - ArraySetAsSeries(close, true); - - // - // Min Number of Array Sizes ... - result = MathMin(ArraySize(open), ArraySize(high)); - result = MathMin(result, ArraySize(close)); - result = MathMin(result, ArraySize(low)); - - // - return result; - } - /** * Validate HK Zone ... * @@ -4749,13 +3448,13 @@ class XCXFIMAHelper : public XCBaseHelper // // Requirements ... - double low[]; - double open[]; - double high[]; - int count = 0; - double close[]; + double low = EMPTY_VALUE; + double open = EMPTY_VALUE; + double high = EMPTY_VALUE; + double close = EMPTY_VALUE; // + int count = 0; int start = zone.FromIndex() + 1; int end = start + validationLength; @@ -4765,15 +3464,11 @@ class XCXFIMAHelper : public XCBaseHelper { // // Reading HK ... - count = ReadHKBars( - open, - high, - low, - close, - i, - 1 // - ); - result = IsValidSize(count); + low = GetHKLow(i); + high = GetHKHigh(i); + result = + NotEmptyZero(low) && + NotEmptyZero(high); if (!result) { break; @@ -4781,8 +3476,8 @@ class XCXFIMAHelper : public XCBaseHelper // result = zone.IsBullish() - ? low[0] > zone.lower - : high[0] < zone.upper; + ? low > zone.lower + : high < zone.upper; if (!result) { break; @@ -4800,16 +3495,12 @@ class XCXFIMAHelper : public XCBaseHelper for (int i = start; i < end; i++) { // - // Reading HK ... - count = ReadHKBars( - open, - high, - low, - close, - i, - 1 // - ); - result = IsValidSize(count); + // Read HK ... + low = GetHKLow(i); + high = GetHKHigh(i); + result = + NotEmptyZero(low) && + NotEmptyZero(high); if (!result) { break; @@ -4817,8 +3508,8 @@ class XCXFIMAHelper : public XCBaseHelper // result = zone.IsBullish() - ? low[0] > zone.lower - : high[0] < zone.upper; + ? low > zone.lower + : high < zone.upper; if (!result) { // @@ -4834,15 +3525,8 @@ class XCXFIMAHelper : public XCBaseHelper { // // Reading HK ... - count = ReadHKBars( - open, - high, - low, - close, - j, - 1 // - ); - result = IsValidSize(count); + close = GetHKClose(j); + result = NotEmptyZero(close); if (!result) { break; @@ -4850,8 +3534,8 @@ class XCXFIMAHelper : public XCBaseHelper // result = zone.IsBullish() - ? close[0] > zone.upper - : close[0] < zone.lower; + ? close > zone.upper + : close < zone.lower; if (result) { // @@ -4876,93 +3560,6 @@ class XCXFIMAHelper : public XCBaseHelper // // Cleanup Resource ... - SpecifiedClean(low); - SpecifiedClean(open); - SpecifiedClean(high); - SpecifiedClean(close); - - // - return result; - } - - // - int ReadMAValues( - double &fast[], - double &slow[], - double &upper[], - double &lower[], - int barIndex = 0, - int count = 0 // - ) - { - // - int result = 0; - - // - // Prepare ... - SpecifiedClean(fast); - SpecifiedClean(slow); - SpecifiedClean(upper); - SpecifiedClean(lower); - - // - // Normalize ... - count = NormalizeInt(count, 1); - barIndex = NormalizeInt(barIndex, 0); - - // - // Validate ... - if (mHandler == INVALID_HANDLE) - { - return result; - } - - // - CopyBuffer( - mHandler, - XFIMA_MA_FAST_LINE, - barIndex, - count, - fast // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_SLOW_LINE, - barIndex, - count, - slow // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_BAND_UPPER_LINE, - barIndex, - count, - upper // - ); - - // - CopyBuffer( - mHandler, - XFIMA_MA_BAND_LOWER_LINE, - barIndex, - count, - lower // - ); - - // - ArraySetAsSeries(fast, true); - ArraySetAsSeries(slow, true); - ArraySetAsSeries(upper, true); - ArraySetAsSeries(lower, true); - - // - result = MathMin(ArraySize(fast), ArraySize(slow)); - result = MathMin(result, ArraySize(upper)); - result = MathMin(result, ArraySize(lower)); // return result; diff --git a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 index 05aac1b2..91a09cf7 100644 --- a/Libraries/x-saherelm.x-poi.extensions.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.extensions.lib.mq5 @@ -3493,6 +3493,66 @@ bool AddIfNotExists( } //+------------------------------------------------------------------+ +//+------------------------------------------------------------------+ +//| Extract | +//+------------------------------------------------------------------+ + +/** + * Extract Specified Directional Items ... + * + * @param dest: reference collection to holds extracted items ... + * @param source: reference collection to provides data source ... + * @param forDir: Specified which direction to Extract items ... + * + * @return ( int ) + */ +template +int ExtractByDirection( + T &dest[], + T &source[], + ENUM_X_DIRECTION forDir // +) +{ + // + int result = 0; + + // + // Prepare ... + XClean(dest); + + // + // Validate ... + bool has = HasChild(source) && + HasDirection(forDir); + if (!has) + { + return result; + } + + // + int count = ArraySize(source); + for (int i = 0; i < count; i++) + { + // + has = source[i].dir == forDir; + if (has) + { + // + AddIfNotExists( + source[i], + dest // + ); + } + } + + // + result = ArraySize(dest); + + // + return result; +} +//+------------------------------------------------------------------+ + // // // @@ -4255,11 +4315,11 @@ bool IsInside( /** * Check a Bar is Inside a Zone or not ... - * + * * @param index: int, reference to holds detected index ... * @param bar: reference to Specified Bar ... * @param source: reference collection to provide source ... - * + * * @return ( bool ) */ bool HasInside( @@ -4307,11 +4367,11 @@ bool HasInside( /** * Extract all Items which Specified Bar is inside them ... - * + * * @param bar: reference to Specified Bar ... * @param dest: reference to result ... * @param source: reference collection to provide source ... - * + * * @return ( int ) */ int ExtractInsides( diff --git a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 index 57b37511..3782844f 100644 --- a/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 +++ b/XFIMAEA/Classes/x-saherelm.xfima.signaller.class.mq5 @@ -219,6 +219,220 @@ class XCXFIMABaseSignaller : public XCBaseSignaller protected: // + // + // Protected Actions ... + + /** + * Check Specified Bar has Pattern or not ... + * + * @param bar: XOHCL, reference to Specified Bar ... + * @param name: string, reference to holds Detected Patterns Name ... + * @param dir: ENUM_X_DIRECTION, reference to holds Detected Patterns Direction ... + * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... + * + * @return ( bool ) + */ + bool HasPattern( + XOHCL &bar, + string &patternName, + ENUM_X_DIRECTION &patternDir, + XFIMAMarketStructure &structure // + ) + { + // + bool result = false; + + // + // Prepare ... + patternName = NULL; + patternDir = X_DIRECTION_NONE; + + // + // Validate ... + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + // Check Required Pattern Exists ... + bool hasPinnedBar = HasDirection(structure.pinnedDir); + bool hasEngulfedBar = HasDirection(structure.engulfedDir); + bool hasFlagPattern = HasDirection(structure.flagPatternDir); + bool hasStarPattern = HasDirection(structure.starPatternDir); + bool hasRisingPattern = HasDirection(structure.risingPatternDir); + bool hasPiercingPattern = HasDirection(structure.piercingPatternDir); + bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir); + + // + // Check Bar Pattern Exists ... + // and Select Pattern Direction and Price and Price Type ... + result = hasPinnedBar || + hasEngulfedBar || + hasFlagPattern || + hasStarPattern || + hasSignalKeyBar || + hasRisingPattern || + hasPiercingPattern; + + // + if (result) + { + // + if (hasPinnedBar) + { + // + patternDir = structure.pinnedDir; + patternName = "XPinned_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasEngulfedBar) + { + // + patternDir = structure.engulfedDir; + patternName = "XEngulfed_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasFlagPattern) + { + // + patternDir = structure.flagPatternDir; + patternName = "XFlag_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasStarPattern) + { + // + patternDir = structure.starPatternDir; + patternName = "XStar_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasSignalKeyBar) + { + // + patternDir = structure.risingPatternDir; + patternName = "XRising_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasRisingPattern) + { + // + patternDir = structure.piercingPatternDir; + patternName = "XPiercing_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + else if (hasPiercingPattern) + { + // + patternDir = structure.signalKeyBarPatternDir; + patternName = "XSignalKey_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); + } + } + + // + result = + result && + IsXValid(patternName) && + HasDirection(patternDir); + + // + return result; + } + + /** + * Validate a Pattern based on MA Band ... + * + * @param bar: XOHCL, reference to Pattern Bar ... + * @param patternName: string, detected pattern's name ... + * @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ... + * @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... + * + * @return ( bool ) + */ + bool ValidatePatternBasedOnMABand( + XOHCL &bar, + string patternName, + ENUM_X_DIRECTION patternDir, + XFIMAConditions &fimaConditions // + ) + { + // + bool result = false; + + // + // Validate ... + result = bar.IsValid() && + IsXValid(patternName) && + HasDirection(patternDir); + if (!result) + { + return result; + } + + // + // Define Requirements ... + bool isBullish = false; + bool isBearish = false; + double iPrice = EMPTY_VALUE; + double iPriceEdge = EMPTY_VALUE; + ENUM_X_PRICE iPriceType = X_PRICE_NONE; + ENUM_X_PRICE iPriceEdgeType = X_PRICE_NONE; + + // + // Calculating Price and Price Types ... + + // + isBullish = IsXBullish(patternDir); + isBearish = IsXBearish(patternDir); + + // + iPriceType = isBullish + ? X_PRICE_DOWN + : X_PRICE_UP; + + // + iPriceEdgeType = isBullish + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + iPrice = bar.GetPrice(iPriceType); + iPriceEdge = bar.GetPrice(iPriceEdgeType); + + // + // Validate ... + result = + NotEmptyZero(iPrice) && + IsXValid(iPriceType) && + NotEmptyZero(iPriceEdge) && + IsXValid(iPriceEdgeType) && + ((isBullish && !isBearish) || + (isBearish && !isBullish)); + if (!result) + { + return result; + } + + // + // Validate Pattern based on MA Band ... + + // + // Retrieve MA Band for Validation ... + double iMABandUpper = fimaConditions.maBandUpperBuffer[0]; + double iMABandLower = fimaConditions.maBandLowerBuffer[0]; + + // + // Validate by Edge Price ... + result = + NotEmptyZero(iMABandUpper) && + NotEmptyZero(iMABandLower) && + (isBullish + ? iPriceEdge < iMABandLower + : iPriceEdge > iMABandUpper); + if (!result) + { + return result; + } + + // + return result; + } + // // Private ... private: @@ -226,7 +440,7 @@ class XCXFIMABaseSignaller : public XCBaseSignaller }; // -// XFIMA Strategy 1 Signaller Class ... +// XFIMA Strategy 2 Signaller Class ... class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller { // @@ -234,7 +448,7 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller public: // // Props ... - int fvgLookupLenght; // Maximum Lenght for Looking up FVG before Crosses + XFIMAPatternDetectorConfig analyserConfig; // // Constructor ... @@ -255,317 +469,6 @@ class XCXFIMAStrategy1Signaller : public XCXFIMABaseSignaller _defaultSignalRiskInPoint, _defaultSignalVolume // ) - { - // - fvgLookupLenght = 5; - } - - // - // Overrides ... - - /** - * Processing Tick ... - * - * @param barIndex: int, Specified Bar Index ... - */ - virtual void ProcessTick(int barIndex = 0) - { - } - - /** - * Processing New Bar ... - * - * @param barIndex: int, Specified Bar Index ... - */ - virtual void ProcessNewBar(int barIndex = 0) - { - // - // Normalize ... - barIndex = NormalizeInt(barIndex, 0); - - // - // Update Helper ... - fimaHelper.Update(barIndex); - - // - XOHCL bar; - XSignal signal; - bool has = false; - int cIdx = barIndex + 1; - int pIdx = cIdx + 1; - ENUM_X_DIRECTION signalDir = X_DIRECTION_NONE; - - // - // Initialize Bar as CBar ... - has = bar.Init( - symbol, - period, - cIdx // - ); - if (!has) - { - // - bar.Clean(); - return; - } - - // - // Retrieve Conditions ... - XFIMAConditions fimaConditions; - has = fimaHelper.GetConditions( - fimaConditions, - barIndex, - 10 // Loopback ... - ); - if (!has) - { - // - bar.Clean(); - fimaConditions.Clean(); - - // - return; - } - - // - // Analyse Conditions for Finding Signal ... - - // - // TODO: Remove this ... - - // - bool isFastCrossedOverSlow = - fimaConditions.maFastBuffer[cIdx] > fimaConditions.maSlowBuffer[cIdx] && - fimaConditions.maFastBuffer[pIdx] < fimaConditions.maSlowBuffer[pIdx]; - - // - bool isFastCrossedUnderSlow = - fimaConditions.maFastBuffer[cIdx] < fimaConditions.maSlowBuffer[cIdx] && - fimaConditions.maFastBuffer[pIdx] > fimaConditions.maSlowBuffer[pIdx]; - - // - has = - isFastCrossedOverSlow || - isFastCrossedUnderSlow; - if (has) - { - // - // Do Conditions Validating ... - // TODO: Igmore All Validations for Testing Purposes ... - - // - // Validate MA Positions ... - double iFastMa = fimaConditions.maFastBuffer[cIdx]; - double iSlowMa = fimaConditions.maSlowBuffer[cIdx]; - double iFiboUpper = fimaConditions.fiboUpperBuffer[cIdx]; - double iFiboLower = fimaConditions.fiboLowerBuffer[cIdx]; - - // - // Checking Has FVG ... - XBoxZone fvg; - ENUM_X_DIRECTION fvgDir; - bool hasFVG = patternDetector.HasFVG( - bar, - fvgDir, - fvg, - fvgLookupLenght // - ); - - // - // Checking Crossed On Shadow ... - - // - bool isCrossedOverHappensOnShadow = - isFastCrossedOverSlow && - iFastMa <= bar.GetDown() && - iFastMa >= bar.low; - - // - bool isCrossedUnderHappensOnShadow = - isFastCrossedUnderSlow && - iFastMa <= bar.high && - iFastMa >= bar.GetUp(); - - // - // Bullish Validation ... - bool isBullish = - // - // Has Cross ... - isFastCrossedOverSlow - // - // && - // // - // // Cross Places Based on Fibo ... - // MathMax(iFastMa, iSlowMa) < iFiboLower - // // - // && - // // - // ( - // // - // // Checking FVG ... - // (hasFVG && - // fvg.IsBullish()) - // // - // || - // // - // // Checking Crossed Place ... - // isCrossedOverHappensOnShadow - // // - // ) - // // - ; - - // - // Bearish Validation ... - bool isBearish = - // - // Has Cross ... - isFastCrossedUnderSlow - // - // && - // // - // // Cross Places Based on Fibo ... - // MathMin(iFastMa, iSlowMa) > iFiboUpper - // // - // && - // // - // ( - // // - // // Checking FVG ... - // (hasFVG && - // fvg.IsBearish()) - // // - // || - // // - // // Checking Crossed Place ... - // isCrossedUnderHappensOnShadow - // // - // ) - // // - ; - - // - has = - (isBullish && !isBearish) || - (isBearish && !isBullish); - if (has) - { - // - signalDir = - isBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - } - } - - // - // Check Signal Founded ... - has = HasDirection(signalDir); - if (has) - { - // - // Prepare Founded Signal ... - XTarget targets[]; - has = PrepareSignal( - signal, - signalDir, - targets // - ); - if (has) - { - // - // Notify On Signal Event ... - NotifySignalEventListeners(signal); - } - } - - // - // Cleanup Resources ... - bar.Clean(); - signal.Clean(); - fimaConditions.Clean(); - } - - /** - * Check Guards Based on MarketConditions ... - * - * @param guards: XGuard[] - * @param barIndex: int - * - * @return ( int ) - */ - int virtual CheckForGuard( - XGuard &guards[], - int barIndex = 0 // - ) - { - // - int result = 0; - - // - SpecifiedClean(guards); - - // - result = ArraySize(guards); - - // - return result; - } - - // - // Private ... - private: - // - // Props ... - - // - // Lookup FVG ... - bool LookupFVG( - XOHCL &bar, - ENUM_X_DIRECTION &dir, - XBoxZone &fvgBox // - ) - { - // - bool result = false; - - // - return result; - } - - // -}; - -// -// XFIMA Strategy 2 Signaller Class ... -class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller -{ - // - // Public ... - public: - // - // Props ... - XFIMAPatternDetectorConfig analyserConfig; - - // - // Constructor ... - XCXFIMAStrategy2Signaller( - string _symbol, // Symbol ... - ENUM_TIMEFRAMES _period, // Period ... - XFIMAInputs &_fimaInputs, // XFIMAInputs ... - bool _processAllTicks = false, // Process All Ticks ... - double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ... - double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ... - double _defaultSignalVolume = 0.01 // Default Signal Volume ... - ) : XCXFIMABaseSignaller("XFIMA2", - _symbol, - _period, - _fimaInputs, - _processAllTicks, - _defaultSignalR2R, - _defaultSignalRiskInPoint, - _defaultSignalVolume // - ) { // // Configure Detector ... @@ -579,7 +482,7 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller // // Deconstructor ... - ~XCXFIMAStrategy2Signaller() + ~XCXFIMAStrategy1Signaller() { // Destroy(); @@ -611,10 +514,6 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller // Normalize ... barIndex = NormalizeInt(barIndex, 0); - // - // Update Helper ... - fimaHelper.Update(barIndex); - // XOHCL iBar; int count = 0; @@ -1160,6 +1059,9 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller ); } + // + // Collect Bar Support and Resistance (s) ... + // // Disable Signallers ... has = false; @@ -1274,217 +1176,6 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller // // Implementing Strategies ... - /** - * Check Specified Bar has Pattern or not ... - * - * @param bar: XOHCL, reference to Specified Bar ... - * @param name: string, reference to holds Detected Patterns Name ... - * @param dir: ENUM_X_DIRECTION, reference to holds Detected Patterns Direction ... - * @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ... - * - * @return ( bool ) - */ - bool HasPattern( - XOHCL &bar, - string &patternName, - ENUM_X_DIRECTION &patternDir, - XFIMAMarketStructure &structure // - ) - { - // - bool result = false; - - // - // Prepare ... - patternName = NULL; - patternDir = X_DIRECTION_NONE; - - // - // Validate ... - result = bar.IsValid(); - if (!result) - { - return result; - } - - // - // Check Required Pattern Exists ... - bool hasPinnedBar = HasDirection(structure.pinnedDir); - bool hasEngulfedBar = HasDirection(structure.engulfedDir); - bool hasFlagPattern = HasDirection(structure.flagPatternDir); - bool hasStarPattern = HasDirection(structure.starPatternDir); - bool hasRisingPattern = HasDirection(structure.risingPatternDir); - bool hasPiercingPattern = HasDirection(structure.piercingPatternDir); - bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir); - - // - // Check Bar Pattern Exists ... - // and Select Pattern Direction and Price and Price Type ... - result = hasPinnedBar || - hasEngulfedBar || - hasFlagPattern || - hasStarPattern || - hasSignalKeyBar || - hasRisingPattern || - hasPiercingPattern; - - // - if (result) - { - // - if (hasPinnedBar) - { - // - patternDir = structure.pinnedDir; - patternName = "XPinned_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasEngulfedBar) - { - // - patternDir = structure.engulfedDir; - patternName = "XEngulfed_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasFlagPattern) - { - // - patternDir = structure.flagPatternDir; - patternName = "XFlag_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasStarPattern) - { - // - patternDir = structure.starPatternDir; - patternName = "XStar_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasSignalKeyBar) - { - // - patternDir = structure.risingPatternDir; - patternName = "XRising_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasRisingPattern) - { - // - patternDir = structure.piercingPatternDir; - patternName = "XPiercing_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); - } - else if (hasPiercingPattern) - { - // - patternDir = structure.signalKeyBarPatternDir; - patternName = "XSignalKey_" + ToXString(patternDir) + ToXString(TimeToSeconds(bar.time)); - } - } - - // - result = - result && - IsXValid(patternName) && - HasDirection(patternDir); - - // - return result; - } - - /** - * Validate a Pattern based on MA Band ... - * - * @param bar: XOHCL, reference to Pattern Bar ... - * @param patternName: string, detected pattern's name ... - * @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ... - * @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ... - * - * @return ( bool ) - */ - bool ValidatePatternBasedOnMABand( - XOHCL &bar, - string patternName, - ENUM_X_DIRECTION patternDir, - XFIMAConditions &fimaConditions // - ) - { - // - bool result = false; - - // - // Validate ... - result = bar.IsValid() && - IsXValid(patternName) && - HasDirection(patternDir); - if (!result) - { - return result; - } - - // - // Define Requirements ... - bool isBullish = false; - bool isBearish = false; - double iPrice = EMPTY_VALUE; - double iPriceEdge = EMPTY_VALUE; - ENUM_X_PRICE iPriceType = X_PRICE_NONE; - ENUM_X_PRICE iPriceEdgeType = X_PRICE_NONE; - - // - // Calculating Price and Price Types ... - - // - isBullish = IsXBullish(patternDir); - isBearish = IsXBearish(patternDir); - - // - iPriceType = isBullish - ? X_PRICE_DOWN - : X_PRICE_UP; - - // - iPriceEdgeType = isBullish - ? X_PRICE_LOW - : X_PRICE_HIGH; - - // - iPrice = bar.GetPrice(iPriceType); - iPriceEdge = bar.GetPrice(iPriceEdgeType); - - // - // Validate ... - result = - NotEmptyZero(iPrice) && - IsXValid(iPriceType) && - NotEmptyZero(iPriceEdge) && - IsXValid(iPriceEdgeType) && - ((isBullish && !isBearish) || - (isBearish && !isBullish)); - if (!result) - { - return result; - } - - // - // Validate Pattern based on MA Band ... - - // - // Retrieve MA Band for Validation ... - double iMABandUpper = fimaConditions.maBandUpperBuffer[0]; - double iMABandLower = fimaConditions.maBandLowerBuffer[0]; - - // - // Validate by Edge Price ... - result = - NotEmptyZero(iMABandUpper) && - NotEmptyZero(iMABandLower) && - (isBullish - ? iPriceEdge < iMABandLower - : iPriceEdge > iMABandUpper); - if (!result) - { - return result; - } - - // - return result; - } - /** * Check Bar Has Signal Based on Strategy 1 ... * @@ -1659,27 +1350,95 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller // Detect Specified MA Cross ... result = HasDirection(structure.maCrossDir); + // + // Collecting Bar Support and Resistances ... + XBoxZone barZones[]; + int count = fimaHelper.ExtractBarZones( + barZones, + bar.Index(), + analyserConfig.recentlyPatternsMaxAllowedCollecting, // Number of Zones ... + analyserConfig.supportAndResistanceBreakeValidationLength, // Break Validation Length ... + analyserConfig.supportAndResistanceBreakeValidationLength > 0, // Validate Fake Breaked Zones ... + 4, // Shadow Multiplier ... + analyserConfig.minAllowdSupportAndResistanceStrength, // Validation Strength ... + 7, // Validation Length ... + analyserConfig.supportAndResistanceMaxAllowedLoopback // Max Allowed Loopback ... + ); + Copy( + supports, + barZones, + false // Force Clean ... + ); + Copy( + resistances, + barZones, + false // Force Clean ... + ); + // // Validate Conditions ... + XBoxZone fvg; + ENUM_X_DIRECTION tmpDir; + bool hasFVG = poiDetector.HasFVG( + bar, + tmpDir, + fvg, + 3 // Max Loopback ... + ); + + // + // Validate result by FVG ... + // result = + // result && + // hasFVG && + // fvg.dir == structure.maCrossDir; + + // + if (result) + { + // + XCBoxObject *iFVGObj; + poiDrawer.DrawBox( + fvg, + iFVGObj // + ); + + // + // Draw Support or Resistances based on Direction of Cross ... + CArrayObj *iZones; + count = poiDrawer.DrawBoxes( + barZones, + iZones // + ); + + // + Print("Cross Happens ..."); + } // // Prepare iZone ... - iZone.to = bar.time; - iZone.from = GetBarTime( - bar.symbol, - bar.period, - bar.Index() + 2 // - ); - iZone.symbol = bar.symbol; - iZone.period = bar.period; - iZone.dir = structure.maCrossDir; - iZone.lower = bar.FindLowest(2, MODE_LOW); - iZone.upper = bar.FindHighest(2, MODE_HIGH); - iZone.type = name + "_" + ToXString(structure.maCrossDir); + if (result) + { + // + iZone.to = bar.time; + iZone.from = GetBarTime( + bar.symbol, + bar.period, + bar.Index() + 2 // + ); + iZone.symbol = bar.symbol; + iZone.period = bar.period; + iZone.dir = structure.maCrossDir; + iZone.lower = bar.FindLowest(2, MODE_LOW); + iZone.upper = bar.FindHighest(2, MODE_HIGH); + iZone.type = name + "_" + ToXString(structure.maCrossDir); + + // + result = iZone.IsValid(); + } // // Check Result ... - result = iZone.IsValid(); if (result) { iDir = structure.maCrossDir; @@ -1691,6 +1450,10 @@ class XCXFIMAStrategy2Signaller : public XCXFIMABaseSignaller { iZone.Clean(); } + + // + fvg.Clean(); + XClean(barZones); // return result;