diff --git a/Documents/BKP/x-121.poi.expert.class.mq5 b/Documents/BKP/x-121.poi.expert.class.mq5 new file mode 100644 index 00000000..ffb094a2 --- /dev/null +++ b/Documents/BKP/x-121.poi.expert.class.mq5 @@ -0,0 +1,830 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XC121SMCExpert +// Description: provides all based classes for use ... +// +// +// 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-expert.class.mq5" +#include "../../Classes/x-saherelm.x-poi.class.mq5" +// #include "../Classes/x-121.smc.xtradehandler.class.mq5" + +// +// Definitions ... +string XC121SMCExpertToken = "XC121SMCEA"; + +// +// Implementation ... + +class XC121SMCExpert : public XCBaseExpert +{ + // + public: + // + + // + // Signal Event Listener ... + TOnStopLoss OnPositionSLEventListener; + TOnTakeProfit OnPositionTPEventListener; + TOnPartialClose OnPositionPartialCloseEventListener; + TOnModify OnPositionModifiedEventListener; + TOnForceClose OnPositionForceCloseEventListener; + + // + // Getter(s) / Setter(s) ... + + /** + * Get Use Dynamic Volume State ... + * + * @return ( bool ) + */ + bool UseDynamicVolume() + { + return mUseDynamicVolume; + } + + /** + * Set Use Dynamic Volume State ... + * + * @param value: Boolean ... + */ + void UseDynamicVolume(bool value) + { + mUseDynamicVolume = value; + } + + /** + * Get Increase Volume Step ... + * + * @return ( double ) + */ + double DynamicVolumeStep() + { + return mDynamicVolumeStep; + } + + /** + * Set Increase Volume Step ... + * + * @param value: Double ... + */ + void DynamicVolumeStep(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mDynamicVolumeStep = value; + } + + /** + * Get Balance Factor for Generate Dynamic Volume ... + * + * @return ( double ) + */ + double DynamicVolumeBalanceFactor() + { + return mDynamicVolumeBalanceFactor; + } + + /** + * Set Balance Factor for Generate Dynamic Volume ... + * + * @param value: Double ... + */ + void DynamicVolumeBalanceFactor(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mDynamicVolumeBalanceFactor = value; + } + + /** + * Get Static Volume ... + * + * @return ( double ) + */ + double Volume() + { + return mVolume; + } + + /** + * Set Static Volume ... + * + * @param value: Double ... + */ + void Volume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mVolume = value; + } + + // + // Actions ... + + // + // Override Actions ... + + /** + * Apply Default Configurations ... + */ + void DefaultConfigure() override + { + // + // Commons ... + Slippage(10); + TagPrefix(""); + MagicNumber(1694056); + + // + // Symbol ... + SetSymbol(_Symbol); + SetPeriod(_Period); + MultiSymbol(false); + Symbols("EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb"); + + // + // Signalling ... + Disabled(false); + AllowLong(true); + AllowShort(true); + + // + string tag = GetTag(); + + // + // Alert ... + SetAlertPrefix(tag); + SetAlertLogAlerts(true); + SetAlertPushAlerts(true); + SetAlertMailAlerts(false); + SetAlertEnableAlerts(true); + SetAlertTerminalAlerts(false); + + // + // Reports ... + ReportNewDays(true); + ReportNewWeeks(false); + ReportNewHours(false); + ReportNewMonths(false); + + // + // Volume Default Configurations ... + Volume(0.01); + UseDynamicVolume(false); + DynamicVolumeStep(0.01); + DynamicVolumeBalanceFactor(200); + } + + /** + * Vaslidate Inputs ... + * + * @return ( bool ) + */ + bool ValidateInputs() override + { + // + bool result = false; + + // + string errMessage = ""; + + // + bool isCommonValid = ( + // + Slippage() > 0 && + MagicNumber() > 0 + // + ); + if (!isCommonValid) + { + // + errMessage += "common configurations error;" + "\n"; + } + + // + // Checking Volume ... + bool isVolumeValid = true; + if (UseDynamicVolume()) + { + // + isVolumeValid = + DynamicVolumeStep() > 0 && + DynamicVolumeBalanceFactor() > 0; + if (!isVolumeValid) + { + errMessage += "Dynamic Volume configurations error;" + "\n"; + } + } + isVolumeValid = isVolumeValid && + Volume() > 0; + if (!isVolumeValid) + { + errMessage += "Static Volume configurations error;" + "\n"; + } + + // + result = + // + // Common ... + isCommonValid && + // + // Volume Coniguration ... + isVolumeValid && + // + // Otere ... + true + // + ; + + // + if (!result) + { + // + // Since here Logger not Initiallized, we Use Raw Print Command ... + errMessage = " Errors: \n" + errMessage; + Alert(errMessage); + } + + // + return result; + } + + // + // Initializers and DeInitializers ... + + /** + * Initial EA Requirements ... + * + * @return ( bool ) + */ + bool InitEA() override + { + // + bool result = false; + + // + // Initialize Indicator Helpers ... + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + mPOIDetector = new XCPOIDetector( + symbol, + period // + ); + mPOIDetector.Init(); + + // + // Bar Timer ... + XCTInputs ctInputs; + ctInputs.Default(); // Default Configurations ... + mCTHelper = new XCXCTHelper(); + result = mCTHelper.Init( + GetSymbol(), + GetPeriod(), + ctInputs // + ); + if (!result) + { + return result; + } + + // + // Bar Styles ... + XCCInputs ccInputs; + ccInputs.Default(); // Default Configurations ... + mCCHelper = new XCXCCHelper(); + result = mCCHelper.Init( + GetSymbol(), + GetPeriod(), + ccInputs // + ); + if (!result) + { + return result; + } + + // + // Create Trader Instance and Configure it ... + mTrader = new XCTrade( + Slippage(), + MagicNumber() // + ); + mTrader.AddOnStopLossEventHandler(OnPositionSLEventListener); + mTrader.AddOnTakeProfitEventHandler(OnPositionTPEventListener); + mTrader.AddOnModifyPositionEventHandler(OnPositionModifiedEventListener); + mTrader.AddOnForceClosePositionEventHandler(OnPositionForceCloseEventListener); + mTrader.AddOnPartialClosePositionEventHandler(OnPositionPartialCloseEventListener); + + // // + // // Initialize Trade Handler ... + // mTradeHandler = new XC121SMCTradeHandler(mTrader); + // mTradeHandler.SaveTrades(true); + // mTradeHandler.SaveSignals(true); + // mTradeHandler.SaveConditions(true); + + // // + // // Configure Alerts ... + // mTradeHandler.SetAlertPrefix(GetTag()); + // mTradeHandler.SetAlertEnableAlerts(GetAlertEnableAlerts()); + // mTradeHandler.SetAlertLogAlerts(GetAlertLogAlerts()); + // mTradeHandler.SetAlertMailAlerts(GetAlertMailAlerts()); + // mTradeHandler.SetAlertPushAlerts(GetAlertPushAlerts()); + // mTradeHandler.SetAlertTerminalAlerts(GetAlertTerminalAlerts()); + + // // + // // TODO: Make This Configurable Later ... + + // // + // mTradeHandler.DelayBarBetweenTwoSignal(3); + // mTradeHandler.MaxAllowedSLToPause(0); + // mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24)); + + // // + // // Configure Trade Management ... + // mTradeHandler.AllowLong(AllowLong()); + // mTradeHandler.AllowShort(AllowShort()); + // mTradeHandler.MaxAllowedLongs(0); + // mTradeHandler.MaxAllowedShorts(0); + // mTradeHandler.UseMaxAllowedTradesPerSymbol(true); + // mTradeHandler.MaxDrawdownPercentForOpenTrades(5); + + // // + // // Configure Position Protector ... + + // // + // mTradeHandler.UseForceMomentumsInProtection(true); + // mTradeHandler.DelayBarBetweenTwoSignal(2); + + // // + // // Configure Hedging ... + // mTradeHandler.AllowHedge(false); + // mTradeHandler.HedgeMinVolumeStep(0.01); + // mTradeHandler.MinimumOpenPositionsForHEHedge(2); + // mTradeHandler.HedgeHEMinProfitPerVolumeStep(0.2); + // mTradeHandler.HedgeBEMinProfitPerVolumeStep(0.06); + + // // + // // In Profit Position Protecting ... + + // // + // // Trail ... + // mTradeHandler.AllowTrail(false); + // mTradeHandler.TrailStep(15); + // mTradeHandler.TrailStartDistance(30); + // mTradeHandler.OnlyTrailUnprotected(true); + // mTradeHandler.RemoveTPAfterTrailedLevel(4); + + // // + // // Partial Close (In Profit) ... + // mTradeHandler.PartialCloseInProfitDistance(0); + // mTradeHandler.PartialCloseInProfitVolume(0); + + // // + // // In Drawdown Positions Protecting ... + + // // + // // Protect ... + // mTradeHandler.AllowProtect(false); + // mTradeHandler.ProtectionDelay(20); + // mTradeHandler.MaxAllowedProtection(0); + // mTradeHandler.UseEntryAsProtectionSL(true); + // mTradeHandler.ProtectOnConditions(true); + // mTradeHandler.AllowDirectionProtct(false); + // mTradeHandler.ProtectionStartDistance(50); + // mTradeHandler.ProtectionVolumeMultiplier(2); + + // // + // // Partial Close (In Profit) ... + // mTradeHandler.PartialCloseInDrawdownDistance(0); + // mTradeHandler.PartialCloseInDrawdownVolume(0); + + // + // Parsers ... + XSymbolParser _symbolParser; + + // + // Single Symbol ... + if (!MultiSymbol()) + { + // + // Register Strategy ... + + // + // Create Class Instance ... + // XCX121SMCBaseStrategy *iX121SMCStrategy; + // iX121SMCStrategy = new XCX121SMCTestStrategy( + // _Symbol, + // _Period // + // ); + + // // + // iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener); + + // // + // ConfigureStrategy(iX121SMCStrategy); + // RegisterStrategy(iX121SMCStrategy); + } + // + // Multi Symbol ... + else + { + // + // Parse Symbols ... + string symbols[]; + int symbolsCount = SplitContent( + symbols, + Symbols() // + ); + result = IsValidSize(symbolsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < symbolsCount; i++) + { + // + // Select Symbol ... + string iSymbol = symbols[i]; + + // + // Register Strategy Based On Symbol ... + + // + // Parse Symbol ... + bool isEURUSD = _symbolParser.IsEURUSD(_Symbol); + bool isGBPUSD = _symbolParser.IsGBPUSD(_Symbol); + bool isEURGBP = _symbolParser.IsEURGBP(_Symbol); + bool isUSDCHF = _symbolParser.IsUSDCHF(_Symbol); + bool isEURCHF = _symbolParser.IsEURCHF(_Symbol); + bool isUSDJPY = _symbolParser.IsUSDJPY(_Symbol); + bool isEURJPY = _symbolParser.IsEURJPY(_Symbol); + bool isUSDCAD = _symbolParser.IsUSDCAD(_Symbol); + bool isEURCAD = _symbolParser.IsEURCAD(_Symbol); + bool isAUDUSD = _symbolParser.IsAUDUSD(_Symbol); + bool isEURAUD = _symbolParser.IsEURAUD(_Symbol); + bool isNZDUSD = _symbolParser.IsNZDUSD(_Symbol); + bool isEURNZD = _symbolParser.IsEURNZD(_Symbol); + + // + // Check Symbol Can Register or not ... + bool canRegisterStrategy = true; + + // + if (canRegisterStrategy) + { + // // + // // Create Class Instance ... + // XCX121SMCBaseStrategy *iX121SMCStrategy; + // iX121SMCStrategy = new XCX121SMCTestStrategy( + // iSymbol, + // _Period // + // ); + + // // + // iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener); + + // // + // // Register Strategy ... + // ConfigureStrategy(iX121SMCStrategy); + // RegisterStrategy(iX121SMCStrategy); + } + } + } + + // + return result; + } + + /** + * Destroy all Initialized EA Requirements ... + */ + void DestroyEA() override + { + // + delete mCTHelper; + delete mCCHelper; + // delete mTradeHandler; + + // + // Clean(mStrategies); + } + + /** + * Call all Registered Strategies On Tick ... + */ + void HandleStrategiesOnTick() override + { + // + ENUM_XPOI_EVENTS events[]; + mPOIDetector.Update(events); + + // + // int count = ArraySize(mStrategies); + // if (!IsValidSize(count)) + // { + // return; + // } + + // // + // for (int i = 0; i < count; i++) + // { + // // + // // Call Tick Handler Function ... + // mStrategies[i].HandleTick(); + // } + } + + // + // Event Handlers ... + + /** + * Calls When a Position's SL Triggered ... + * + * @param deal: XDeal instance ... + */ + void HandleOnStopLossTriggered(const XDeal &deal) override + { + // + // Finish ... + // mTradeHandler.Finish(deal); + + // + HandleReportBalance(); + } + + /** + * Calls When a Position's TP Triggered ... + * + * @param deal: XDeal instance ... + */ + void HandleOnTakeProfitTriggered(const XDeal &deal) override + { + // + // Finish ... + // mTradeHandler.Finish(deal); + + // + HandleReportBalance(); + } + + /** + * Handle Force Close a Position ... + * + * @param ticket: Position Ticket ... + * @param position: XPosition ... + * @param comment: Closing Comment ... + */ + void HandleOnPositionForceClosed( + const ulong ticket, + const XPosition &position, + const string comment // + ) override + { + // + // Finish ... + // mTradeHandler.Finish( + // ticket, + // position, + // comment // + // ); + + // + HandleReportBalance(); + } + + /** + * Reset All Paused Symbols on Each New Days ... + */ + void HandleOnNewDay() override + { + // mTradeHandler.ResumePausedSymbols(); + } + + /** + * Generate Identifier Tag ... + * + * @return ( string ) + */ + string GetTag() override + { + // + string result = NULL; + + // + string tagPrefix = TagPrefix(); + if (IsValid(tagPrefix)) + { + result = tagPrefix; + } + else + { + result = ""; + } + + // + result = + XCBaseExpertToken + result; + + // + return result; + } + + // + protected: + // + + // + // Props ... + + // + datetime mLastSignalOn; + + // + XCPOIDetector *mPOIDetector; + + // + // XC121SMCTradeHandler *mTradeHandler; // Trade Handler ... + // XCX121SMCBaseStrategy *mStrategies[]; // Registere Strategies in EA ... + + // + // Actions ... + + /** + * Apply Volume Based On Configurations on Signal ... + * + * @param signal: XSignal instance + */ + void ApplyVolumeOnSignal(XSignal &signal) + { + // + // Prepare Signal Dynamic Volume + // if Provided ... + if (UseDynamicVolume() && + DynamicVolumeStep() > 0 && + DynamicVolumeBalanceFactor() > 0) + { + // + double dVolume = mTrader.GetDynamicVolume( + signal.symbol, + DynamicVolumeBalanceFactor(), + DynamicVolumeStep() // + ); + + // + if (dVolume > 0) + { + signal.volume = dVolume; + } + else + { + signal.volume = Volume(); + } + } + else + { + signal.volume = Volume(); + } + + // + // mTradeHandler.UpdateSignal(signal); + } + + /** + * Configure Startegy ... + */ + // void ConfigureStrategy(XCX121SMCBaseStrategy *&strategy) + // { + // // + // if (strategy == NULL) + // { + // return; + // } + + // // + // // Configure Alerts ... + // strategy.SetAlertPrefix(GetTag()); + // strategy.SetAlertLogAlerts(GetAlertLogAlerts()); + // strategy.SetAlertMailAlerts(GetAlertMailAlerts()); + // strategy.SetAlertPushAlerts(GetAlertPushAlerts()); + // strategy.SetAlertEnableAlerts(GetAlertEnableAlerts()); + // strategy.SetAlertTerminalAlerts(GetAlertTerminalAlerts()); + + // // + // // Confiugre Signalling ... + + // // + // strategy.R2R(2); + // strategy.AllowLong(AllowLong()); + // strategy.AllowShort(AllowShort()); + + // // + // if (Disabled()) + // { + // strategy.Disable(); + // } + // else + // { + // strategy.Enable(); + // } + + // // + // } + + /** + * Register an Strategy in EA ... + * + * @param strategy: XCX121SMCBaseStrategy instance ... + */ + // void RegisterStrategy(XCX121SMCBaseStrategy *strategy) + // { + // // + // if (strategy == NULL) + // { + // return; + // } + + // // + // ArrayResize( + // mStrategies, + // ArraySize(mStrategies) + 1 // + // ); + + // // + // mStrategies[ArraySize(mStrategies) - 1] = strategy; + // } + + /** + * Re Configure All Registered Strategies ... + */ + // void ReConfigureAllStrategies() + // { + // // + // int count = ArraySize(mStrategies); + // if (!IsValidSize(count)) + // { + // return; + // } + + // // + // for (int i = 0; i < count; i++) + // { + // // + // ConfigureStrategy(mStrategies[i]); + // } + // } + + // + private: + // + + // + // Props ... + + // + // Volume Management ... + bool mUseDynamicVolume; // Use Dynamic Volume ... + double mDynamicVolumeStep; // Increase Volume Step ... + double mDynamicVolumeBalanceFactor; // Balance Factor for Generate Dynamic Volume ... + double mVolume; // Static Volume ... + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.expert.class.mq5 b/Documents/BKP/x-121.smc.expert.class.mq5 new file mode 100644 index 00000000..d20f5815 --- /dev/null +++ b/Documents/BKP/x-121.smc.expert.class.mq5 @@ -0,0 +1,1113 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XC121SMCExpert +// Description: provides all based classes for use ... +// +// +// 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-expert.class.mq5" +#include "../Classes/x-121.smc.x-tradehandler.class.mq5" +#include "../Libraries/x-121.smc.lib.mq5" +#include "../Strategy/x-121.smc.test.strategy.class.mq5" + +// +// Definitions ... +string XC121SMCExpertToken = "XC121SMCEA"; + +// +// Implementation ... + +class XC121SMCExpert : public XCBaseExpert +{ + // + public: + // + + // + // Signal Event Listener ... + TOnStopLoss OnPositionSLEventListener; + TOnTakeProfit OnPositionTPEventListener; + TOnPartialClose OnPositionPartialCloseEventListener; + TOnModify OnPositionModifiedEventListener; + TOnForceClose OnPositionForceCloseEventListener; + + // + TOnX121SMCSignal OnSignalEventListener; + + // + // Getter(s) / Setter(s) ... + + /** + * Get Risk to Reward Ratio ... + * + * @return ( double ) + */ + double R2R() + { + return mR2R; + } + + /** + * Set Risk to Reward Ratio ... + * + * @param value: Double ... + */ + void R2R(double value) + { + // + if (value < 1) + { + value = 1; + } + + // + mR2R = value; + ReConfigureAllStrategies(); + } + + /** + * Get Use Dynamic Volume State ... + * + * @return ( bool ) + */ + bool UseDynamicVolume() + { + return mUseDynamicVolume; + } + + /** + * Set Use Dynamic Volume State ... + * + * @param value: Boolean ... + */ + void UseDynamicVolume(bool value) + { + mUseDynamicVolume = value; + } + + /** + * Get Increase Volume Step ... + * + * @return ( double ) + */ + double DynamicVolumeStep() + { + return mDynamicVolumeStep; + } + + /** + * Set Increase Volume Step ... + * + * @param value: Double ... + */ + void DynamicVolumeStep(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mDynamicVolumeStep = value; + } + + /** + * Get Balance Factor for Generate Dynamic Volume ... + * + * @return ( double ) + */ + double DynamicVolumeBalanceFactor() + { + return mDynamicVolumeBalanceFactor; + } + + /** + * Set Balance Factor for Generate Dynamic Volume ... + * + * @param value: Double ... + */ + void DynamicVolumeBalanceFactor(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mDynamicVolumeBalanceFactor = value; + } + + /** + * Get Risk Percent Per Balance in Each Trade ... + * + * @return ( double ) + */ + double RiskPercentPerBalance() + { + return mRiskPercentPerBalance; + } + + /** + * Set Risk Percent Per Balance in Each Trade ... + * + * @param value: Double + */ + void RiskPercentPerBalance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mRiskPercentPerBalance = value; + } + + /** + * Get Dynamic Risk Management State ... + * + * @return ( bool ) + */ + bool DynamicRiskManagement() + { + return mDynamicRiskManagement; + } + + /** + * Set Dynamic Risk Management State ... + * + * @param value: Boolean ... + */ + void DynamicRiskManagement(bool value) + { + mDynamicRiskManagement = value; + } + + /** + * Get Static Volume ... + * + * @return ( double ) + */ + double Volume() + { + return mVolume; + } + + /** + * Set Static Volume ... + * + * @param value: Double ... + */ + void Volume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mVolume = value; + } + + // + // Actions ... + + /** + * Handle OnSignalRecieved Event ... + * + * @param signal: XSignal instance ... + * @param conditions: X121SMCStrategyConditions instance ... + */ + void HandleOnSignalRecieved( + XSignal &signal, + X121SMCStrategyConditions &conditions // + ) + { + // + // Check Signal and Conditions Validations ... + + // + if (!signal.IsValid()) + { + return; + } + + // + if (!conditions.IsValid()) + { + return; + } + + // + bool isLong = IsLong(signal.type); + + // + // Notify When a Raw (Unfiltered) Signal Recieved + // if it's Provided ... + bool mAlertRawSignals = false; + if (mAlertRawSignals) + { + // + string msg = "Raw " + (IsLong(signal.type) ? "Long" : "Short") + " Signal Recieved: (" + signal.provider + "," + signal.symbol + "," + ToString(signal.period) + ") ..."; + Alert(msg); + } + + // + // Apply Volume On Signal ... + ApplyVolumeOnSignal(signal); + + // + // Chekc Signalling Enable or not ... + bool canContinue = + isLong + ? AllowLong() + : AllowShort(); + if (!canContinue) + { + return; + } + + // + // TODO: Apply Filtering On Signal ... + bool isFiltered = false; + if (isFiltered) + { + // + mTradeHandler.RemoveSignal(signal); + return; + } + + // + // Attach Conditions Summary to Signal ... + string conditionsSummary = conditions.GenerateSummary( + false, + false, + true, + false // + ); + + // + // TODO: Retrieve Conditions Summary based on Filter ... + signal.conditions = conditionsSummary; + + // + datetime currentTime = TimeCurrent(); + + // + // Check Signal Protections ... + bool canTrail = false; + ENUM_X_121_SMC_PROVIDERS signalProvider = ParseProvider(signal.provider); + if (IsValid(signalProvider)) + { + // + // Complete this in Force States ... + // canTrail = true; + } + + // + // Execute Signal Using Trade Handler ... + ENUM_X_SIGNAL_EXECUTION_RESULT state; + bool isExecuted = mTradeHandler.ExecuteSignal( + signal, + state, + false, // ignore Policies ... + // + // Force Protections ... + canTrail // + ); + + // + if (isExecuted) + { + mLastSignalOn = currentTime; + } + } + + // + // Override Actions ... + + /** + * Apply Default Configurations ... + */ + void DefaultConfigure() override + { + // + // Commons ... + Slippage(10); + TagPrefix(""); + MagicNumber(1694056); + + // + // Symbol ... + SetSymbol(_Symbol); + SetPeriod(_Period); + MultiSymbol(false); + Symbols("EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb"); + + // + // Signalling ... + Disabled(false); + AllowLong(true); + AllowShort(true); + + // + string tag = GetTag(); + + // + // Alert ... + SetAlertPrefix(tag); + SetAlertLogAlerts(true); + SetAlertPushAlerts(true); + SetAlertMailAlerts(false); + SetAlertEnableAlerts(true); + SetAlertTerminalAlerts(false); + + // + // Reports ... + ReportNewDays(true); + ReportNewWeeks(false); + ReportNewHours(false); + ReportNewMonths(false); + + // + R2R(1); + + // + // Volume Default Configurations ... + Volume(0.01); + UseDynamicVolume(false); + DynamicVolumeStep(0.01); + DynamicVolumeBalanceFactor(200); + + // + RiskPercentPerBalance(0); + DynamicRiskManagement(false); + } + + /** + * Vaslidate Inputs ... + * + * @return ( bool ) + */ + bool ValidateInputs() override + { + // + bool result = false; + + // + string errMessage = ""; + + // + bool isCommonValid = ( + // + Slippage() > 0 && + MagicNumber() > 0 + // + ); + if (!isCommonValid) + { + // + errMessage += "common configurations error;" + "\n"; + } + + // + // Checking Volume ... + bool isVolumeValid = true; + if (UseDynamicVolume()) + { + // + isVolumeValid = + DynamicVolumeStep() > 0 && + DynamicVolumeBalanceFactor() > 0; + if (!isVolumeValid) + { + errMessage += "Dynamic Volume configurations error;" + "\n"; + } + } + isVolumeValid = isVolumeValid && + Volume() > 0; + if (!isVolumeValid) + { + errMessage += "Static Volume configurations error;" + "\n"; + } + + // + result = + // + // Common ... + isCommonValid && + // + // Volume Coniguration ... + isVolumeValid && + // + // Otere ... + true + // + ; + + // + if (!result) + { + // + // Since here Logger not Initiallized, we Use Raw Print Command ... + errMessage = " Errors: \n" + errMessage; + Alert(errMessage); + } + + // + return result; + } + + // + // Initializers and DeInitializers ... + + /** + * Initial EA Requirements ... + * + * @return ( bool ) + */ + bool InitEA() override + { + // + bool result = false; + + // + // Initialize Indicator Helpers ... + + // + // Bar Timer ... + XCTInputs ctInputs; + ctInputs.Default(); // Default Configurations ... + mCTHelper = new XCXCTHelper(); + result = mCTHelper.Init( + GetSymbol(), + GetPeriod(), + ctInputs // + ); + if (!result) + { + return result; + } + + // + // Bar Styles ... + XCCInputs ccInputs; + ccInputs.Default(); // Default Configurations ... + mCCHelper = new XCXCCHelper(); + result = mCCHelper.Init( + GetSymbol(), + GetPeriod(), + ccInputs // + ); + if (!result) + { + return result; + } + + // + // Configure Alerts ... + SetAlertPrefix(GetTag()); + SetAlertEnableAlerts(GetAlertEnableAlerts()); + SetAlertLogAlerts(GetAlertLogAlerts()); + SetAlertMailAlerts(GetAlertMailAlerts()); + SetAlertPushAlerts(GetAlertPushAlerts()); + SetAlertTerminalAlerts(GetAlertTerminalAlerts()); + + // + // Create Trader Instance and Configure it ... + mTrader = new XCTrade( + Slippage(), + MagicNumber() // + ); + mTrader.AddOnStopLossEventHandler(OnPositionSLEventListener); + mTrader.AddOnTakeProfitEventHandler(OnPositionTPEventListener); + mTrader.AddOnModifyPositionEventHandler(OnPositionModifiedEventListener); + mTrader.AddOnForceClosePositionEventHandler(OnPositionForceCloseEventListener); + mTrader.AddOnPartialClosePositionEventHandler(OnPositionPartialCloseEventListener); + + // + // Initialize Trade Handler ... + mTradeHandler = new XC121SMCTradeHandler(mTrader); + mTradeHandler.SaveTrades(true); + mTradeHandler.SaveSignals(true); + mTradeHandler.SaveConditions(true); + + // + // Configure Alerts ... + mTradeHandler.SetAlertPrefix(GetTag()); + mTradeHandler.SetAlertEnableAlerts(GetAlertEnableAlerts()); + mTradeHandler.SetAlertLogAlerts(GetAlertLogAlerts()); + mTradeHandler.SetAlertMailAlerts(GetAlertMailAlerts()); + mTradeHandler.SetAlertPushAlerts(GetAlertPushAlerts()); + mTradeHandler.SetAlertTerminalAlerts(GetAlertTerminalAlerts()); + + // + // TODO: Make This Configurable Later ... + + // + mTradeHandler.MaxAllowedSLToPause(0); + mTradeHandler.DelayBarBetweenTwoSignal(3); + mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24)); + + // + // Configure Trade Management ... + mTradeHandler.AllowLong(AllowLong()); + mTradeHandler.AllowShort(AllowShort()); + mTradeHandler.MaxAllowedLongs(0); + mTradeHandler.MaxAllowedShorts(0); + mTradeHandler.UseMaxAllowedTradesPerSymbol(true); + mTradeHandler.MaxDrawdownPercentForOpenTrades(5); + + // + // Configure Position Protector ... + + // + mTradeHandler.UseForceMomentumsInProtection(true); + mTradeHandler.DelayBarBetweenTwoSignal(2); + + // + // Configure Hedging ... + mTradeHandler.AllowHedge(false); + mTradeHandler.HedgeMinVolumeStep(0.01); + mTradeHandler.MinimumOpenPositionsForHEHedge(2); + mTradeHandler.HedgeHEMinProfitPerVolumeStep(0.2); + mTradeHandler.HedgeBEMinProfitPerVolumeStep(0.06); + + // + // In Profit Position Protecting ... + + // + // Trail ... + mTradeHandler.AllowTrail(false); + mTradeHandler.TrailStep(15); + mTradeHandler.TrailStartDistance(30); + mTradeHandler.OnlyTrailUnprotected(true); + mTradeHandler.RemoveTPAfterTrailedLevel(3); + + // + // Partial Close (In Profit) ... + mTradeHandler.PartialCloseInProfitDistance(0); + mTradeHandler.PartialCloseInProfitVolume(0); + + // + // In Drawdown Positions Protecting ... + + // + // Protect ... + mTradeHandler.AllowProtect(false); + mTradeHandler.ProtectionDelay(20); + mTradeHandler.MaxAllowedProtection(0); + mTradeHandler.UseEntryAsProtectionSL(true); + mTradeHandler.ProtectOnConditions(true); + mTradeHandler.AllowDirectionProtct(false); + mTradeHandler.ProtectionStartDistance(50); + mTradeHandler.ProtectionVolumeMultiplier(2); + + // + // Partial Close (In Profit) ... + mTradeHandler.PartialCloseInDrawdownDistance(0); + mTradeHandler.PartialCloseInDrawdownVolume(0); + + // + // Parsers ... + XSymbolParser _symbolParser; + + // + // Single Symbol ... + if (!MultiSymbol()) + { + // + // Register Strategy ... + + // + // Create Class Instance ... + XCX121SMCBaseStrategy *iX121SMCStrategy; + iX121SMCStrategy = new XCX121SMCTestStrategy( + _Symbol, + _Period // + ); + + // + iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener); + + // + ConfigureStrategy(iX121SMCStrategy); + RegisterStrategy(iX121SMCStrategy); + } + // + // Multi Symbol ... + else + { + // + // Parse Symbols ... + string symbols[]; + int symbolsCount = SplitContent( + symbols, + Symbols() // + ); + result = IsValidSize(symbolsCount); + if (!result) + { + return result; + } + + // + for (int i = 0; i < symbolsCount; i++) + { + // + // Select Symbol ... + string iSymbol = symbols[i]; + + // + // Register Strategy Based On Symbol ... + + // + // Parse Symbol ... + bool isEURUSD = _symbolParser.IsEURUSD(_Symbol); + bool isGBPUSD = _symbolParser.IsGBPUSD(_Symbol); + bool isEURGBP = _symbolParser.IsEURGBP(_Symbol); + bool isUSDCHF = _symbolParser.IsUSDCHF(_Symbol); + bool isEURCHF = _symbolParser.IsEURCHF(_Symbol); + bool isUSDJPY = _symbolParser.IsUSDJPY(_Symbol); + bool isEURJPY = _symbolParser.IsEURJPY(_Symbol); + bool isUSDCAD = _symbolParser.IsUSDCAD(_Symbol); + bool isEURCAD = _symbolParser.IsEURCAD(_Symbol); + bool isAUDUSD = _symbolParser.IsAUDUSD(_Symbol); + bool isEURAUD = _symbolParser.IsEURAUD(_Symbol); + bool isNZDUSD = _symbolParser.IsNZDUSD(_Symbol); + bool isEURNZD = _symbolParser.IsEURNZD(_Symbol); + + // + // Check Symbol Can Register or not ... + bool canRegisterStrategy = true; + + // + if (canRegisterStrategy) + { + // + // Create Class Instance ... + XCX121SMCBaseStrategy *iX121SMCStrategy; + iX121SMCStrategy = new XCX121SMCTestStrategy( + iSymbol, + _Period // + ); + + // + iX121SMCStrategy.AddXSignalEventHandler(OnSignalEventListener); + + // + // Register Strategy ... + ConfigureStrategy(iX121SMCStrategy); + RegisterStrategy(iX121SMCStrategy); + } + } + } + + // + return result; + } + + /** + * Destroy all Initialized EA Requirements ... + */ + void DestroyEA() override + { + // + delete mCTHelper; + delete mCCHelper; + delete mTradeHandler; + + // + Clean(mStrategies); + } + + /** + * Call all Registered Strategies On Tick ... + */ + void HandleStrategiesOnTick() override + { + // + // Calling Protection Handler of TradeHandler ... + mTradeHandler.HandleProtection(); + + // + int count = ArraySize(mStrategies); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + // Call Tick Handler Function ... + mStrategies[i].HandleTick(); + } + } + + // + // Event Handlers ... + + /** + * Calls When a Position's SL Triggered ... + * + * @param deal: XDeal instance ... + */ + void HandleOnStopLossTriggered(const XDeal &deal) override + { + // + // Finish ... + mTradeHandler.Finish(deal); + + // + HandleReportBalance(); + } + + /** + * Calls When a Position's TP Triggered ... + * + * @param deal: XDeal instance ... + */ + void HandleOnTakeProfitTriggered(const XDeal &deal) override + { + // + // Finish ... + mTradeHandler.Finish(deal); + + // + bool useDynamicRiskManagement = DynamicRiskManagement(); + if (useDynamicRiskManagement) + { + mTradeHandler.ResetSymbolInfo(deal.symbol); + } + + // + HandleReportBalance(); + } + + /** + * Handle Force Close a Position ... + * + * @param ticket: Position Ticket ... + * @param position: XPosition ... + * @param comment: Closing Comment ... + */ + void HandleOnPositionForceClosed( + const ulong ticket, + const XPosition &position, + const string comment // + ) override + { + // + // Finish ... + mTradeHandler.Finish( + ticket, + position, + comment // + ); + + // + HandleReportBalance(); + } + + /** + * Reset All Paused Symbols on Each New Days ... + */ + void HandleOnNewDay() override + { + mTradeHandler.ResumePausedSymbols(); + } + + /** + * Generate Identifier Tag ... + * + * @return ( string ) + */ + string GetTag() override + { + // + string result = NULL; + + // + string tagPrefix = TagPrefix(); + if (IsValid(tagPrefix)) + { + result = tagPrefix; + } + else + { + result = ""; + } + + // + result = + XC121SMCExpertToken + result; + + // + return result; + } + + // + protected: + // + + // + // Props ... + + // + datetime mLastSignalOn; + + // + XC121SMCTradeHandler *mTradeHandler; // Trade Handler ... + XCX121SMCBaseStrategy *mStrategies[]; // Registere Strategies in EA ... + + // + // Actions ... + + /** + * Apply Volume Based On Configurations on Signal ... + * + * @param signal: XSignal instance + */ + void ApplyVolumeOnSignal(XSignal &signal) + { + // + // Prepare Signal Dynamic Volume + // if Provided ... + if (UseDynamicVolume() && + DynamicVolumeStep() > 0 && + DynamicVolumeBalanceFactor() > 0) + { + // + double dVolume = mTrader.GetDynamicVolume( + signal.symbol, + DynamicVolumeBalanceFactor(), + DynamicVolumeStep() // + ); + + // + if (dVolume > 0) + { + signal.volume = dVolume; + } + else + { + signal.volume = Volume(); + } + } + else if (RiskPercentPerBalance() > 0) + { + // + double riskPercent = RiskPercentPerBalance(); + + // + double balance = mTrader.mAccount.GetBalance(); + double riskAmountPerBalance = (riskPercent * balance) / 100; + + // + double risk = signal.GetRisk(); + double points = GetPoints(signal.symbol); + double riskInPoints = risk / points; + + // + double volume = mTrader.mAccount.CalculateVolume( + signal.symbol, + riskAmountPerBalance, + riskInPoints // + ); + + // + // Check Dynamic Risk Management ... + bool allowDynamicRiskManagement = DynamicRiskManagement(); + if (allowDynamicRiskManagement) + { + // + // Calculate Dynamic Additional Risk Management Volume Multiplier ... + double mAdditionalRiskMultiplier = CalculateAdditionalVolumeMultiplier(signal); + if (mAdditionalRiskMultiplier < 1) + { + mAdditionalRiskMultiplier = 1; + } + + // + volume *= mAdditionalRiskMultiplier; + } + + // + if (volume > 0) + { + volume = NormalizeVolume(volume, signal.symbol); + } + + // + signal.volume = volume; + } + else + { + signal.volume = Volume(); + } + + // + mTradeHandler.UpdateSignal(signal); + } + + /** + * Configure Startegy ... + */ + void ConfigureStrategy(XCX121SMCBaseStrategy *&strategy) + { + // + if (strategy == NULL) + { + return; + } + + // + // Configure Alerts ... + strategy.SetAlertPrefix(GetTag()); + strategy.SetAlertLogAlerts(GetAlertLogAlerts()); + strategy.SetAlertMailAlerts(GetAlertMailAlerts()); + strategy.SetAlertPushAlerts(GetAlertPushAlerts()); + strategy.SetAlertEnableAlerts(GetAlertEnableAlerts()); + strategy.SetAlertTerminalAlerts(GetAlertTerminalAlerts()); + + // + // Confiugre Signalling ... + + // + strategy.R2R(R2R()); + strategy.AllowLong(AllowLong()); + strategy.AllowShort(AllowShort()); + strategy.MaxAllowedSpread(20); + + // + if (Disabled()) + { + strategy.Disable(); + } + else + { + strategy.Enable(); + } + + // + } + + /** + * Register an Strategy in EA ... + * + * @param strategy: XCX121SMCBaseStrategy instance ... + */ + void RegisterStrategy(XCX121SMCBaseStrategy *strategy) + { + // + if (strategy == NULL) + { + return; + } + + // + ArrayResize( + mStrategies, + ArraySize(mStrategies) + 1 // + ); + + // + mStrategies[ArraySize(mStrategies) - 1] = strategy; + } + + /** + * Re Configure All Registered Strategies ... + */ + void ReConfigureAllStrategies() + { + // + int count = ArraySize(mStrategies); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + ConfigureStrategy(mStrategies[i]); + } + } + + // + private: + // + + // + // Props ... + + // + // Volume Management ... + double mR2R; // Signallers Risk to Reward Ratio ... + bool mUseDynamicVolume; // Use Dynamic Volume ... + double mDynamicVolumeStep; // Increase Volume Step ... + double mDynamicVolumeBalanceFactor; // Balance Factor for Generate Dynamic Volume ... + double mVolume; // Static Volume ... + bool mDynamicRiskManagement; // Dynamic Risk Management ... + double mRiskPercentPerBalance; // Risk Percent Per Balance in Each Trade ... + + // + double CalculateAdditionalVolumeMultiplier(XSignal &signal) + { + // + double result = 0; + + // + if (!signal.IsValid()) + { + return result; + } + + // + X121SMCSymbolPositionInfo info; + bool hasInfo = mTradeHandler.GetSymbolInfo( + signal.symbol, + info // + ); + if (!hasInfo) + { + return result; + } + + // + if (info.countedSLs >= 2) + { + result = (info.countedSLs / 2) + 1; + } + + // + return result; + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.lib copy.mq5 b/Documents/BKP/x-121.smc.lib copy.mq5 new file mode 100644 index 00000000..898b58de --- /dev/null +++ b/Documents/BKP/x-121.smc.lib copy.mq5 @@ -0,0 +1,2144 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: X121SMCLib +// Description: provide all commonly used functions ... +// +// +// 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.base.class.mq5" +#include "../../Helpers/x-saherelm.x121.helper.mq5" +#include "../../Libraries/x-saherelm.common.lib.mq5" +#include "../../Libraries/x-saherelm.x-poi.lib.mq5" +#include "../../Libraries/x-saherelm.x-trade.lib.mq5" + +// +// Definitions ... + +const string X121SMCStrategyToken = "X121SMC"; + +const string X121SMCPVToken = "X121SMCPV"; +const string X121SMCBOSToken = "X121SMCBOS"; +const string X121SMCSARToken = "X121SMCSAR"; +const string X121SMCCHOCHToken = "X121SMCCHOCH"; +const string X121SMCPULLBKToken = "X121SMCPULLBK"; + +enum ENUM_X_121_SMC_PROVIDERS +{ + // + X_121_SMC_PROVIDER_NONE, + X_121_SMC_PROVIDER_PV, + X_121_SMC_PROVIDER_BOS, + X_121_SMC_PROVIDER_SAR, + X_121_SMC_PROVIDER_CHOCH, + X_121_SMC_PROVIDER_PULLBK, +}; + +enum ENUM_XPV_PIVOTS +{ + XPV_NONE, + XPV_PEAK, + XPV_VALE, +}; + +struct XPVPivot +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double upper; + double lower; + + // + datetime from; + datetime to; + + // + int repetition; + + // + ENUM_XPV_PIVOTS type; + + // + // Combined all States ... + XPOIState state; + + // + XPVPivot() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + upper = 0; + lower = 0; + + // + to = NULL; + from = NULL; + symbol = NULL; + period = NULL; + + // + repetition = 0; + + // + type = XPV_NONE; + + // + state.Clean(); + } + + /** + * Validation ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(to) && + IsValid(from) && + IsValid(symbol) && + IsValid(period) && + repetition > 0 && + type != XPV_NONE && + (upper > 0 || lower > 0) + // + ; + + // + return result; + } + + /** + * Check Pivot is Peak ... + * + * @return ( bool ) + */ + bool IsPeak() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_PEAK; + + // + return result; + } + + /** + * Check Pivot is Vale ... + * + * @return ( bool ) + */ + bool IsVale() + { + // + bool result = false; + + // + result = IsValid() && + type == XPV_VALE; + + // + return result; + } + + /** + * Calculate Lower for Peaks ... + * + * @return ( double ) + */ + double CalculateLower() + { + // + double result = 0; + + // + if (!IsValid() || + !IsPeak()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int llIDX = iLowest( + symbol, + period, + MODE_LOW, + count, + toIndex // + ); + + // + result = + iLow( + symbol, + period, + llIDX // + ); + + // + return result; + } + + /** + * Calculate Upper for Vales ... + * + * @return ( double ) + */ + double CalculateUpper() + { + // + double result = 0; + + // + if (!IsValid() || + !IsVale()) + { + return result; + } + + // + int fromIndex = iBarShift( + symbol, + period, + from // + ); + + // + int toIndex = iBarShift( + symbol, + period, + to // + ); + + // + int count = + fromIndex - toIndex; + + // + int hhIDX = iHighest( + symbol, + period, + MODE_HIGH, + count, + toIndex // + ); + + // + result = + iHigh( + symbol, + period, + hhIDX // + ); + + // + return result; + } + + /** + * Calculate Range of Pivot ... + * + * @return ( double ) + */ + double CalculateRange() + { + // + double result = 0; + + // + if (!IsValid() || + upper <= 0 || + lower <= 0) + { + return result; + } + + // + result = upper - lower; + + // + return result; + } + + /** + * Calculate Middle of Pivot ... + * Used for + * @return ( double ) + */ + double CalculateMid() + { + // + double result = 0; + + // + double range = CalculateRange(); + if (range <= 0) + { + return result; + } + + // + result = lower + (range / 2); + + // + return result; + } + + /** + * Calculate Liquidity Percent for Specified Direction ... + * + * @param forDirection: ENUM_X_DIRECTION member, Specified Liquidity ... + * @param price: Double, Specified Price ... + * + * @return ( double ) + */ + double CalculateLiquidityPercent( + ENUM_X_DIRECTION forDirection, + double price = 0 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + result = state + .CalculateLiquidityPercent( + forDirection, + price // + ); + + // + return result; + } + + // + + /** + * Get Unique Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + string hash = symbol + "_" + + ToString(period) + "_" + + ToString(upper) + "," + + ToString(lower) + "_" + + ToString(from) + "," + + ToString(to); + hash = ToMD5(hash); + + // + string typeStr = + type == XPV_PEAK + ? "Peak" + : "Vale"; + + // + result = + // + "XPV_" + + typeStr + "_" + + symbol + "_" + + ToString(period) + + "_" + hash + // + ; + + // + return result; + } + + // +}; + +// +// Each Market Cycle (Time Frame) Conditions +// Model as this Structure ... +struct X121SMCCycleConditions +{ + // + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + X121Conditions x121Conditions; + + // + XPOIState state; + + // + void X121SMCStrategyConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + time = NULL; + + // + state.Clean(); + x121Conditions.Clean(); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(time); + // + ; + + // + return result; + } + + /** + * Check Cycle Conditions Has Bullish State ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool IsBullish( + XOHCL &bar // + ) + { + // + bool result = false; + + // + int index = bar.Index(); + + // + result = + // + // Check Conditions Validation ... + IsValid() && + // + // Check Bar Validation ... + bar.IsValid() && + // + // Check XCHSar Current is Bullish ... + xchsarConditions.isCBullish && + // + // Check X3VWAP is Bullish State ... + x3vwapConditions.isBullishState && + // + // Check X3VWAP is Bullish Ordered ... + x3vwapConditions.isBullishOrdered && + // + // Check Close Over X3MA Fast ... + bar.close > x3maConditions.fasts[index] + // + ; + + // + return result; + } + + /** + * Check Cycle Conditions Has Bearish State ... + * + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool IsBearish( + XOHCL &bar // + ) + { + // + bool result = false; + + // + int index = bar.Index(); + + // + result = + // + // Check Conditions Validation ... + IsValid() && + // + // Check Bar Validation ... + bar.IsValid() && + // + // Check XCHSar Current is Bearish ... + xchsarConditions.isCBearish && + // + // Check X3VWAP is Bearish State ... + x3vwapConditions.isBearishState && + // + // Check X3VWAP is Bearish Ordered ... + x3vwapConditions.isBearishOrdered && + // + // Check Close Under X3MA Fast ... + bar.close < x3maConditions.fasts[index] + // + ; + + // + return result; + } + + // + // Reporter Functions ... + + /** + * Generate Provided Scores ... + * + * @param bullishScore: Integer, reference ... + * @param bearishScore: Integer, referenceF ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + if (!IsValid()) + { + return; + } + + // + double bullScore = 0; + double bearScore = 0; + + // // + // // XPV ... + // pvConditions.GenerateScore( + // bullScore, + // bearScore // + // ); + // bullishScore += bullScore; + // bearishScore += bearScore; + } + + /** + * Generate Summary ... + * + * @param onlyCommons: Boolean ... + * @param onlyConditions: Boolean ... + * @param includeScores: Boolean ... + * @param ignoreFalseConditions: Boolean ... + * @param separator: String ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores, + true // + ); + + // // + // // XPV ... + // string pvStr = pvConditions.GenerateSummary( + // false, + // true, + // false, + // ignoreFalseConditions // + // ); + + // + string conditionsStr = + // + // pvStr + separator + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + "----------" + separator + + (onlyConditions + ? "" + : commonStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Get Unique Identifier ... + * + * @param forObject: Boolean ... + * + * @return ( string ) + */ + string GetTag( + bool forObject = false // + ) + { + // + string result = NULL; + + // + string typeName = GetTypeName(this); + + // + if (!forObject) + { + result = typeName; + } + else + { + // + result = typeName + "_" + + symbol + "_" + ToString(period) + "_" + + ToMD5(time); + } + + // + return result; + } + + // +}; + +// +// Model Signalling Conditions ... +struct X121SMCStrategyConditions +{ + // + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Cycles Conditions here ... + X121SMCCycleConditions triggerConditions; + X121SMCCycleConditions decisionConditions; + X121SMCCycleConditions analyseConditions; + X121SMCCycleConditions verificationConditions; + X121SMCCycleConditions consolidationConditions; + X121SMCCycleConditions visionConditions; + + // + double sl; + string provider; + ENUM_X_DIRECTION marketStructureDir; + + // + void X121SMCStrategyConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + symbol = NULL; + period = NULL; + time = NULL; + + // + sl = 0; + provider = NULL; + marketStructureDir = X_DIRECTION_NONE; + + // + triggerConditions.Clean(); + decisionConditions.Clean(); + analyseConditions.Clean(); + verificationConditions.Clean(); + consolidationConditions.Clean(); + visionConditions.Clean(); + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(time); + + // + return result; + } + + /** + * Check Conditions has Ddirection or not ... + * + * @param dir: ENUM_X_DIRECTIOn member ... + * @param bar: XOHCL instance ... + * + * @return ( bool ) + */ + bool HasDirection( + ENUM_X_DIRECTION &dir, + XOHCL &bar // + ) + { + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + result = IsValid() && + bar.IsValid() && + bar.Index() > 0; + if (!result) + { + return result; + } + + // + int index = bar.Index(); + + // + // Parse Cycles Conditions ... + + // + // Vision ... + + // + bool isVisionBullish = + // + // XCHSar Current is Bullish ... + visionConditions.xchsarConditions.isCBullish && + // + // Close Over X3MA Fast ... + bar.close > visionConditions.x3maConditions.fasts[index] && + // + // X3VWap Fast is Bullish ... + visionConditions.x3vwapConditions.fastStates[index] == + X3VWAP_STATE_BULLISH + // + ; + + // + bool isVisionBearish = + // + // XCHSar Current is Bearish ... + visionConditions.xchsarConditions.isCBearish && + // + // Close Under X3MA Fast ... + bar.close < visionConditions.x3maConditions.fasts[index] && + // + // X3VWap Fast is Bearish ... + visionConditions.x3vwapConditions.fastStates[index] == + X3VWAP_STATE_BEARISH + // + ; + + // + // Check Vision Has Conditions or not ... + bool hasVisionConditions = + isVisionBullish || + isVisionBearish; + result = hasVisionConditions; + if (!result) + { + return result; + } + + // + // Consolidation ... + + // + bool isConsolidationBullish = consolidationConditions.IsBullish(bar); + bool isConsolidationBearish = consolidationConditions.IsBearish(bar); + bool hasConsolidationConditions = + isConsolidationBullish || + isConsolidationBearish; + result = hasConsolidationConditions; + if (!result) + { + return result; + } + + // + // Verification ... + + // + bool isVerificationBullish = verificationConditions.IsBullish(bar); + bool isVerificationBearish = verificationConditions.IsBearish(bar); + bool hasVerificationConditions = + isVerificationBullish || + isVerificationBearish; + result = hasVerificationConditions; + if (!result) + { + return result; + } + + // + // Analyse ... + + // + bool isAnalyseBullish = analyseConditions.IsBullish(bar); + bool isAnalyseBearish = analyseConditions.IsBearish(bar); + bool hasAnalyseConditions = + isAnalyseBullish || + isAnalyseBearish; + result = hasAnalyseConditions; + if (!result) + { + return result; + } + + // + // Decision ... + + // + bool isDecisionBullish = decisionConditions.IsBullish(bar); + bool isDecisionBearish = decisionConditions.IsBearish(bar); + bool hasDecisionConditions = + isDecisionBullish || + isDecisionBearish; + result = hasDecisionConditions; + if (!result) + { + return result; + } + + // + // Analyse Conditions ... + bool hasBullishConditions = + // + isVisionBullish && + isConsolidationBullish && + isVerificationBullish && + isAnalyseBullish && + isDecisionBullish + // + ; + bool hasBearishConditions = + // + isVisionBearish && + isConsolidationBearish && + isVerificationBearish && + isAnalyseBearish && + isDecisionBearish + // + ; + result = hasBullishConditions || + hasBearishConditions; + if (!result) + { + return result; + } + + // + // Specified Conditions Direction ... + dir = + hasBullishConditions + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + return result; + } + + // + // Reporter Functions ... + + /** + * Generate Provided Scores ... + * + * @param bullishScore: Integer, reference ... + * @param bearishScore: Integer, referenceF ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + if (!IsValid()) + { + return; + } + + // + double bullScore = 0; + double bearScore = 0; + + // // + // // XPV ... + // pvConditions.GenerateScore( + // bullScore, + // bearScore // + // ); + // bullishScore += bullScore; + // bearishScore += bearScore; + } + + /** + * Generate Summary ... + * + * @param onlyCommons: Boolean ... + * @param onlyConditions: Boolean ... + * @param includeScores: Boolean ... + * @param ignoreFalseConditions: Boolean ... + * @param separator: String ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores, + true // + ); + + // // + // // XPV ... + // string pvStr = pvConditions.GenerateSummary( + // false, + // true, + // false, + // ignoreFalseConditions // + // ); + + // + string conditionsStr = + // + // pvStr + separator + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + "----------" + separator + + (onlyConditions + ? "" + : commonStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Get Unique Identifier ... + * + * @param forObject: Boolean ... + * + * @return ( string ) + */ + string GetTag( + bool forObject = false // + ) + { + // + string result = NULL; + + // + string typeName = GetTypeName(this); + + // + if (!forObject) + { + result = typeName; + } + else + { + // + result = typeName + "_" + + symbol + "_" + ToString(period) + "_" + + ToMD5(time); + } + + // + return result; + } + + // +}; + +// +// +// + +typedef void (*TOnX121SMCSignal)( + XSignal &signal, + X121SMCStrategyConditions &conditions // +); + +// +// Extentions ... + +/** + * Find Oldest Pivot Index ... + * + * @param pivots: XPVPivot instance ... + * @return ( int ) + */ +int FindOldestPivotIndex( + XPVPivot &pivots[] // +) +{ + // + int result = -1; + + // + int count = ArraySize(pivots); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + bool isOldest = true; + for (int j = 0; j < count; j++) + { + // + XPVPivot jPivot = pivots[j]; + + // + isOldest = iPivot.from <= jPivot.from; + if (!isOldest) + { + break; + } + } + + // + if (isOldest) + { + // + result = i; + break; + } + } + + // + return result; +} + +/** + * Sort Pivots Based On From Date ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void SortPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1); + } + else + { + // + int idx = FindOldestPivotIndex(tmp); + if (IsValidIndex(idx)) + { + // + AddRef( + tmp[idx], + pivots // + ); + + // + ArrayRemove( + tmp, + idx, + 1 // + ); + } + } + } + + // + Clean(tmp); +} + +bool IsPivotBreaked( + XPVPivot &pivot, + XPVPivot &pivots[] // +) +{ + // + bool result = false; + + // + result = pivot.IsValid(); + if (!result) + { + return result; + } + + // + int count = ArraySize(pivots); + result = IsValidSize(pivots); + if (!result) + { + return result; + } + + // + // For Peaks Highs Must not Broked ... + // For Vales Lows Must not Broked ... + bool isPeak = pivot.IsPeak(); + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = pivots[i]; + + // + result = isPeak + ? iPivot.upper > pivot.upper + : iPivot.lower < pivot.lower; + if (result) + { + break; + } + } + + // + return result; +} + +/** + * Filter Broken Pivots for Detect Order Flow ... + * + * @param pivots: XPVPivot instance Collection reference ... + */ +void FilterBrokenPivots( + XPVPivot &pivots[] // +) +{ + // + XPVPivot tmp[]; + Copy( + pivots, + tmp // + ); + + // + Clean(pivots); + + // + while (ArraySize(tmp) > 0) + { + // + if (ArraySize(tmp) == 1) + { + // + AddRef( + tmp[0], + pivots // + ); + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + } + else + { + // + XPVPivot pivot = tmp[0]; + + // + ArrayRemove( + tmp, + 0, + 1 // + ); + + // + bool isBreaked = IsPivotBreaked( + pivot, + tmp // + ); + if (!isBreaked) + { + // + AddRef( + pivot, + pivots // + ); + } + } + } + + // + Clean(tmp); +} + +/** + * Calculate Order Flow Direction ... + * + * @param orderFlow: XPVPivot instance Collection reference ... + * @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ... + * + * @return ( bool ) + */ +bool DetectPivotDirection( + XPVPivot &orderFlow[], + ENUM_X_DIRECTION &dir // +) +{ + // + bool result = false; + + // + dir = X_DIRECTION_NONE; + + // + int count = ArraySize(orderFlow); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // For Bullish Direction all Exists lowers must be Greater or Equal Prev ... + bool isBullish = false; + bool canLookupForBullish = true; + + // + // For Bearish Direction all Exists uppers must be Lesser or Equal Prev ... + bool isBearish = false; + bool canLookupForBearish = true; + + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = orderFlow[i]; + + // + XPVPivot tmp[]; + Copy( + orderFlow, + tmp // + ); + ArrayRemove( + tmp, + 0, + i + 1 // + ); + + // + int tmpCount = ArraySize(tmp); + if (IsValidSize(tmpCount)) + { + // + for (int j = 0; j < tmpCount; j++) + { + // + XPVPivot jPivot = tmp[j]; + + // + // Check Bullish Direction ... + isBullish = + canLookupForBullish && + jPivot.lower >= iPivot.lower; + if (!isBullish) + { + canLookupForBullish = false; + } + + // + // Check Bearish Direction ... + isBearish = + canLookupForBearish && + jPivot.upper <= iPivot.upper; + if (!isBearish) + { + canLookupForBearish = false; + } + + // + if (!canLookupForBullish && + !canLookupForBearish) + { + break; + } + } + } + Clean(tmp); + } + + // + if (isBullish && + !isBearish) + { + dir = X_DIRECTION_BULLISH; + } + else if (isBearish && + !isBullish) + { + dir = X_DIRECTION_BEARISH; + } + + // + result = dir != X_DIRECTION_NONE; + + // + return result; +} + +/** + * Detect all POIs which inside a Pivot ... + * + * @param pivot: XPVPivot instance, Specified Pivot ... + * @param source: XPOIState instance, Reference to Source State ... + * @param state: XPOIState instance, Reference to Detected Pivots ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + */ +void DetectPivotPOIs( + XPVPivot &pivot, + XPOIState &source, + XPOIState &state, + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // +) +{ + // + state.Clean(); + + // + if (!pivot.IsValid()) + { + return; + } + + // + int count = 0; + + // + state.symbol = pivot.symbol; + state.period = pivot.period; + state.time = TimeCurrent(); + + // + // Swings ... + + // + // Swing High ... + if (lookupSwingHighs) + { + // + count = ArraySize(source.swingHighs); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper; + if (isInside) + { + // + Add( + iSwing, + state.swingHighs // + ); + } + } + } + } + + // + // Swing Low ... + if (lookupSwingLows) + { + // + count = ArraySize(source.swingLows); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing *iSwing = source.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iSwing, + state.swingLows // + ); + } + } + } + } + + // + // Support and Resistance Zones ... + + // + // Support Zones ... + if (lookupSupportZones) + { + // + count = ArraySize(source.supportZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone *iZone = source.supportZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.supportZones // + ); + } + } + } + } + + // + // Resistance Zones ... + if (lookupResistanceZones) + { + // + count = ArraySize(source.resistanceZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone *iZone = source.resistanceZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.resistanceZones // + ); + } + } + } + } + + // + // Supply and Demand Zones ... + + // + // Supply Zones ... + if (lookupSupplyZones) + { + // + count = ArraySize(source.supplyZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone *iZone = source.supplyZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.supplyZones // + ); + } + } + } + } + + // + // Demand Zones ... + if (lookupDemandZones) + { + // + count = ArraySize(source.demandZones); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone *iZone = source.demandZones[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.demandZones // + ); + } + } + } + } + + // + // Order Blocks ... + + // + // Bullish Order Blocks ... + if (lookupBullishOrderBlocks) + { + // + count = ArraySize(source.bullishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bullishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bullishOrderBlocks // + ); + } + } + } + } + + // + // Bearish Order Blocks ... + if (lookupBearishOrderBlocks) + { + // + count = ArraySize(source.bearishOrderBlocks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock *iZone = source.bearishOrderBlocks[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bearishOrderBlocks // + ); + } + } + } + } + + // + // Fair Value Gaps ... + + // + // Bullish Fair Value Gaps ... + if (lookupBullishFairValueGaps) + { + // + count = ArraySize(source.bullishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bullishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bullishFairValueGaps // + ); + } + } + } + } + + // + // Bearish Fair Value Gaps ... + if (lookupBearishFairValueGaps) + { + // + count = ArraySize(source.bearishFairValueGaps); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG *iZone = source.bearishFairValueGaps[i]; + + // + bool isInside = + iZone.Upper() <= pivot.upper && + iZone.Lower() >= pivot.lower; + if (isInside) + { + // + Add( + iZone, + state.bearishFairValueGaps // + ); + } + } + } + } + + // + // Rejection Bars ... + + // + // Bullish Rejection Bars ... + if (lookupBullishRejectionBars) + { + // + count = ArraySize(source.bullishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iRejection, + state.bullishRejectionBars // + ); + } + } + } + } + + // + // Bearish Rejection Bars ... + if (lookupBearishRejectionBars) + { + // + count = ArraySize(source.bearishRejectionBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar *iRejection = source.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + Add( + iRejection, + state.bearishRejectionBars // + ); + } + } + } + } + + // + // Momentum Bars ... + + // + // Bullish Momentum Bars ... + if (lookupBullishMomentumBars) + { + // + count = ArraySize(source.bullishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.low <= pivot.upper && + iBar.low >= pivot.lower; + if (isInside) + { + // + Add( + iMomentum, + state.bullishMomentumBars // + ); + } + } + } + } + + // + // Bearish Momenum Bars ... + if (lookupBearishMomentumBars) + { + // + count = ArraySize(source.bearishMomentumBars); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar *iMomentum = source.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isInside = iBar.high <= pivot.upper && + iBar.high >= pivot.lower; + if (isInside) + { + // + Add( + iMomentum, + state.bearishMomentumBars // + ); + } + } + } + } +} + +// +// Provider Extensions ... + +/** + * Validate a Signal Provider ... + * + * @param value: ENUM_X_121_SMC_PROVIDERS member ... + * + * @return ( bool ) + */ +bool IsValid(ENUM_X_121_SMC_PROVIDERS value) +{ + // + bool result = false; + + // + result = value != X_121_SMC_PROVIDER_NONE; + + // + return result; +} + +/** + * Converts a Signal Provider to String ... + * + * @param value: ENUM_X_121_SMC_PROVIDERS member ... + * + * @return ( string ) + */ +string ToString(ENUM_X_121_SMC_PROVIDERS value) +{ + // + string result = NULL; + + // + if (!IsValid(value)) + { + return result; + } + + // + switch (value) + { + // + case X_121_SMC_PROVIDER_PV: + result = X121SMCPVToken; + break; + + // + case X_121_SMC_PROVIDER_BOS: + result = X121SMCBOSToken; + break; + + // + case X_121_SMC_PROVIDER_SAR: + result = X121SMCSARToken; + break; + + // + case X_121_SMC_PROVIDER_CHOCH: + result = X121SMCCHOCHToken; + break; + + // + case X_121_SMC_PROVIDER_PULLBK: + result = X121SMCPULLBKToken; + break; + } + + // + return result; +} + +/** + * Parse Specified String as a Signal Provider ... + * + * @param value: String ... + * + * @return ( ENUM_X_121_SMC_PROVIDERS ) + */ +ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) +{ + // + ENUM_X_121_SMC_PROVIDERS result = X_121_SMC_PROVIDER_NONE; + + // + if (!IsValid(value)) + { + return result; + } + + // + if (Contains(X121SMCPVToken, value)) + { + result = X_121_SMC_PROVIDER_PV; + } + else if (Contains(X121SMCBOSToken, value)) + { + result = X_121_SMC_PROVIDER_BOS; + } + else if (Contains(X121SMCSARToken, value)) + { + result = X_121_SMC_PROVIDER_SAR; + } + else if (Contains(X121SMCCHOCHToken, value)) + { + result = X_121_SMC_PROVIDER_CHOCH; + } + else if (Contains(X121SMCPULLBKToken, value)) + { + result = X_121_SMC_PROVIDER_PULLBK; + } + + // + return result; +} + +// \ No newline at end of file diff --git a/Documents/BKP/x-121.smc.market.cycle.helper.class.mq5 b/Documents/BKP/x-121.smc.market.cycle.helper.class.mq5 new file mode 100644 index 00000000..826e6738 --- /dev/null +++ b/Documents/BKP/x-121.smc.market.cycle.helper.class.mq5 @@ -0,0 +1,1483 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XC121SMCCycleHelper +// Description: provides all based classes for use ... +// +// +// 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-bar.analyser.class.mq5" +#include "../../Classes/x-saherelm.x-poi.class.mq5" +#include "../../Helpers/x-saherelm.x121.helper.mq5" +#include "../Libraries/x-121.smc.lib.mq5" + +// +// Definitions ... +struct XSarChange +{ + // + // Props ... + ENUM_X_DIRECTION dir; // Sar Changed To Direction ... + datetime time; // Sar Changed Time ... + double last; // Sar Value Before Change ... + double value; // Sar Value After Change ... + + // + // Constructor ... + XSarChange() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + last = 0; + value = 0; + time = NULL; + dir = X_DIRECTION_NONE; + } + + /** + * Validation ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + last > 0 && + value > 0 && + IsValid(time) && + HasDirection(dir); + + // + return result; + } + + /** + * Initialize ... + * + * @param _last: Last Sar Value ... + * @param _current: Current Sar Value ... + * + * @return ( bool ) + */ + bool Init( + double _last, + double _current, + datetime _time, + ENUM_X_DIRECTION _dir // + ) + { + // + bool result = false; + + // + result = + _last > 0 && + _current > 0 && + IsValid(_time) && + HasDirection(_dir); + if (!result) + { + return result; + } + + // + dir = _dir; + last = _last; + time = _time; + value = _current; + + // + result = IsValid(); + + // + return result; + } + + /** + * Check Change is Bullish ... + * + * @return ( bool ) + */ + bool IsBullish() + { + // + bool result = false; + + // + result = + IsValid() && + IsBullish(dir); + + // + return result; + } + + /** + * Check Change is Bearish ... + * + * @return ( bool ) + */ + bool IsBearishÙ‘() + { + // + bool result = false; + + // + result = + IsValid() && + IsBearish(dir); + + // + return result; + } + + // +}; + +// +// Implementations ... + +class XC121SMCCycleHelper : public XCBase +{ + // + public: + // + // Props ... + + // + // XPV ... + XCXPVHelper *mXPVHelper; + XPVPivot pivots[]; + XPVPivot orderFlow[]; + + // + // X3MA ... + XCX3MAHelper *mX3MAHelper; + + // + // X3VWAP ... + XCX3VWAPHelper *mX3VWAPHelper; + + // + // XCHSAR ... + XCXCHSARHelper *mXCHSARHelper; + XSarChange sarChanges[]; + + // + // X121 ... + XCX121Helper *mX121Helper; + + // + // POI Detector ... + XCPOIDetector *mPOIDetector; + + // + // Constructor(s) ... + XC121SMCCycleHelper() + { + } + + // + // Deconstructor ... + ~XC121SMCCycleHelper() + { + DeInit(); + } + + // + // Getter/Setter(s) ... + + // + // Actions ... + + /** + * Initialize ... + * + * @param symbol: String ... + * @param period: ENUM_TIMEFRAMES member ... + * @param xpvInputs: XPVInputs instance ... + * @param x3maInputs: X3MAInputs instance ... + * @param x3vwapInputs: X3VWAPInputs instance ... + * @param xchsarInputs: XCHSARInputs instance ... + * + * @return ( bool ) + */ + bool Init( + string symbol, + ENUM_TIMEFRAMES period, + XPVInputs &xpvInputs, + X3MAInputs &x3maInputs, + X3VWAPInputs &x3vwapInputs, + XCHSARInputs &xchsarInputs // + ) + { + // + bool result = false; + + // + result = IsValid(symbol) && + IsValid(period); + if (!result) + { + return result; + } + + // + // XPV ... + + // + result = xpvInputs.IsValid(); + if (!result) + { + return result; + } + + // + mXPVHelper = new XCXPVHelper(); + result = mXPVHelper.Init( + symbol, + period, + xpvInputs // + ); + if (!result) + { + return result; + } + + // + // X3MA ... + + // + result = x3maInputs.IsValid(); + if (!result) + { + return result; + } + + // + mX3MAHelper = new XCX3MAHelper(); + result = mX3MAHelper.Init( + symbol, + period, + x3maInputs // + ); + if (!result) + { + return result; + } + + // + // X3VWAP ... + + // + result = x3vwapInputs.IsValid(); + if (!result) + { + return result; + } + + // + mX3VWAPHelper = new XCX3VWAPHelper(); + result = mX3VWAPHelper.Init( + symbol, + period, + x3vwapInputs // + ); + if (!result) + { + return result; + } + + // + // XCHSAR ... + + // + result = xchsarInputs.IsValid(); + if (!result) + { + return result; + } + + // + mXCHSARHelper = new XCXCHSARHelper(); + result = mXCHSARHelper.Init( + symbol, + period, + xchsarInputs // + ); + if (!result) + { + return result; + } + + // + mPOIDetector = new XCPOIDetector( + symbol, + period // + ); + mPOIDetector.MaxNumberOfRequiredPOIs(0); + mPOIDetector.Init(); + + // + // Initialize Bar Analyser Class Instance ... + mBarAnalyser = new XCBarAnalyser(); + + // + // Set Chart Style ... + ApplyChartStyle(); + + // + return result; + } + + /** + * Get Specified Bar ... + * + * @param source: XOHCL instance, Source Bar ... + * @param bar: XOHCL instance, Dest Bar ... + * + * @return ( bool ) + */ + bool GetBar( + XOHCL &source, + XOHCL &bar // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + result = + IsValid(symbol) && + IsValid(period) && + source.IsValid(); + if (!result) + { + return result; + } + + // + int index = iBarShift( + symbol, + period, + source.time // + ); + result = bar.Init( + symbol, + period, + index // + ); + if (!result) + { + // + bar.Clean(); + return result; + } + + // + return result; + } + + /** + * Retrieve Specified Bar ... + * + * @param bar: XOHCL instance ... + * @param index: Integer ... + * + * @return ( bool ) + */ + bool GetBar( + XOHCL &bar, + int index = 0 // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + if (index < 0) + { + index = 0; + } + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + result = bar.Init( + symbol, + period, + index // + ); + + // + return result; + } + + /** + * Retrieve Specified Bar ... + * + * @param bar: XOHCL instance ... + * @param time: Datetime ... + * + * @return ( bool ) + */ + bool GetBar( + XOHCL &bar, + datetime time = NULL // + ) + { + // + bool result = false; + + // + int index = GetBarIndex(time); + result = GetBar(bar, + index // + ); + + // + return result; + } + + /** + * Retrieve Specified Time Bar Index ... + * + * @param time: DateTime ... + * + * @return ( int ) + */ + int GetBarIndex(datetime time = NULL) + { + // + int result = -1; + + // + time = NormalizeTime(time); + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + result = iBarShift( + symbol, + period, + time // + ); + + // + return result; + } + + /** + * Retrieve Cycle Conditions ... + * + * @param conditions: X121SMCCycleConditions instance ... + * @param barIndex: Integer ... + * @param loopback: Integer ... + * + * @return ( bool ) + */ + bool GetConditions( + X121SMCCycleConditions &conditions, + int barIndex = 0, + int loopback = 7 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + result = mXPVHelper.GetConditions( + conditions.xpvConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + result = mX3MAHelper.GetConditions( + conditions.x3maConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + result = mX3VWAPHelper.GetConditions( + conditions.x3vwapConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + result = mXCHSARHelper.GetConditions( + conditions.xchsarConditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + conditions.symbol = conditions.xpvConditions.symbol; + conditions.period = conditions.xpvConditions.period; + conditions.time = TimeCurrent(); + + // + result = conditions.IsValid(); + + // + return result; + } + + // + // POI Tools ... + + /** + * Detect Nearest Current SAR Change ... + * + * @param changeBar: XOHCL instance, Holds Nearest Change Bar ... + * @param bar: XOHCL instance, represents Current Bar for Loopback ... + * + * @return ( bool ) + */ + bool DetectNearestCSARChange( + XOHCL &changeBar, + XOHCL &bar // + ) + { + // + bool result = false; + + // + changeBar.Clean(); + + // + result = + bar.IsValid(); + if (!result) + { + return result; + } + + // + XOHCL mBar; + result = GetBar( + bar, + mBar // + ); + if (!result) + { + return result; + } + + // + int barIndex = mBar.Index(); + double sar = mXCHSARHelper.GetC(barIndex); + bool isBullish = sar > 0 && + sar < mBar.low; + bool isBearish = sar > 0 && + sar > mBar.high; + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Loop Back to Find Nearest Sar Change ... + bool canContinue = true; + while (canContinue) + { + // + barIndex++; + + // + XOHCL iBar; + canContinue = iBar.Init( + mBar.symbol, + mBar.period, + barIndex // + ); + if (!canContinue) + { + break; + } + + // + double iSar = mXCHSARHelper.GetC(barIndex); + bool isISarBullish = + iSar > 0 && + iSar < iBar.low; + bool isISarBearish = + iSar > 0 && + iSar > iBar.high; + bool isSarChanged = + isBullish + ? !isISarBullish + : !isISarBearish; + + // + if (isSarChanged) + { + // + result = iBar.GetNextBar(changeBar); + canContinue = false; + break; + } + } + + // + result = changeBar.IsValid(); + + // + return result; + } + + /** + * Detect Last Decision Bar ( Rejection, Pin, Momentum ) ... + * + * @param decisionBar: XOHCL instance, Holds Decision Bar ... + * @param forDir: ENUM_X_DIRECTION member, Specified Bar Direction ... + * @param bar: XOHCL instance, represents Current Bar for Loopback ... + * + * @return ( bool ) + */ + bool DetectNearestDecisionBar( + XOHCL &decisionBar, + ENUM_X_DIRECTION forDir, + XOHCL &bar // + ) + { + // + bool result = false; + + // + decisionBar.Clean(); + + // + result = + bar.IsValid() && + forDir != X_DIRECTION_ALL && + forDir != X_DIRECTION_NONE; + if (!result) + { + return result; + } + + // + XOHCL mBar; + result = GetBar( + bar, + mBar // + ); + if (!result) + { + return result; + } + + // + int barIndex = mBar.Index(); + bool isBullish = IsBullish(forDir); + + // + bool canContinue = true; + while (canContinue) + { + // + barIndex++; + + // + XOHCL iBar; + canContinue = iBar.Init( + mBar.symbol, + mBar.period, + barIndex // + ); + if (!canContinue) + { + break; + } + + // + ENUM_X_DIRECTION decisionDir; + bool isDecisionBar = mBarAnalyser + .IsDecisionBar( + iBar, + decisionDir // + ); + if (isDecisionBar) + { + // + if (decisionDir == forDir) + { + // + decisionBar = mBar; + canContinue = false; + break; + } + } + + // + canContinue = !decisionBar.IsValid(); + } + + // + result = decisionBar + .IsValid(); + + // + return result; + } + + // + // Parabolic Sar Extensions ... + + /** + * Check Sar Changes and Save it ... + * + * @param change: XSarChange instance ... + * @param time: DateTime ... + * + * @return ( bool ) + */ + bool IsSarChanged( + XSarChange &change, + datetime time = NULL // + ) + { + // + bool result = false; + + // + change.Clean(); + + // + XOHCL bar; + result = GetBar( + bar, + time // + ); + if (!result) + { + return result; + } + + // + XOHCL prevBar; + result = bar.GetPreviousBar(prevBar); + if (!result) + { + return result; + } + + // + XOHCL prevPrevBar; + result = prevBar.GetPreviousBar(prevPrevBar); + if (!result) + { + return result; + } + + // + prevPrevBar = prevBar; + prevBar = bar; + + // + int index = prevBar.Index(); + + // + double current = mXCHSARHelper.GetC(index); + double prev = mXCHSARHelper.GetC(index + 1); + + // + bool isCurrentBullish = + current < prevBar.low; + bool isPrevBullish = + prev < prevPrevBar.low; + + // + bool isCurrentBearish = + current > prevBar.high; + bool isPrevBearish = + prev > prevPrevBar.high; + + // + bool isChangedToBullish = + isCurrentBullish && + !isPrevBullish; + + // + bool isChangedToBearish = + isCurrentBearish && + !isPrevBearish; + + // + result = isChangedToBullish || + isChangedToBearish; + if (!result) + { + return result; + } + ENUM_X_DIRECTION dir = + isChangedToBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + result = change + .Init( + prev, + current, + prevBar.time, + dir // + ); + if (!result) + { + return result; + } + + // + XSarChange lastChange; + bool hasLastItem = GetLastItem( + lastChange, + sarChanges // + ); + bool canAdd = !hasLastItem + ? true + : lastChange.time < change.time; + if (canAdd) + { + // + AddRef( + change, + sarChanges // + ); + } + + // + CleanSarChanges(); + + // + return result; + } + + /** + * Cleanup Unused Sar Changes ... + */ + void CleanSarChanges() + { + // + int required = 10; + int count = ArraySize(sarChanges); + if (!IsValidSize(count) || count <= required) + { + return; + } + + // + int mustRemove = count - required; + ArrayRemove( + sarChanges, + 0, + mustRemove // + ); + } + + // + // XPV Extensions ... + + /** + * Detect First Pivot ... + * + * @param pivot: XPVPivot instance ... + * @param time: DateTime ... + * @param minRepetition: Integer, Minimum Repetition ... + * @param maxAllowedLoopbackBars: Integer, Max Allowed LoopBack Bars ... + * + * @return ( bool ) + */ + bool DetectLastPivot( + XPVPivot &pivot, + datetime time = NULL, + int minRepetition = 40, + int maxAllowedLoopbackBars = 576 // + ) + { + // + bool result = false; + + // + pivot.Clean(); + + // + int index = GetBarIndex(time); + result = DetectPivot( + pivot, + index, + minRepetition, + maxAllowedLoopbackBars // + ); + + // + return result; + } + + /** + * Detect Pivot ... + * + * @param pivot: XPVPivot instance ... + * @param barIndex: Integer ... + * @param minRepetition: Integer, Minimum Repetition ... + * @param maxAllowedLoopbackBars: Integer, Max Allowed LoopBack Bars ... + * + * @return ( bool ) + */ + bool DetectPivot( + XPVPivot &pivot, + int barIndex = 0, + int minRepetition = 40, + int maxAllowedLoopbackBars = 576 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int start = barIndex; + int end = start + maxAllowedLoopbackBars; + + // + double peak = 0; + int peakRepeate = 0; + int peakToBarIndex = 0; + int peakFromBarIndex = 0; + + // + double vale = 0; + int valeRepeate = 0; + int valeToBarIndex = 0; + int valeFromBarIndex = 0; + + // + bool canLookupPeak = true; + bool canLookupVale = true; + bool canLookup = true; + while (canLookup) + { + // + // Check Peak ... + double iPeak = mXPVHelper.GetPeak(barIndex); + if (iPeak != peak) + { + // + if (peak != 0 && + peakRepeate >= minRepetition) + { + // + XPVPivot iPivot; + + // + iPivot.lower = 0; + iPivot.upper = peak; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_PEAK; + iPivot.repetition = peakRepeate; + iPivot.to = iTime( + symbol, + period, + peakToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + peakFromBarIndex // + ); + + // + iPivot.lower = iPivot.CalculateLower(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + pivot = iPivot; + break; + } + } + + // + peak = iPeak; + peakRepeate = 0; + peakFromBarIndex = 0; + peakToBarIndex = barIndex; + } + else if (iPeak == peak) + { + // + peakRepeate++; + peakFromBarIndex = barIndex; + } + + // + // Check Vale ... + double iVale = mXPVHelper.GetVale(barIndex); + if (iVale != vale) + { + // + if (vale != 0 && + valeRepeate >= minRepetition) + { + // + XPVPivot iPivot; + + // + iPivot.upper = 0; + iPivot.lower = vale; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_VALE; + iPivot.repetition = valeRepeate; + iPivot.to = iTime( + symbol, + period, + valeToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + valeFromBarIndex // + ); + + // + iPivot.upper = iPivot.CalculateUpper(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + pivot = iPivot; + break; + } + } + + // + vale = iVale; + valeRepeate = 0; + valeFromBarIndex = 0; + valeToBarIndex = barIndex; + } + else if (iVale == vale) + { + // + valeRepeate++; + valeFromBarIndex = barIndex; + } + + // + canLookupPeak = !pivot.IsValid(); + canLookupVale = !pivot.IsValid(); + canLookup = barIndex < end && + (canLookupPeak || + canLookupVale); + if (canLookup) + { + barIndex++; + } + } + + // + result = pivot.IsValid(); + if (result) + { + // + XPVPivot last; + bool hasLastPivot = GetLastPivot(last); + + // + if (hasLastPivot) + { + // + // Check For Pivot Update ... + bool isLastPivotSameAsCurrent = + pivot.IsValid() && + last.IsValid() && + pivot.from == last.from && + pivot.type == last.type; + if (!isLastPivotSameAsCurrent) + { + // + AddRef( + pivot, + pivots // + ); + + // + CleanPivots(); + } + else + { + // + // Update Last Pivot ... + RemoveLastItem(pivots); + + // + pivot.to = TimeCurrent(); + + // + AddRef( + pivot, + pivots // + ); + + // + CleanPivots(); + } + } + else + { + // + // Add New Pivot ... + AddRef( + pivot, + pivots // + ); + + // + CleanPivots(); + } + } + + // + // DetectOrderFlow(); + + // + return result; + } + + /** + * Retriece Last Pivot if Exists ... + * + * @param pivot: XPVPivot instane ... + * + * @return ( bool ) + */ + bool GetLastPivot(XPVPivot &pivot) + { + // + bool result = false; + + // + pivot.Clean(); + + // + int count = ArraySize(pivots); + if (!IsValidSize(count)) + { + return result; + } + + // + result = GetLastItem( + pivot, + pivots // + ); + + // + return result; + } + + /** + * Detect Order Flow ... + * + * @param dir: ENUM_X_DIRECTION member, Hold's Order Flow Direction ... + * @param minPivots: Integer, minimum Required Pivots for Order Flow ... + * + * @return ( bool ) + */ + bool DetectOrderFlow( + ENUM_X_DIRECTION &dir, + int minPivots = 3 // + ) + { + // + bool result = false; + + // + // Normalize Minimum Pivots ... + if (minPivots < 2) + { + minPivots = 2; + } + + // + Clean(orderFlow); + Copy( + pivots, + orderFlow // + ); + + // + // Sort Pivots ... + SortPivots(orderFlow); + + // + // Filter Broken Order Flows ... + FilterBrokenPivots(orderFlow); + + // + int count = ArraySize(orderFlow); + result = IsValidSize(count) && + count >= minPivots; + if (!result) + { + return result; + } + + // + // Detect Order Flow Direction ... + result = DetectPivotDirection( + orderFlow, + dir // + ); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Cleanup Unused Pivots ... + */ + void CleanPivots() + { + // + int required = 10; + int count = ArraySize(pivots); + if (!IsValidSize(count) || count <= required) + { + return; + } + + // + int mustRemove = count - required; + ArrayRemove( + pivots, + 0, + mustRemove // + ); + } + + // + // Virtuals ... + + // + protected: + // + + // + private: + // + // Props ... + XCBarAnalyser *mBarAnalyser; + + // + // Actions ... + + /** + * Release All Resources ... + */ + void DeInit() + { + // + delete mXPVHelper; + delete mX3MAHelper; + delete mX3VWAPHelper; + delete mXCHSARHelper; + + // + delete mBarAnalyser; + } + + /** + * Apply Chart Style ... + */ + void ApplyChartStyle() + { + // + // Retrieve Current Chart ID ... + long chartId = ChartID(); + + // + ENUM_CHART_MODE mMode = CHART_CANDLES; // chart's mMode + bool mShowBidLine = true; // show bid line + bool mShowAskLine = true; // show ask line + bool mShowGrid = false; // show grids on chart + bool mShowVolumes = false; // show volumes + bool mShowTradeLevels = true; // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) + bool mAutoScroll = true; // chart autoscroll + bool mQuickNavigation = true; // chart quick navigation state + color mForeGroundColor = clrWhite; // chart's foreground color + color mBackGroundColor = clrBlack; // chart's background color + color mUpColor = clrGreen; // Up Color + color mDownColor = clrRed; // Down Color + color mBullishColor = clrGreen; // Bullish color + color mBearishColor = clrRed; // Bearish color + color mGridColor = clrGray; // grid color + color mBidLineColor = clrGray; // bid line color + color mAskLineColor = clrRed; // ask line color + color mLineColor = clrLime; // line mMode and doji candlestick color + color mStopColor = clrGold; // Color of stop order levels (Stop Loss and Take Profit) + color mVolumesColor = clrGreen; // volumes color + + // + ChartSetInteger(chartId, CHART_MODE, mMode); + ChartSetInteger(chartId, CHART_SHOW_BID_LINE, mShowBidLine); + ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, mShowAskLine); + ChartSetInteger(chartId, CHART_SHOW_GRID, mShowGrid); + ChartSetInteger(chartId, CHART_SHOW_VOLUMES, mShowVolumes); + ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels); + ChartSetInteger(chartId, CHART_AUTOSCROLL, mAutoScroll); + ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, mQuickNavigation); + ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, mForeGroundColor); + ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, mBackGroundColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_UP, mUpColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, mDownColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, mBullishColor); + ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, mBearishColor); + ChartSetInteger(chartId, CHART_COLOR_GRID, mGridColor); + ChartSetInteger(chartId, CHART_COLOR_BID, mBidLineColor); + ChartSetInteger(chartId, CHART_COLOR_ASK, mAskLineColor); + ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, mStopColor); + ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, mLineColor); + ChartSetInteger(chartId, CHART_COLOR_VOLUME, mVolumesColor); + } + + /** + * Retrieve Symbol ... + * + * @return ( string ) + */ + string GetSymbol() + { + // + string result = NULL; + + // + result = mXPVHelper.GetSymbol(); + + // + return result; + } + + /** + * Retrieve TimeFrame (Period) ... + * + * @return ( ENUM_TIMEFRAMES ) + */ + ENUM_TIMEFRAMES GetPeriod() + { + // + ENUM_TIMEFRAMES result = NULL; + + // + result = mXPVHelper.GetPeriod(); + + // + return result; + } +}; diff --git a/Documents/BKP/x-121.smc.test.strategy.class copy 2.mq5 b/Documents/BKP/x-121.smc.test.strategy.class copy 2.mq5 new file mode 100644 index 00000000..d9966caa --- /dev/null +++ b/Documents/BKP/x-121.smc.test.strategy.class copy 2.mq5 @@ -0,0 +1,2793 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XCX121SMCTestStrategy +// Description: provides all based classes for use ... +// +// +// 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-121.smc.base.strategy.class.mq5" +#include "../Classes/x-121.smc.market.cycle.helper.class.mq5" + +// +// Definitions ... + +// +// XStrategy Class Implementation(s) ... +class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy +{ + // + // Public ... + public: + // + + // + // Constructor(s) ... + void XCX121SMCTestStrategy( + // + // Base ... + string _symbol, // Trading Symbol + ENUM_TIMEFRAMES _period // Trading TimeFrame + ) + : XCX121SMCBaseStrategy(_symbol, _period) + { + InitialHelpers(); + } + + // + // Deconstructur ... + void ~XCX121SMCTestStrategy() + { + } + + // + // Overrides Actions ... + + /** + * Destroy All Class Implementations ... + */ + void Destroy() override + { + // + delete mTriggerCycleHelper; + delete mDecisionCycleHelper; + delete mAnalyseCycleHelper; + delete mVerificationCycleHelper; + delete mConsolidationCycleHelper; + delete mVisionCycleHelper; + } + + /** + * Check Conditions For Signal ... + */ + bool HasSignal( + XSignal &signal, + X121SMCStrategyConditions &conditions // + ) override + { + // + bool result = false; + + // + signal.Clean(); + conditions.Clean(); + + // + int pushers = 0; + + // + double sl = 0; + double tp = 0; + double risk = 0; + double entry = 0; + double reward = 0; + double r2r = R2R(); + string provider = ""; + double volume = Volume(); + ENUM_POSITION_TYPE type = POSITION_TYPE_BUY; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + + // + bool hasLong = false; + bool hasShort = false; + + // + double selectedSL = 0; + + // + // Start Calculations ... + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + double points = GetPoints(symbol); + double pip = GetPipPrice(symbol); + double pip2 = 2 * pip; + + // + // Detect Conditions ... + result = DetectConditions(conditions); + if (!result) + { + conditions.Clean(); + return result; + } + + // + // Check Spread ... + bool isSpreadPassed = IsSpreadPass(); + result = isSpreadPassed; + if (!result) + { + // + // string message = "Spread is not Passed for Analysing ..."; + // LogAlert(message); + + // + return result; + } + + // + // Combine all Signals Conditions ... + selectedSL = conditions.sl; + provider = conditions.provider; + + // + hasLong = + // + IsBullish(conditions.marketStructureDir) + // + ; + + // + hasShort = + // + IsBearish(conditions.marketStructureDir) + // + ; + + // + result = hasLong || + hasShort; + + // + // Rmove Signal Condition ... + if (result) + { + // + // TYPE ... + type = + hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + ENUM_X_POSITION_TYPES xType = + hasLong + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; + + // + entry = GetEntry( + conditions.symbol, + type // + ); + + // + sl = + hasLong + ? selectedSL - pip2 + : selectedSL + pip2; + + // + // RISK Reward ... + risk = + hasLong + ? entry - sl + : sl - entry; + reward = risk * r2r; + tp = + hasLong + ? entry + reward + : entry - reward; + + // + signal.sl = sl; + signal.tp = tp; + signal.type = type; + signal.mode = mode; + signal.entry = entry; + signal.volume = volume; + signal.symbol = symbol; + signal.period = period; + signal.pushers = pushers; + signal.provider = provider; + signal.time = TimeCurrent(); + + // + result = PrepareSignal(signal); + if (result) + { + // + Print("PRV: ", provider); + + // + ENUM_X_DIRECTION forDir = ToDirection(signal.type); + bool ignoreSwingHighs = false; + bool ignoreSwingLows = false; + bool ignoreSupportZones = false; + bool ignoreResistanceZones = false; + bool ignoreSupplyZones = false; + bool ignoreDemandZones = false; + bool ignoreBullishOrderBlocks = false; + bool ignoreBearishOrderBlocks = false; + bool ignoreBullishFairValueGaps = false; + bool ignoreBearishFairValueGaps = false; + bool ignoreBullishRejectionBars = false; + bool ignoreBearishRejectionBars = false; + bool ignoreBullishMomentumBars = false; + bool ignoreBearishMomentumBars = false; + if (IsBullish(forDir)) + { + // + ignoreSwingLows = false; + ignoreDemandZones = false; + ignoreSupportZones = false; + ignoreBullishOrderBlocks = false; + ignoreBullishFairValueGaps = false; + ignoreBullishRejectionBars = false; + ignoreBullishMomentumBars = false; + } + else + { + // + ignoreSwingHighs = true; + ignoreSupplyZones = true; + ignoreResistanceZones = true; + ignoreBearishOrderBlocks = true; + ignoreBearishFairValueGaps = false; + ignoreBearishRejectionBars = true; + ignoreBearishMomentumBars = true; + } + + // + RedrawOrderFlow( + true, // Force Clean ... + false, // Same Period ... + true, // Order Flow ... + true, // Order Flow State ... + false, // Only Last Order Flow ... + true, // Only Last Order Flow State ... + // + forDir, // Direction Force ... + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + DrawSignal(signal); + ClearDraws(); + + // + ResetOrderFlow(); + } + + // + hasLong = false; + hasShort = false; + } + + // + return result; + } + + /** + * Customize Strategy Identifier ... + */ + string GetTag() override + { + return X121SMCStrategyToken; + } + + // + // Protected ... + protected: + // + + // + // Props ... + + // + // Trigger Order Flow ... + XPVPivot mOrderFlow[]; + ENUM_X_DIRECTION mOrderFlowDir; + + // + XC121SMCCycleHelper *mTriggerCycleHelper; + XC121SMCCycleHelper *mDecisionCycleHelper; + XC121SMCCycleHelper *mAnalyseCycleHelper; + XC121SMCCycleHelper *mVerificationCycleHelper; + XC121SMCCycleHelper *mConsolidationCycleHelper; + XC121SMCCycleHelper *mVisionCycleHelper; + + // + // Actions ... + + /** + * Detect and Parse Market Conditions ... + * + * @return ( bool ) + */ + bool DetectConditions( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + string msg = NULL; + + // + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + conditions.time = cTime; + conditions.symbol = symbol; + conditions.period = period; + + // + int conditionsLoopback = 7; + + // + // Fill Cycles Conditions ... + + // + // Trigger ... + mTriggerCycleHelper.GetConditions( + conditions.triggerConditions, + zIndex, + conditionsLoopback // + ); + conditions.triggerConditions.state = mTriggerState; + + // + // Decision ... + mDecisionCycleHelper.GetConditions( + conditions.decisionConditions, + zIndex, + conditionsLoopback // + ); + conditions.decisionConditions.state = mDecisionState; + + // + // Analyse ... + mAnalyseCycleHelper.GetConditions( + conditions.analyseConditions, + zIndex, + conditionsLoopback // + ); + conditions.analyseConditions.state = mAnalyseState; + + // + // Verification ... + mVerificationCycleHelper.GetConditions( + conditions.verificationConditions, + zIndex, + conditionsLoopback // + ); + conditions.verificationConditions.state = mVerificationState; + + // + // Consolidation ... + mConsolidationCycleHelper.GetConditions( + conditions.consolidationConditions, + zIndex, + conditionsLoopback // + ); + conditions.consolidationConditions.state = mConsolidationState; + + // + // Vision ... + mVisionCycleHelper.GetConditions( + conditions.visionConditions, + zIndex, + conditionsLoopback // + ); + conditions.visionConditions.state = mVisionState; + + // + // Detect and Store Parabolic Sar Changes ... + XSarChange sarChange; + bool isSarChanged = mTriggerCycleHelper + .IsSarChanged( + sarChange, + cTime // + ); + + // + // Detect and Store Pivots ... + XPVPivot pivot; + bool isPivotDetected = mTriggerCycleHelper + .DetectPivot(pivot); + if (isPivotDetected) { + // + Print("Pivot Detected ..."); + + // + ClearDraws(); + XCXPVPivotObject *iObj; + iObj = new XCXPVPivotObject(); + bool isCreated = iObj.Create( + mPOIDrawer.ChartIdentification(), + mPOIDrawer.SubWindowIdentification(), + pivot // + ); + if (isCreated) + { + // + if (pivot.IsPeak()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotColor(clrAqua); + iObj.PivotStyle(STYLE_SOLID); + } + + // + if (pivot.IsVale()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotStyle(STYLE_SOLID); + iObj.PivotColor(clrMagenta); + } + + // + AddObjectIfNotExists(iObj); + } + } + + // + if (!result) + { + // + conditions.Clean(); + return result; + } + + // + return result; + } + + /** + * Detect XPV Based POI(s) ... + * + * @param barIndex: Start Bar Index ... + * @param minRepetition: minimum Repeate of POI for Validation ... + * @param requiredPivots: Number of Min Requirement POI(s) ... + * @param pivotHelper: XC121SMCCycleHelper instance Pointer ... + * @param orderFlow: XPVPivot instance Array Reference ... + * @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ... + * @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ... + * + * @return ( bool ) + */ + bool DetectOrderFlow( + int barIndex, + int minRepetition, + int requiredPivots, + XC121SMCCycleHelper *pivotHelper, // XPV Helper ... + XPVPivot &orderFlow[], // OrderFlows ... + ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ... + // + bool useVisionState = true, // Use Vision State ... + bool useConsolidationState = true, // Use Consolidation State ... + bool useVerificationState = true, // Use Verification State ... + bool useAnalyseState = true, // Use Analyse State ... + bool useDecisionState = true, // Use Decision State ... + bool useTriggerState = true, // Use Trigger State ... + // + int maxAllowedLoopbackBars = 576 // + ) + { + // + bool result = false; + + // + orderFlowDirection = X_DIRECTION_NONE; + + // + if (maxAllowedLoopbackBars <= 0) + { + maxAllowedLoopbackBars = 1000; + } + + // + int start = barIndex; + int end = start + maxAllowedLoopbackBars; + + // + Clean(orderFlow); + + // + result = minRepetition > 0 && + requiredPivots > 0 && + pivotHelper != NULL; + if (!result) + { + return result; + } + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + double peak = 0; + XPVPivot peaks[]; + int peakRepeate = 0; + int peakToBarIndex = 0; + int peakFromBarIndex = 0; + + // + double vale = 0; + XPVPivot vales[]; + int valeRepeate = 0; + int valeToBarIndex = 0; + int valeFromBarIndex = 0; + + // + bool canLookupPeak = true; + bool canLookupVale = true; + bool canLookup = true; + while (canLookup) + { + // + // Check Peak ... + double iPeak = pivotHelper.mXPVHelper.GetPeak(barIndex); + if (iPeak != peak) + { + // + if (peak != 0 && + peakRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(peaks); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = peaks[i]; + + // + if (iPivot.upper == iPeak) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.lower = 0; + iPivot.upper = peak; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_PEAK; + iPivot.repetition = peakRepeate; + iPivot.to = iTime( + symbol, + period, + peakToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + peakFromBarIndex // + ); + + // + iPivot.lower = iPivot.CalculateLower(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + peaks // + ); + } + } + } + + // + peak = iPeak; + peakRepeate = 0; + peakFromBarIndex = 0; + peakToBarIndex = barIndex; + } + else if (iPeak == peak) + { + // + peakRepeate++; + peakFromBarIndex = barIndex; + } + + // + // Check Vale ... + double iVale = pivotHelper.mXPVHelper.GetVale(barIndex); + if (iVale != vale) + { + // + if (vale != 0 && + valeRepeate >= minRepetition) + { + // + bool isExists = false; + int count = ArraySize(vales); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XPVPivot iPivot = vales[i]; + + // + if (iPivot.lower == iVale) + { + // + isExists = true; + break; + } + } + } + if (!isExists) + { + // + XPVPivot iPivot; + + // + iPivot.upper = 0; + iPivot.lower = vale; + iPivot.symbol = symbol; + iPivot.period = period; + iPivot.type = XPV_VALE; + iPivot.repetition = valeRepeate; + iPivot.to = iTime( + symbol, + period, + valeToBarIndex // + ); + iPivot.from = iTime( + symbol, + period, + valeFromBarIndex // + ); + + // + iPivot.upper = iPivot.CalculateUpper(); + + // + bool isValid = iPivot.IsValid(); + if (isValid) + { + // + AddRef( + iPivot, + vales // + ); + } + } + } + + // + vale = iVale; + valeRepeate = 0; + valeFromBarIndex = 0; + valeToBarIndex = barIndex; + } + else if (iVale == vale) + { + // + valeRepeate++; + valeFromBarIndex = barIndex; + } + + // + canLookupPeak = ArraySize(peaks) < requiredPivots; + canLookupVale = ArraySize(vales) < requiredPivots; + canLookup = barIndex < end && + (canLookupPeak || + canLookupVale); + if (canLookup) + { + barIndex++; + } + } + + // + result = IsValidSize(ArraySize(peaks)) || + IsValidSize(ArraySize(vales)); + if (!result) + { + return result; + } + + // + // Detect Order Flow ... + Copy( + peaks, + orderFlow, + false // + ); + Copy( + vales, + orderFlow, + false // + ); + int count = ArraySize(orderFlow); + result = IsValidSize(orderFlow); + if (!result) + { + return result; + } + + // + // Sort Pivots ... + SortPivots(orderFlow); + + // + // Filter Broken Order Flows ... + FilterBrokenPivots(orderFlow); + + // + // Detect Order Flow Direction ... + result = DetectPivotDirection( + orderFlow, + orderFlowDirection // + ); + if (!result) + { + return result; + } + + // + // Find State Inside Pivots and Attached Them to Pivot ... + int orderFlowCount = ArraySize(mOrderFlow); + if (IsValidSize(orderFlowCount)) + { + // + // Loop Through Order Flow ... + for (int i = 0; i < orderFlowCount; i++) + { + // + FillPivotSate( + i, + useVisionState, // Use Vision State ... + useConsolidationState, // Use Consolidation State ... + useVerificationState, // Use Verification State ... + useAnalyseState, // Use Analyse State ... + useDecisionState, // Use Decision State ... + useTriggerState // Use Trigger State ... + ); + } + } + + // + return result; + } + + /** + * Filling Specified Orer Flow Index ... + * + * @param pivotIDX: Integer ... + * @param lookupSwingHighs: Boolean ... + * @param lookupSwingLows: Boolean ... + * @param lookupSupportZones: Boolean ... + * @param lookupResistanceZones: Boolean ... + * @param lookupSupplyZones: Boolean ... + * @param lookupDemandZones: Boolean ... + * @param lookupBullishOrderBlocks: Boolean ... + * @param lookupBearishOrderBlocks: Boolean ... + * @param lookupBullishFairValueGaps: Boolean ... + * @param lookupBearishFairValueGaps: Boolean ... + * @param lookupBullishRejectionBars: Boolean ... + * @param lookupBearishRejectionBars: Boolean ... + * @param lookupBullishMomentumBars: Boolean ... + * @param lookupBearishMomentumBars: Boolean ... + */ + void FillPivotSate( + int pivotIDX, // + bool useVisionState = true, // Use Vision State ... + bool useConsolidationState = true, // Use Consolidation State ... + bool useVerificationState = true, // Use Verification State ... + bool useAnalyseState = true, // Use Analyse State ... + bool useDecisionState = true, // Use Decision State ... + bool useTriggerState = true, // Use Trigger State ... + bool lookupSwingHighs = true, + bool lookupSwingLows = true, + bool lookupSupportZones = true, + bool lookupResistanceZones = true, + bool lookupSupplyZones = true, + bool lookupDemandZones = true, + bool lookupBullishOrderBlocks = true, + bool lookupBearishOrderBlocks = true, + bool lookupBullishFairValueGaps = true, + bool lookupBearishFairValueGaps = true, + bool lookupBullishRejectionBars = true, + bool lookupBearishRejectionBars = true, + bool lookupBullishMomentumBars = true, + bool lookupBearishMomentumBars = true // + ) + { + // + CalculatePivotTickZone(pivotIDX); + + // + // Trigger ... + XPOIState mPivotTriggerState; + if (useTriggerState && + mTriggerState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mTriggerState, + mPivotTriggerState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotTriggerState.HasChild()) + { + mPivotTriggerState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Decision ... + XPOIState mPivotDecisionState; + if (useDecisionState && + mDecisionState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mDecisionState, + mPivotDecisionState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotDecisionState.HasChild()) + { + mPivotDecisionState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Analyse ... + XPOIState mPivotAnalyseState; + if (useAnalyseState && + mAnalyseState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mAnalyseState, + mPivotAnalyseState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotAnalyseState.HasChild()) + { + mPivotAnalyseState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Verification ... + XPOIState mPivotVerificationState; + if (useVerificationState && + mVerificationState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mVerificationState, + mPivotVerificationState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotVerificationState.HasChild()) + { + mPivotVerificationState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Consolidation ... + XPOIState mPivotConsolidationState; + if (useConsolidationState && + mConsolidationState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mConsolidationState, + mPivotConsolidationState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotConsolidationState.HasChild()) + { + mPivotConsolidationState.Fill(mOrderFlow[pivotIDX].state); + } + } + + // + // Vision ... + XPOIState mPivotVisionState; + if (useVisionState && + mVisionState.HasChild()) + { + // + DetectPivotPOIs( + mOrderFlow[pivotIDX], + mVisionState, + mPivotVisionState, + lookupSwingHighs, + lookupSwingLows, + lookupSupportZones, + lookupResistanceZones, + lookupSupplyZones, + lookupDemandZones, + lookupBullishOrderBlocks, + lookupBearishOrderBlocks, + lookupBullishFairValueGaps, + lookupBearishFairValueGaps, + lookupBullishRejectionBars, + lookupBearishRejectionBars, + lookupBullishMomentumBars, + lookupBearishMomentumBars // + ); + + // + if (mPivotVisionState.HasChild()) + { + mPivotVisionState.Fill(mOrderFlow[pivotIDX].state); + } + } + } + + /** + * When a BOS Happens ... + * we have to Update Order Flow ... + */ + void UpdateOrderFlow() + { + ResetOrderFlow(); + } + + /** + * Fill Pivot Tick Zone ... + * + * @param pivotIDX: Integer ... + */ + void CalculatePivotTickZone(int pivotIDX) + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + bool isInited = false; + + // + datetime from = mOrderFlow[pivotIDX].from; + XOHCL iFromBar; + int iFromBarIndex = iBarShift( + symbol, + period, + from // + ); + isInited = iFromBar.Init( + symbol, + period, + iFromBarIndex // + ); + if (!isInited) + { + return; + } + + // + datetime to = mOrderFlow[pivotIDX].to; + XOHCL iToBar; + int iToBarIndex = iBarShift( + symbol, + period, + to // + ); + isInited = iToBar.Init( + symbol, + period, + iToBarIndex // + ); + if (!isInited) + { + return; + } + + // + XCTicksZone *iZone; + iZone = new XCTicksZone(); + + // + int ticksLevels = mTriggerDetector.TicksRangeZoneLevel(); + int ticksRange = mTriggerDetector.TicksRangeZoneRange(); + isInited = ticksLevels > 0 && + ticksRange > 0; + if (!isInited) + { + return; + } + + // + isInited = iZone.Init( + iFromBar, + iToBar // + ); + if (!isInited) + { + return; + } + + // + mOrderFlow[pivotIDX].state.ticksZone = iZone; + } + + /** + * Validate Order Flow ... + * + * @return ( bool ) + */ + bool HasValidOrderFlow() + { + // + bool result = false; + + // + int orderFlowCount = ArraySize(mOrderFlow); + result = + IsValidSize(orderFlowCount) && + mOrderFlowDir != X_DIRECTION_ALL && + mOrderFlowDir != X_DIRECTION_NONE; + + // + return result; + } + + /** + * Reset Order Flow ... + */ + void ResetOrderFlow() + { + // + Clean(mOrderFlow); + mOrderFlowDir = X_DIRECTION_NONE; + + // + ClearDraws(); + } + + /** + * Detect Breaker Bar ... + * + * @param bar: XOHCL instance ... + * @param breakerBar: XOHCL instance, Breaker Bar ... + * @param pivot: XPVPivot instance ... + * @param forDir: ENUM_X_DIRECTION member, Market Structure Direction ... + * + * @return ( bool ) + */ + bool DetectLastBreakerBar( + XOHCL &bar, + XOHCL &breakerBar, + XPVPivot &pivot, + ENUM_X_DIRECTION forDir // + ) + { + // + bool result = false; + + // + result = + bar.IsValid() && + pivot.IsValid() && + forDir != X_DIRECTION_ALL && + forDir != X_DIRECTION_NONE; + if (!result) + { + return result; + } + + // + // FVG ... + result = DetectLastFVGBreakerBar( + bar, + breakerBar, + pivot, + forDir // + ); + if (result) + { + return result; + } + + // + // Order Block ... + // result = DetectLastOBBreakerBar( + // bar, + // breakerBar, + // pivot, + // forDir // + // ); + // if (result) + // { + // return result; + // } + + // + return result; + } + + bool DetectLastFVGBreakerBar( + XOHCL &bar, + XOHCL &breakerBar, + XPVPivot &pivot, + ENUM_X_DIRECTION forDir // + ) + { + // + bool result = false; + + // + result = + bar.IsValid() && + pivot.IsValid() && + forDir != X_DIRECTION_ALL && + forDir != X_DIRECTION_NONE; + if (!result) + { + return result; + } + + // + bool isBullishDir = IsBullish(forDir); + + // + int fvgsCount = + isBullishDir + ? pivot.state.CountBullishFairValueGaps() + : pivot.state.CountBearishFairValueGaps(); + result = IsValidSize(fvgsCount); + if (!result) + { + return result; + } + + // + int idx = -1; + XCFVG *zone = NULL; + for (int i = 0; i < fvgsCount; i++) + { + // + if (isBullishDir) + { + // + // Bullish FVG ... + if (zone == NULL) + { + // + zone = pivot.state.bullishFairValueGaps[i]; + + // + bool isBreaked = CheckZoneBreak( + forDir, + bar, + breakerBar, + zone // + ); + if (isBreaked) + { + idx = i; + } + } + else + { + // + bool isNewer = ((int)zone.From() - (int)bar.time) > ((int)pivot.state.bullishFairValueGaps[i].From() - (int)bar.time); + if (isNewer) + { + // + zone = pivot.state.bullishFairValueGaps[i]; + + // + bool isBreaked = CheckZoneBreak( + forDir, + bar, + breakerBar, + zone // + ); + if (isBreaked) + { + idx = i; + } + } + } + } + else + { + // + // Bearish FVG ... + if (zone == NULL) + { + // + zone = pivot.state.bearishFairValueGaps[i]; + + // + bool isBreaked = CheckZoneBreak( + forDir, + bar, + breakerBar, + zone // + ); + if (isBreaked) + { + idx = i; + } + } + else + { + // + bool isNewer = ((int)zone.From() - (int)bar.time) > ((int)pivot.state.bearishFairValueGaps[i].From() - (int)bar.time); + if (isNewer) + { + // + zone = pivot.state.bearishFairValueGaps[i]; + + // + bool isBreaked = CheckZoneBreak( + forDir, + bar, + breakerBar, + zone // + ); + if (isBreaked) + { + idx = i; + } + } + } + } + } + + // + result = + breakerBar.IsValid() && + IsValidIndex(idx) && + zone.IsValid(); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Check an FVG is Breaked or not ... + * + * @param forDir: ENUM_X_DIRECTION member, Market Structure Direction ... + * @param bar: XOHCL instance ... + * @param breakerBar: XOHCL instance, Breaker Bar ... + * + * @return ( bool ) + */ + bool CheckZoneBreak( + ENUM_X_DIRECTION forDir, + XOHCL &bar, + XOHCL &breakerBar, + XCFVG *&zone // + ) + { + // + bool result = false; + + // + breakerBar.Clean(); + + // + result = bar.IsValid() && + zone.IsValid() && + forDir != X_DIRECTION_ALL && + forDir != X_DIRECTION_NONE; + if (!result) + { + return result; + } + + // + int start = bar.Index(); + int end = iBarShift( + bar.symbol, + bar.period, + zone.From()); + for (int i = start; i < end; i++) + { + // + XOHCL iBar; + result = iBar.Init( + bar.symbol, + bar.period, + i // + ); + if (!result) + { + break; + } + + // + if (IsBullish(forDir)) + { + // + // Bullish Break ... + result = iBar.low < zone.Upper() && + iBar.high > zone.Upper() && + iBar.GetDown() < zone.Upper() && + iBar.GetUp() > zone.Upper() && + iBar.IsBullish(); + } + else + { + // + // Bearish Break ... + result = iBar.low < zone.Lower() && + iBar.high > zone.Lower() && + iBar.GetDown() < zone.Lower() && + iBar.GetUp() > zone.Lower() && + iBar.IsBearish(); + } + + // + if (result) + { + // + breakerBar = iBar; + break; + } + } + + // + result = breakerBar.IsValid(); + + // + return result; + } + + /** + * Detect most Upper and Lower Order Blocks ... + * + * @return ( bool ) + */ + bool DetectOrderBlocks( + XCOrderBlock *bullOBBoundary, + XCOrderBlock *bearOBBoundary, + XCOrderBlock *&bullOB, + XCOrderBlock *&bearOB, + XOHCL &bar, + XPOIState &state // + ) + { + // + bool result = false; + + // + result = bar.IsValid() && + state.IsValid(); + if (!result) + { + return result; + } + + // + XCOrderBlock *mBullOB = NULL; + if (bullOB == NULL) + { + // + for (int i = 0; i < state.CountBullishOrderBlocks(); i++) + { + // + XCOrderBlock *ob = state.bullishOrderBlocks[i]; + bool isPricePassed = bar.low > ob.Upper(); + if (isPricePassed) + { + // + bool isBoundaryPassed = + bullOBBoundary == NULL + ? true + : ob.Lower() < bullOBBoundary.Upper(); + if (isBoundaryPassed) + { + // + if (mBullOB == NULL) + { + mBullOB = ob; + } + else + { + // + bool isRefined = + mBullOB.Upper() < ob.Upper(); + if (isRefined) + { + mBullOB = ob; + } + } + } + } + } + + // + if (mBullOB != NULL) + { + bullOB = mBullOB; + } + } + + // + XCOrderBlock *mBearOB = NULL; + if (bearOB == NULL) + { + // + for (int i = 0; i < state.CountBearishOrderBlocks(); i++) + { + // + XCOrderBlock *ob = state.bearishOrderBlocks[i]; + bool isPricePassed = bar.high < ob.Lower(); + if (isPricePassed) + { + // + bool isBoundaryPassed = + bearOBBoundary == NULL + ? true + : ob.Upper() > bearOBBoundary.Lower(); + if (isBoundaryPassed) + { + // + if (mBearOB == NULL) + { + mBearOB = ob; + } + else + { + // + bool isRefined = + mBearOB.Lower() > ob.Lower(); + if (isRefined) + { + mBearOB = ob; + } + } + } + } + } + + // + if (mBearOB != NULL) + { + bearOB = mBearOB; + } + } + + // + result = bullOB != NULL && + bearOB != NULL; + + // + return result; + } + + // + // Drawings ... + + /** + * Draw Order Flow ... + */ + void RedrawOrderFlow( + bool forceClearDraws = true, + bool forceDrawSamePeriod = true, + bool drawOrderFlow = true, + bool drawOrderFlowState = true, + bool drawOnlyLastOrderFlow = false, + bool drawOnlyLastOrderFlowState = true, + // + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + // + // Ignores List ... + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false, + // + // States Drawing ... + bool drawVisionState = false, + bool drawConsolidationState = false, + bool drawVerificationState = false, + bool drawAnalyseState = false, + bool drawDecisionState = false, + bool drawTriggerState = false // + ) + { + // + if (forceClearDraws) + { + ClearDraws(); + } + + // + if (!drawOrderFlow || + !HasValidOrderFlow()) + { + return; + } + + // + int orderFlowCount = ArraySize(mOrderFlow); + for (int i = 0; i < orderFlowCount; i++) + { + // + bool isLast = i == orderFlowCount - 1; + bool canDraw = + !drawOnlyLastOrderFlow || + (isLast && + drawOnlyLastOrderFlow); + if (!canDraw) + { + continue; + } + + // + XPVPivot iPivot = mOrderFlow[i]; + + // + XCXPVPivotObject *iObj; + iObj = new XCXPVPivotObject(); + bool isCreated = iObj.Create( + mPOIDrawer.ChartIdentification(), + mPOIDrawer.SubWindowIdentification(), + iPivot // + ); + if (isCreated) + { + // + bool canDrawState = + drawOrderFlowState && + (!drawOnlyLastOrderFlowState || + (isLast && + drawOnlyLastOrderFlowState)); + if (canDrawState) + { + // + CustomStateDrawing( + iPivot.state, + forceDrawSamePeriod, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + if (iPivot.IsPeak()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotColor(clrAqua); + iObj.PivotStyle(STYLE_SOLID); + } + + // + if (iPivot.IsVale()) + { + // + iObj.PivotWidth(1); + iObj.PivotFill(false); + iObj.PivotStyle(STYLE_SOLID); + iObj.PivotColor(clrMagenta); + } + + // + AddObjectIfNotExists(iObj); + } + } + + // + // Draw States ... + + // + // Vision ... + if (drawVisionState) + { + // + CustomStateDrawing( + mVisionState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Consolidation ... + if (drawConsolidationState) + { + // + CustomStateDrawing( + mConsolidationState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Verification ... + if (drawVerificationState) + { + // + CustomStateDrawing( + mVerificationState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Analyse ... + if (drawAnalyseState) + { + // + CustomStateDrawing( + mAnalyseState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Decision ... + if (drawDecisionState) + { + // + CustomStateDrawing( + mDecisionState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + + // + // Trigger ... + if (drawTriggerState) + { + // + CustomStateDrawing( + mTriggerState, + false, + forDir, + ignoreSwingHighs, + ignoreSwingLows, + ignoreSupportZones, + ignoreResistanceZones, + ignoreSupplyZones, + ignoreDemandZones, + ignoreBullishOrderBlocks, + ignoreBearishOrderBlocks, + ignoreBullishFairValueGaps, + ignoreBearishFairValueGaps, + ignoreBullishRejectionBars, + ignoreBearishRejectionBars, + ignoreBullishMomentumBars, + ignoreBearishMomentumBars // + ); + } + } + + /** + * Custom Drawing State ... + * + * @param state: XPOIState instance reference, Specified Which state to Draw ... + * @param forceDrawSamePeriod: Boolean ... + */ + void CustomStateDrawing( + XPOIState &state, + bool forceDrawSamePeriod = false, + ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, + // + // Ignores List ... + bool ignoreSwingHighs = false, + bool ignoreSwingLows = false, + bool ignoreSupportZones = false, + bool ignoreResistanceZones = false, + bool ignoreSupplyZones = false, + bool ignoreDemandZones = false, + bool ignoreBullishOrderBlocks = false, + bool ignoreBearishOrderBlocks = false, + bool ignoreBullishFairValueGaps = false, + bool ignoreBearishFairValueGaps = false, + bool ignoreBullishRejectionBars = false, + bool ignoreBearishRejectionBars = false, + bool ignoreBullishMomentumBars = false, + bool ignoreBearishMomentumBars = false // + ) + { + // + XPOIState tmpState = state; + if (forceDrawSamePeriod) + { + // + int count = 0; + ENUM_TIMEFRAMES period = GetPeriod(); + + // + count = state.CountSwingHighs(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingHighs[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingHighs, + i, + 1 // + ); + } + } + } + + // + count = state.CountSwingLows(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSwing iSwing = state.swingLows[i]; + + // + XOHCL iBar; + bool isFilled = iSwing.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.swingLows, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishMomentumBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCMomentumBar iMomentum = state.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishMomentumBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bullishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishRejectionBars(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCRejectionBar iRejection = state.bearishRejectionBars[i]; + + // + XOHCL iBar; + bool isFilled = iRejection.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishRejectionBars, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupportZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupportZone iZone = state.supportZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supportZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountResistanceZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCResistanceZone iZone = state.resistanceZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.resistanceZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountSupplyZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCSupplyZone iZone = state.supplyZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.supplyZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountDemandZones(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCDemandZone iZone = state.demandZones[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.demandZones, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bullishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishOrderBlocks(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCOrderBlock iZone = state.bearishOrderBlocks[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishOrderBlocks, + i, + 1 // + ); + } + } + } + + // + count = state.CountBullishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bullishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bullishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + count = state.CountBearishFairValueGaps(); + if (IsValidSize(count)) + { + // + for (int i = 0; i < count; i++) + { + // + XCFVG iZone = state.bearishFairValueGaps[i]; + + // + XOHCL iBar; + bool isFilled = iZone.FillStartBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isSamePeriod = iBar.period == period; + if (!isSamePeriod) + { + // + ArrayRemove( + tmpState.bearishFairValueGaps, + i, + 1 // + ); + } + } + } + + // + } + + // + bool drawSwingHighs = true; + bool drawSwingLows = true; + bool drawSupportZones = true; + bool drawResistanceZones = true; + bool drawSupplyZones = true; + bool drawDemandZones = true; + bool drawBullishOrderBlocks = true; + bool drawBearishOrderBlocks = true; + bool drawBullishFairValueGaps = true; + bool drawBearishFairValueGaps = true; + bool drawBullishRejectionBars = true; + bool drawBearishRejectionBars = true; + bool drawBullishMomentumBars = true; + bool drawBearishMomentumBars = true; + + // + // Change Drawing Specs Conditions based on + // Provided Direction ... + if (forDir == X_DIRECTION_BULLISH) + { + // + drawSwingLows = true; + drawDemandZones = true; + drawSupportZones = true; + drawBullishOrderBlocks = true; + drawBullishFairValueGaps = true; + drawBullishRejectionBars = true; + drawBullishMomentumBars = true; + + // + drawSwingHighs = false; + drawSupplyZones = false; + drawResistanceZones = false; + drawBearishOrderBlocks = false; + drawBearishFairValueGaps = false; + drawBearishRejectionBars = false; + drawBearishMomentumBars = false; + } + else if (forDir == X_DIRECTION_BEARISH) + { + // + drawSwingLows = false; + drawDemandZones = false; + drawSupportZones = false; + drawBullishOrderBlocks = false; + drawBullishFairValueGaps = false; + drawBullishRejectionBars = false; + drawBullishMomentumBars = false; + + // + drawSwingHighs = true; + drawSupplyZones = true; + drawResistanceZones = true; + drawBearishOrderBlocks = true; + drawBearishFairValueGaps = true; + drawBearishRejectionBars = true; + drawBearishMomentumBars = true; + } + + // + // Apply Ignore List ... + + // + if (ignoreSwingHighs) + { + drawSwingHighs = false; + } + + // + if (ignoreSwingLows) + { + drawSwingLows = false; + } + + // + if (ignoreSupportZones) + { + drawSupportZones = false; + } + + // + if (ignoreResistanceZones) + { + drawResistanceZones = false; + } + + // + if (ignoreSupplyZones) + { + drawSupplyZones = false; + } + + // + if (ignoreDemandZones) + { + drawDemandZones = false; + } + + // + if (ignoreBullishOrderBlocks) + { + drawBullishOrderBlocks = false; + } + + // + if (ignoreBearishOrderBlocks) + { + drawBearishOrderBlocks = false; + } + + // + if (ignoreBullishFairValueGaps) + { + drawBullishFairValueGaps = false; + } + + // + if (ignoreBearishFairValueGaps) + { + drawBearishFairValueGaps = false; + } + + // + if (ignoreBullishRejectionBars) + { + drawBullishRejectionBars = false; + } + + // + if (ignoreBearishRejectionBars) + { + drawBearishRejectionBars = false; + } + + // + if (ignoreBullishMomentumBars) + { + drawBullishMomentumBars = false; + } + + // + if (ignoreBearishMomentumBars) + { + drawBearishMomentumBars = false; + } + + // + DrawState( + tmpState, // State ... + true, // Update To of all Drawings Till now ... + drawSwingHighs, // Draw SwingHighs .. + drawSwingLows, // Draw SwingLows .. + drawSupportZones, // Draw SupportZones .. + drawResistanceZones, // Draw ResistanceZones .. + drawSupplyZones, // Draw SupplyZones .. + drawDemandZones, // Draw DemandZones .. + drawBullishOrderBlocks, // Draw BullishOrderBlocks .. + drawBearishOrderBlocks, // Draw BearishOrderBlocks .. + drawBullishFairValueGaps, // Draw BullishFairValueGaps .. + drawBearishFairValueGaps, // Draw BearishFairValueGaps .. + drawBullishRejectionBars, // Draw BullishRejectionBars .. + drawBearishRejectionBars, // Draw BearishRejectionBars .. + drawBullishMomentumBars, // Draw BullishMomentumBars .. + drawBearishMomentumBars, // Draw BearishMomentumBars .. + true // Draw Ticks Zone ... + ); + } + + // + // Private ... + private: + // + // Props ... + + /** + * Initial Required Indicators Helper ... + */ + void InitialHelpers() + { + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + // Short ... + ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + + // + // Medium ... + ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + + // + // Long ... + ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + + // + // Hind ... + ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period + ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + + // + // XPV ... + XPVInputs xpvInputs; + + // + xpvInputs.Default(); + + // + xpvInputs.scMethod = scMethod; + xpvInputs.scPeriod = scPeriod; + xpvInputs.mcMethod = mcMethod; + xpvInputs.mcPeriod = mcPeriod; + xpvInputs.lcMethod = lcMethod; + xpvInputs.lcPeriod = lcPeriod; + xpvInputs.hcMethod = hcMethod; + xpvInputs.hcPeriod = hcPeriod; + + // + xpvInputs.showPeaksAndVales = true; + xpvInputs.showLevels = false; + xpvInputs.showConsolidations = false; + xpvInputs.showFibo1Levels = false; + xpvInputs.showFibo2Levels = false; + xpvInputs.showFibo3Levels = false; + xpvInputs.showFibo4Levels = false; + xpvInputs.showFibo5Levels = false; + + // + // X3MA ... + X3MAInputs x3maInputs; + + // + x3maInputs.Default(); + + // + // x3maInputs.fastLength = 10; + // x3maInputs.midLength = 25; + // x3maInputs.slowLength = 50; + + // + x3maInputs.showFast = true; + x3maInputs.showMid = false; + x3maInputs.showSlow = false; + + // + // X3VWAP ... + X3VWAPInputs x3vwapInputs; + + // + x3vwapInputs.Default(); + + // + // x3vwapInputs.fastLength = 10; + // x3vwapInputs.midLength = 25; + // x3vwapInputs.slowLength = 50; + + // + x3vwapInputs.showFast = true; + x3vwapInputs.showMid = true; + x3vwapInputs.showSlow = true; + + // + // XCHSAR ... + XCHSARInputs xchsarInputs; + + // + xchsarInputs.Default(); + + // + xchsarInputs.scMethod = scMethod; + xchsarInputs.scPeriod = scPeriod; + xchsarInputs.mcMethod = mcMethod; + xchsarInputs.mcPeriod = mcPeriod; + xchsarInputs.lcMethod = lcMethod; + xchsarInputs.lcPeriod = lcPeriod; + xchsarInputs.hcMethod = hcMethod; + xchsarInputs.hcPeriod = hcPeriod; + + // + xchsarInputs.showCurrent = true; + xchsarInputs.showShort = false; + xchsarInputs.showMedium = false; + xchsarInputs.showLong = false; + xchsarInputs.showHind = false; + + // + // Initialize Cycle Helpers ... + + // + mTriggerCycleHelper = new XC121SMCCycleHelper(); + mTriggerCycleHelper.Init( + symbol, + PERIOD_M1, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mDecisionCycleHelper = new XC121SMCCycleHelper(); + mDecisionCycleHelper.Init( + symbol, + PERIOD_M5, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mAnalyseCycleHelper = new XC121SMCCycleHelper(); + mAnalyseCycleHelper.Init( + symbol, + PERIOD_M15, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mVerificationCycleHelper = new XC121SMCCycleHelper(); + mVerificationCycleHelper.Init( + symbol, + PERIOD_M30, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mConsolidationCycleHelper = new XC121SMCCycleHelper(); + mConsolidationCycleHelper.Init( + symbol, + PERIOD_H1, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + + // + mVisionCycleHelper = new XC121SMCCycleHelper(); + mVisionCycleHelper.Init( + symbol, + PERIOD_H4, + xpvInputs, + x3maInputs, + x3vwapInputs, + xchsarInputs // + ); + } + + // +}; + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index 94c31a9c..46fdce61 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -76,6 +76,15 @@ enum ENUM_X121_BUFFERS X121_VALID_VALES_LINE = 38, }; +// +enum ENUM_XVWAP_STATES +{ + // + XVWAP_STATE_BULLISH = 1, + XVWAP_STATE_BEARISH = 2, + XVWAP_STATE_NEUTURAL = 3, +}; + // // Inputs ... struct X121Inputs @@ -507,6 +516,114 @@ struct X121Conditions double validPeaksBuffer[]; double validValesBuffer[]; + // + // Conditions ... + + // + // XSAR ... + + // + bool isSarBullish; + bool isSarBearish; + + // + bool isSarSwitchedBullish; + bool isSarSwitchedBearish; + + // + // XPV ... + + // + bool isNewPeak; + bool isNewPeakOverLast; + bool isNewPeakUnderLast; + + // + bool isNewVale; + bool isNewValeOverLast; + bool isNewValeUnderLast; + + // + // XVWAP ... + + // + bool isVWapFastBullish; + bool isVWapFastBearish; + bool isVWapFastNeutural; + + // + bool isVWapMidBullish; + bool isVWapMidBearish; + bool isVWapMidNeutural; + + // + bool isVWapSlowBullish; + bool isVWapSlowBearish; + bool isVWapSlowNeutural; + + // + bool isVWapFastOverMid; + bool isVWapMidOverSlow; + + // + bool isVWapFastUnderMid; + bool isVWapMidUnderSlow; + + // + bool isVWapBullishState; + bool isVWapBearishState; + bool isVWapNeuturalState; + + // + bool isVWapBullishOrdered; + bool isVWapBearishOrdered; + + // + bool isVWapSwitchedToBullishOrdered; + bool isVWapSwitchedToBearishOrdered; + + // + bool isVWapSwitchedToBullishState; + bool isVWapSwitchedToBearishState; + bool isVWapSwitchedToNeuturalState; + + // + // XDON ... + + // + // bool isCloseLower + + // + // XFIBONACCI ... + + // + bool isOerFib1; + bool isOerFib2; + bool isOerFib3; + bool isOerFib4; + bool isOerFib5; + + // + bool isUnderFib1; + bool isUnderFib2; + bool isUnderFib3; + bool isUnderFib4; + bool isUnderFib5; + + // + bool isCloseOerFib1; + bool isCloseOerFib2; + bool isCloseOerFib3; + bool isCloseOerFib4; + bool isCloseOerFib5; + + // + bool isCloseUnderFib1; + bool isCloseUnderFib2; + bool isCloseUnderFib3; + bool isCloseUnderFib4; + bool isCloseUnderFib5; + // // Constructor ... X121Conditions() @@ -606,6 +723,111 @@ struct X121Conditions ArraySetAsSeries(vwapSlowStateBuffer, true); ArraySetAsSeries(validPeaksBuffer, true); ArraySetAsSeries(validValesBuffer, true); + + // + // Conditions ... + + // + // XSAR ... + + // + isSarBullish = false; + isSarBearish = false; + + // + isSarSwitchedBullish = false; + isSarSwitchedBearish = false; + + // + // XPV ... + + // + isNewPeak = false; + isNewPeakOverLast = false; + isNewPeakUnderLast = false; + + // + isNewVale = false; + isNewValeOverLast = false; + isNewValeUnderLast = false; + + // + // XVWAP ... + + // + isVWapFastBullish = false; + isVWapFastBearish = false; + isVWapFastNeutural = false; + + // + isVWapMidBullish = false; + isVWapMidBearish = false; + isVWapMidNeutural = false; + + // + isVWapSlowBullish = false; + isVWapSlowBearish = false; + isVWapSlowNeutural = false; + + // + isVWapFastOverMid = false; + isVWapMidOverSlow = false; + + // + isVWapFastUnderMid = false; + isVWapMidUnderSlow = false; + + // + isVWapBullishState = false; + isVWapBearishState = false; + isVWapNeuturalState = false; + + // + isVWapBullishOrdered = false; + isVWapBearishOrdered = false; + + // + isVWapSwitchedToBullishOrdered = false; + isVWapSwitchedToBearishOrdered = false; + + // + isVWapSwitchedToBullishState = false; + isVWapSwitchedToBearishState = false; + isVWapSwitchedToNeuturalState = false; + + // + // XDON ... + + // + // XFIBONACCI ... + + // + isOerFib1 = false; + isOerFib2 = false; + isOerFib3 = false; + isOerFib4 = false; + isOerFib5 = false; + + // + isUnderFib1 = false; + isUnderFib2 = false; + isUnderFib3 = false; + isUnderFib4 = false; + isUnderFib5 = false; + + // + isCloseOerFib1 = false; + isCloseOerFib2 = false; + isCloseOerFib3 = false; + isCloseOerFib4 = false; + isCloseOerFib5 = false; + + // + isCloseUnderFib1 = false; + isCloseUnderFib2 = false; + isCloseUnderFib3 = false; + isCloseUnderFib4 = false; + isCloseUnderFib5 = false; } /** @@ -677,7 +899,72 @@ struct X121Conditions // // TODO: Implement this if required ... - string conditionsStr = ""; + string conditionsStr = + // + // XSAR ... + ToString("isSarBullish", isSarBullish, ignoreFalseConditions, separator) + + ToString("isSarBearish", isSarBearish, ignoreFalseConditions, separator) + + ToString("isSarSwitchedBullish", isSarSwitchedBullish, ignoreFalseConditions, separator) + + ToString("isSarSwitchedBearish", isSarSwitchedBearish, ignoreFalseConditions, separator) + + // + // XPV ... + ToString("isNewPeak", isNewPeak, ignoreFalseConditions, separator) + + ToString("isNewPeakOverLast", isNewPeakOverLast, ignoreFalseConditions, separator) + + ToString("isNewPeakUnderLast", isNewPeakUnderLast, ignoreFalseConditions, separator) + + ToString("isNewVale", isNewVale, ignoreFalseConditions, separator) + + ToString("isNewValeOverLast", isNewValeOverLast, ignoreFalseConditions, separator) + + ToString("isNewValeUnderLast", isNewValeUnderLast, ignoreFalseConditions, separator) + + // + // XVWAP ... + ToString("isVWapFastBullish", isVWapFastBullish, ignoreFalseConditions, separator) + + ToString("isVWapFastBearish", isVWapFastBearish, ignoreFalseConditions, separator) + + ToString("isVWapFastNeutural", isVWapFastNeutural, ignoreFalseConditions, separator) + + ToString("isVWapMidBullish", isVWapMidBullish, ignoreFalseConditions, separator) + + ToString("isVWapMidBearish", isVWapMidBearish, ignoreFalseConditions, separator) + + ToString("isVWapMidNeutural", isVWapMidNeutural, ignoreFalseConditions, separator) + + ToString("isVWapSlowBullish", isVWapSlowBullish, ignoreFalseConditions, separator) + + ToString("isVWapSlowBearish", isVWapSlowBearish, ignoreFalseConditions, separator) + + ToString("isVWapSlowNeutural", isVWapSlowNeutural, ignoreFalseConditions, separator) + + ToString("isVWapFastOverMid", isVWapFastOverMid, ignoreFalseConditions, separator) + + ToString("isVWapMidOverSlow", isVWapMidOverSlow, ignoreFalseConditions, separator) + + ToString("isVWapFastUnderMid", isVWapFastUnderMid, ignoreFalseConditions, separator) + + ToString("isVWapMidUnderSlow", isVWapMidUnderSlow, ignoreFalseConditions, separator) + + ToString("isVWapBullishState", isVWapBullishState, ignoreFalseConditions, separator) + + ToString("isVWapBearishState", isVWapBearishState, ignoreFalseConditions, separator) + + ToString("isVWapNeuturalState", isVWapNeuturalState, ignoreFalseConditions, separator) + + ToString("isVWapBullishOrdered", isVWapBullishOrdered, ignoreFalseConditions, separator) + + ToString("isVWapBearishOrdered", isVWapBearishOrdered, ignoreFalseConditions, separator) + + ToString("isVWapSwitchedToBullishOrdered", isVWapSwitchedToBullishOrdered, ignoreFalseConditions, separator) + + ToString("isVWapSwitchedToBearishOrdered", isVWapSwitchedToBearishOrdered, ignoreFalseConditions, separator) + + ToString("isVWapSwitchedToBullishState", isVWapSwitchedToBullishState, ignoreFalseConditions, separator) + + ToString("isVWapSwitchedToBearishState", isVWapSwitchedToBearishState, ignoreFalseConditions, separator) + + ToString("isVWapSwitchedToNeuturalState", isVWapSwitchedToNeuturalState, ignoreFalseConditions, separator) + + // + // XFIBONACCI ... + ToString("isOerFib1", isOerFib1, ignoreFalseConditions, separator) + + ToString("isOerFib2", isOerFib2, ignoreFalseConditions, separator) + + ToString("isOerFib3", isOerFib3, ignoreFalseConditions, separator) + + ToString("isOerFib4", isOerFib4, ignoreFalseConditions, separator) + + ToString("isOerFib5", isOerFib5, ignoreFalseConditions, separator) + + ToString("isUnderFib1", isUnderFib1, ignoreFalseConditions, separator) + + ToString("isUnderFib2", isUnderFib2, ignoreFalseConditions, separator) + + ToString("isUnderFib3", isUnderFib3, ignoreFalseConditions, separator) + + ToString("isUnderFib4", isUnderFib4, ignoreFalseConditions, separator) + + ToString("isUnderFib5", isUnderFib5, ignoreFalseConditions, separator) + + ToString("isCloseOerFib1", isCloseOerFib1, ignoreFalseConditions, separator) + + ToString("isCloseOerFib2", isCloseOerFib2, ignoreFalseConditions, separator) + + ToString("isCloseOerFib3", isCloseOerFib3, ignoreFalseConditions, separator) + + ToString("isCloseOerFib4", isCloseOerFib4, ignoreFalseConditions, separator) + + ToString("isCloseOerFib5", isCloseOerFib5, ignoreFalseConditions, separator) + + ToString("isCloseUnderFib1", isCloseUnderFib1, ignoreFalseConditions, separator) + + ToString("isCloseUnderFib2", isCloseUnderFib2, ignoreFalseConditions, separator) + + ToString("isCloseUnderFib3", isCloseUnderFib3, ignoreFalseConditions, separator) + + ToString("isCloseUnderFib4", isCloseUnderFib4, ignoreFalseConditions, separator) + + ToString("isCloseUnderFib5", isCloseUnderFib5, ignoreFalseConditions, separator) + + // + "" + // + ; // result = @@ -2169,6 +2456,61 @@ class XCX121Helper : public XCBaseHelper ); } + // + // Converts to State ... + ENUM_XVWAP_STATES ToVWAPState(double value) + { + // + ENUM_XVWAP_STATES result = + value == 1 + ? XVWAP_STATE_BULLISH + : value == 2 + ? XVWAP_STATE_BEARISH + : XVWAP_STATE_NEUTURAL; + + // + return result; + } + + // + bool IsVWAPBullish(double value) + { + // + bool result = false; + + // + result = ToVWAPState(value) == XVWAP_STATE_BULLISH; + + // + return result; + } + + // + bool IsVWAPBearish(double value) + { + // + bool result = false; + + // + result = ToVWAPState(value) == XVWAP_STATE_BEARISH; + + // + return result; + } + + // + bool IsVWAPNeutural(double value) + { + // + bool result = false; + + // + result = ToVWAPState(value) == XVWAP_STATE_NEUTURAL; + + // + return result; + } + // // XDON ... @@ -2868,8 +3210,8 @@ class XCX121Helper : public XCBaseHelper bool GetConditions( X121Conditions &conditions, // - int barIndex = 0, // - int loopback = 5 // + int barIndex = 0, // + int loopback = 5 // ) { // @@ -2895,6 +3237,42 @@ class XCX121Helper : public XCBaseHelper int pIndex = cIndex + 1; int ppIndex = pIndex + 1; + // + XOHCL zBar; + result = zBar.Init( + mSymbol, + mPeriod, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + mSymbol, + mPeriod, + pIndex // + ); + if (!result) + { + return result; + } + // // Buffers ... @@ -3152,7 +3530,237 @@ class XCX121Helper : public XCBaseHelper // // Conditions ... - // TODO: Implement this if Required ... + + // + // XSAR ... + + // + bool isSarBullish = conditions.sarBuffer[cIndex] < cBar.low; + bool isSarBullishPrev = conditions.sarBuffer[pIndex] < pBar.low; + + // + bool isSarBearish = conditions.sarBuffer[cIndex] > cBar.high; + bool isSarBearishPrev = conditions.sarBuffer[pIndex] > pBar.high; + + // + bool isSarSwitchedBullish = isSarBullish && + !isSarBullishPrev; + bool isSarSwitchedBearish = isSarBearish && + !isSarBearishPrev; + + // + // XPV ... + + // + bool isNewPeak = conditions.peaksBuffer[cIndex] != conditions.peaksBuffer[pIndex]; + bool isNewPeakOverLast = isNewPeak && + conditions.peaksBuffer[cIndex] > conditions.peaksBuffer[pIndex]; + bool isNewPeakUnderLast = isNewPeak && + conditions.peaksBuffer[cIndex] < conditions.peaksBuffer[pIndex]; + + // + bool isNewVale = conditions.valesBuffer[cIndex] != conditions.valesBuffer[pIndex]; + bool isNewValeOverLast = isNewVale && + conditions.valesBuffer[cIndex] > conditions.valesBuffer[pIndex]; + bool isNewValeUnderLast = isNewVale && + conditions.valesBuffer[cIndex] < conditions.valesBuffer[pIndex]; + + // + // XVWAP ... + + // + bool isVWapFastBullish = IsVWAPBullish(conditions.vwapFastStateBuffer[cIndex]); + bool isVWapFastBullishPrev = IsVWAPBullish(conditions.vwapFastStateBuffer[pIndex]); + + // + bool isVWapFastBearish = IsVWAPBearish(conditions.vwapFastStateBuffer[cIndex]); + bool isVWapFastBearishPrev = IsVWAPBearish(conditions.vwapFastStateBuffer[pIndex]); + + // + bool isVWapFastNeutural = IsVWAPNeutural(conditions.vwapFastStateBuffer[cIndex]); + bool isVWapFastNeuturalPrev = IsVWAPNeutural(conditions.vwapFastStateBuffer[pIndex]); + + // + bool isVWapMidBullish = IsVWAPBullish(conditions.vwapMidStateBuffer[cIndex]); + bool isVWapMidBullishPrev = IsVWAPBullish(conditions.vwapMidStateBuffer[pIndex]); + + // + bool isVWapMidBearish = IsVWAPBearish(conditions.vwapMidStateBuffer[cIndex]); + bool isVWapMidBearishPrev = IsVWAPBearish(conditions.vwapMidStateBuffer[pIndex]); + + // + bool isVWapMidNeutural = IsVWAPNeutural(conditions.vwapMidStateBuffer[cIndex]); + bool isVWapMidNeuturalPrev = IsVWAPNeutural(conditions.vwapMidStateBuffer[pIndex]); + + // + bool isVWapSlowBullish = IsVWAPBullish(conditions.vwapSlowStateBuffer[cIndex]); + bool isVWapSlowBullishPrev = IsVWAPBullish(conditions.vwapSlowStateBuffer[pIndex]); + + // + bool isVWapSlowBearish = IsVWAPBearish(conditions.vwapSlowStateBuffer[cIndex]); + bool isVWapSlowBearishPrev = IsVWAPBearish(conditions.vwapSlowStateBuffer[pIndex]); + + // + bool isVWapSlowNeutural = IsVWAPNeutural(conditions.vwapSlowStateBuffer[cIndex]); + bool isVWapSlowNeuturalPrev = IsVWAPNeutural(conditions.vwapSlowStateBuffer[pIndex]); + + // + bool isVWapFastOverMid = conditions.vwapFastBuffer[cIndex] > conditions.vwapMidBuffer[cIndex]; + bool isVWapFastOverMidPrev = conditions.vwapFastBuffer[pIndex] > conditions.vwapMidBuffer[pIndex]; + + // + bool isVWapMidOverSlow = conditions.vwapMidBuffer[cIndex] > conditions.vwapSlowBuffer[cIndex]; + bool isVWapMidOverSlowPrev = conditions.vwapMidBuffer[pIndex] > conditions.vwapSlowBuffer[pIndex]; + + // + bool isVWapFastUnderMid = conditions.vwapFastBuffer[cIndex] < conditions.vwapMidBuffer[cIndex]; + bool isVWapFastUnderMidPrev = conditions.vwapFastBuffer[pIndex] < conditions.vwapMidBuffer[pIndex]; + + // + bool isVWapMidUnderSlow = conditions.vwapMidBuffer[cIndex] < conditions.vwapSlowBuffer[cIndex]; + bool isVWapMidUnderSlowPrev = conditions.vwapMidBuffer[pIndex] < conditions.vwapSlowBuffer[pIndex]; + + // + bool isVWapBullishState = isVWapFastBullish && + isVWapMidBullish && + isVWapSlowBullish; + bool isVWapBullishStatePrev = isVWapFastBullishPrev && + isVWapMidBullishPrev && + isVWapSlowBullishPrev; + + // + bool isVWapBearishState = isVWapFastBearish && + isVWapMidBearish && + isVWapSlowBearish; + bool isVWapBearishStatePrev = isVWapFastBearishPrev && + isVWapMidBearishPrev && + isVWapSlowBearishPrev; + + // + bool isVWapNeuturalState = isVWapFastNeutural && + isVWapMidNeutural && + isVWapSlowNeutural; + bool isVWapNeuturalStatePrev = isVWapFastNeuturalPrev && + isVWapMidNeuturalPrev && + isVWapSlowNeuturalPrev; + + // + bool isVWapBullishOrdered = isVWapFastOverMid && + isVWapMidOverSlow; + bool isVWapBullishOrderedPrev = isVWapFastOverMidPrev && + isVWapMidOverSlowPrev; + + // + bool isVWapBearishOrdered = isVWapFastUnderMid && + isVWapMidUnderSlow; + bool isVWapBearishOrderedPrev = isVWapFastUnderMidPrev && + isVWapMidUnderSlowPrev; + + // + bool isVWapSwitchedToBullishOrdered = isVWapBullishOrdered && + !isVWapBullishOrderedPrev; + bool isVWapSwitchedToBearishOrdered = isVWapBearishOrdered && + !isVWapBearishOrderedPrev; + + // + bool isVWapSwitchedToBullishState = isVWapBullishState && + !isVWapBullishStatePrev; + bool isVWapSwitchedToBearishState = isVWapBearishState && + !isVWapBearishStatePrev; + bool isVWapSwitchedToNeuturalState = isVWapNeuturalState && + !isVWapNeuturalStatePrev; + + // + // XDON ... + + // + // XFIBONACCI ... + + // + bool isOerFib1 = cBar.low > conditions.fl1Buffer[cIndex]; + bool isOerFib2 = cBar.low > conditions.fl2Buffer[cIndex]; + bool isOerFib3 = cBar.low > conditions.fl3Buffer[cIndex]; + bool isOerFib4 = cBar.low > conditions.fl4Buffer[cIndex]; + bool isOerFib5 = cBar.low > conditions.fl5Buffer[cIndex]; + + // + bool isUnderFib1 = cBar.high < conditions.fl1Buffer[cIndex]; + bool isUnderFib2 = cBar.high < conditions.fl2Buffer[cIndex]; + bool isUnderFib3 = cBar.high < conditions.fl3Buffer[cIndex]; + bool isUnderFib4 = cBar.high < conditions.fl4Buffer[cIndex]; + bool isUnderFib5 = cBar.high < conditions.fl5Buffer[cIndex]; + + // + bool isCloseOerFib1 = cBar.close > conditions.fl1Buffer[cIndex]; + bool isCloseOerFib2 = cBar.close > conditions.fl2Buffer[cIndex]; + bool isCloseOerFib3 = cBar.close > conditions.fl3Buffer[cIndex]; + bool isCloseOerFib4 = cBar.close > conditions.fl4Buffer[cIndex]; + bool isCloseOerFib5 = cBar.close > conditions.fl5Buffer[cIndex]; + + // + bool isCloseUnderFib1 = cBar.close < conditions.fl1Buffer[cIndex]; + bool isCloseUnderFib2 = cBar.close < conditions.fl2Buffer[cIndex]; + bool isCloseUnderFib3 = cBar.close < conditions.fl3Buffer[cIndex]; + bool isCloseUnderFib4 = cBar.close < conditions.fl4Buffer[cIndex]; + bool isCloseUnderFib5 = cBar.close < conditions.fl5Buffer[cIndex]; + + // + + // + // Set ... + conditions.isSarBullish = isSarBullish; + conditions.isSarBearish = isSarBearish; + conditions.isSarSwitchedBullish = isSarSwitchedBullish; + conditions.isSarSwitchedBearish = isSarSwitchedBearish; + conditions.isNewPeak = isNewPeak; + conditions.isNewPeakOverLast = isNewPeakOverLast; + conditions.isNewPeakUnderLast = isNewPeakUnderLast; + conditions.isNewVale = isNewVale; + conditions.isNewValeOverLast = isNewValeOverLast; + conditions.isNewValeUnderLast = isNewValeUnderLast; + conditions.isVWapFastBullish = isVWapFastBullish; + conditions.isVWapFastBearish = isVWapFastBearish; + conditions.isVWapFastNeutural = isVWapFastNeutural; + conditions.isVWapMidBullish = isVWapMidBullish; + conditions.isVWapMidBearish = isVWapMidBearish; + conditions.isVWapMidNeutural = isVWapMidNeutural; + conditions.isVWapSlowBullish = isVWapSlowBullish; + conditions.isVWapSlowBearish = isVWapSlowBearish; + conditions.isVWapSlowNeutural = isVWapSlowNeutural; + conditions.isVWapFastOverMid = isVWapFastOverMid; + conditions.isVWapMidOverSlow = isVWapMidOverSlow; + conditions.isVWapFastUnderMid = isVWapFastUnderMid; + conditions.isVWapMidUnderSlow = isVWapMidUnderSlow; + conditions.isVWapBullishState = isVWapBullishState; + conditions.isVWapBearishState = isVWapBearishState; + conditions.isVWapNeuturalState = isVWapNeuturalState; + conditions.isVWapBullishOrdered = isVWapBullishOrdered; + conditions.isVWapBearishOrdered = isVWapBearishOrdered; + conditions.isVWapSwitchedToBullishOrdered = isVWapSwitchedToBullishOrdered; + conditions.isVWapSwitchedToBearishOrdered = isVWapSwitchedToBearishOrdered; + conditions.isVWapSwitchedToBullishState = isVWapSwitchedToBullishState; + conditions.isVWapSwitchedToBearishState = isVWapSwitchedToBearishState; + conditions.isVWapSwitchedToNeuturalState = isVWapSwitchedToNeuturalState; + conditions.isOerFib1 = isOerFib1; + conditions.isOerFib2 = isOerFib2; + conditions.isOerFib3 = isOerFib3; + conditions.isOerFib4 = isOerFib4; + conditions.isOerFib5 = isOerFib5; + conditions.isUnderFib1 = isUnderFib1; + conditions.isUnderFib2 = isUnderFib2; + conditions.isUnderFib3 = isUnderFib3; + conditions.isUnderFib4 = isUnderFib4; + conditions.isUnderFib5 = isUnderFib5; + conditions.isCloseOerFib1 = isCloseOerFib1; + conditions.isCloseOerFib2 = isCloseOerFib2; + conditions.isCloseOerFib3 = isCloseOerFib3; + conditions.isCloseOerFib4 = isCloseOerFib4; + conditions.isCloseOerFib5 = isCloseOerFib5; + conditions.isCloseUnderFib1 = isCloseUnderFib1; + conditions.isCloseUnderFib2 = isCloseUnderFib2; + conditions.isCloseUnderFib3 = isCloseUnderFib3; + conditions.isCloseUnderFib4 = isCloseUnderFib4; + conditions.isCloseUnderFib5 = isCloseUnderFib5; // return result; diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index a98e5558..60bce4dd 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -25,143 +25,6 @@ #include "../../Classes/x-saherelm.x-poi.class.mq5" #include "../Libraries/x-121.smc.lib.mq5" -// -// Definitions ... -struct XSarChange -{ - // - // Props ... - ENUM_X_DIRECTION dir; // Sar Changed To Direction ... - datetime time; // Sar Changed Time ... - double last; // Sar Value Before Change ... - double value; // Sar Value After Change ... - - // - // Constructor ... - XSarChange() - { - Clean(); - } - - // - // Tools ... - - /** - * Cleanup ... - */ - void Clean() - { - // - last = 0; - value = 0; - time = NULL; - dir = X_DIRECTION_NONE; - } - - /** - * Validation ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - last > 0 && - value > 0 && - IsValid(time) && - HasDirection(dir); - - // - return result; - } - - /** - * Initialize ... - * - * @param _last: Last Sar Value ... - * @param _current: Current Sar Value ... - * - * @return ( bool ) - */ - bool Init( - double _last, - double _current, - datetime _time, - ENUM_X_DIRECTION _dir // - ) - { - // - bool result = false; - - // - result = - _last > 0 && - _current > 0 && - IsValid(_time) && - HasDirection(_dir); - if (!result) - { - return result; - } - - // - dir = _dir; - last = _last; - time = _time; - value = _current; - - // - result = IsValid(); - - // - return result; - } - - /** - * Check Change is Bullish ... - * - * @return ( bool ) - */ - bool IsBullish() - { - // - bool result = false; - - // - result = - IsValid() && - IsBullish(dir); - - // - return result; - } - - /** - * Check Change is Bearish ... - * - * @return ( bool ) - */ - bool IsBearishÙ‘() - { - // - bool result = false; - - // - result = - IsValid() && - IsBearish(dir); - - // - return result; - } - - // -}; - // // Implementations ... @@ -173,23 +36,8 @@ class XC121SMCCycleHelper : public XCBase // Props ... // - // XPV ... - XCXPVHelper *mXPVHelper; - XPVPivot pivots[]; - XPVPivot orderFlow[]; - - // - // X3MA ... - XCX3MAHelper *mX3MAHelper; - - // - // X3VWAP ... - XCX3VWAPHelper *mX3VWAPHelper; - - // - // XCHSAR ... - XCXCHSARHelper *mXCHSARHelper; - XSarChange sarChanges[]; + // X121 ... + XCX121Helper *mX121Helper; // // POI Detector ... @@ -219,20 +67,14 @@ class XC121SMCCycleHelper : public XCBase * * @param symbol: String ... * @param period: ENUM_TIMEFRAMES member ... - * @param xpvInputs: XPVInputs instance ... - * @param x3maInputs: X3MAInputs instance ... - * @param x3vwapInputs: X3VWAPInputs instance ... - * @param xchsarInputs: XCHSARInputs instance ... + * @param x121Inputs: X121Inputs instance ... * * @return ( bool ) */ bool Init( string symbol, ENUM_TIMEFRAMES period, - XPVInputs &xpvInputs, - X3MAInputs &x3maInputs, - X3VWAPInputs &x3vwapInputs, - XCHSARInputs &xchsarInputs // + X121Inputs &x121Inputs // ) { // @@ -247,87 +89,12 @@ class XC121SMCCycleHelper : public XCBase } // - // XPV ... - - // - result = xpvInputs.IsValid(); - if (!result) - { - return result; - } - - // - mXPVHelper = new XCXPVHelper(); - result = mXPVHelper.Init( + // X121 ... + mX121Helper = new XCX121Helper(); + result = mX121Helper.Init( symbol, period, - xpvInputs // - ); - if (!result) - { - return result; - } - - // - // X3MA ... - - // - result = x3maInputs.IsValid(); - if (!result) - { - return result; - } - - // - mX3MAHelper = new XCX3MAHelper(); - result = mX3MAHelper.Init( - symbol, - period, - x3maInputs // - ); - if (!result) - { - return result; - } - - // - // X3VWAP ... - - // - result = x3vwapInputs.IsValid(); - if (!result) - { - return result; - } - - // - mX3VWAPHelper = new XCX3VWAPHelper(); - result = mX3VWAPHelper.Init( - symbol, - period, - x3vwapInputs // - ); - if (!result) - { - return result; - } - - // - // XCHSAR ... - - // - result = xchsarInputs.IsValid(); - if (!result) - { - return result; - } - - // - mXCHSARHelper = new XCXCHSARHelper(); - result = mXCHSARHelper.Init( - symbol, - period, - xchsarInputs // + x121Inputs // ); if (!result) { @@ -539,8 +306,8 @@ class XC121SMCCycleHelper : public XCBase conditions.Clean(); // - result = mXPVHelper.GetConditions( - conditions.xpvConditions, + result = mX121Helper.GetConditions( + conditions.x121Conditions, barIndex, loopback // ); @@ -552,47 +319,8 @@ class XC121SMCCycleHelper : public XCBase } // - result = mX3MAHelper.GetConditions( - conditions.x3maConditions, - barIndex, - loopback // - ); - if (!result) - { - // - conditions.Clean(); - return result; - } - - // - result = mX3VWAPHelper.GetConditions( - conditions.x3vwapConditions, - barIndex, - loopback // - ); - if (!result) - { - // - conditions.Clean(); - return result; - } - - // - result = mXCHSARHelper.GetConditions( - conditions.xchsarConditions, - barIndex, - loopback // - ); - if (!result) - { - // - conditions.Clean(); - return result; - } - - // - conditions.symbol = conditions.xpvConditions.symbol; - conditions.period = conditions.xpvConditions.period; + conditions.symbol = conditions.x121Conditions.symbol; + conditions.period = conditions.x121Conditions.period; conditions.time = TimeCurrent(); // @@ -602,761 +330,6 @@ class XC121SMCCycleHelper : public XCBase return result; } - // - // POI Tools ... - - /** - * Detect Nearest Current SAR Change ... - * - * @param changeBar: XOHCL instance, Holds Nearest Change Bar ... - * @param bar: XOHCL instance, represents Current Bar for Loopback ... - * - * @return ( bool ) - */ - bool DetectNearestCSARChange( - XOHCL &changeBar, - XOHCL &bar // - ) - { - // - bool result = false; - - // - changeBar.Clean(); - - // - result = - bar.IsValid(); - if (!result) - { - return result; - } - - // - XOHCL mBar; - result = GetBar( - bar, - mBar // - ); - if (!result) - { - return result; - } - - // - int barIndex = mBar.Index(); - double sar = mXCHSARHelper.GetC(barIndex); - bool isBullish = sar > 0 && - sar < mBar.low; - bool isBearish = sar > 0 && - sar > mBar.high; - result = isBullish || - isBearish; - if (!result) - { - return result; - } - - // - // Loop Back to Find Nearest Sar Change ... - bool canContinue = true; - while (canContinue) - { - // - barIndex++; - - // - XOHCL iBar; - canContinue = iBar.Init( - mBar.symbol, - mBar.period, - barIndex // - ); - if (!canContinue) - { - break; - } - - // - double iSar = mXCHSARHelper.GetC(barIndex); - bool isISarBullish = - iSar > 0 && - iSar < iBar.low; - bool isISarBearish = - iSar > 0 && - iSar > iBar.high; - bool isSarChanged = - isBullish - ? !isISarBullish - : !isISarBearish; - - // - if (isSarChanged) - { - // - result = iBar.GetNextBar(changeBar); - canContinue = false; - break; - } - } - - // - result = changeBar.IsValid(); - - // - return result; - } - - /** - * Detect Last Decision Bar ( Rejection, Pin, Momentum ) ... - * - * @param decisionBar: XOHCL instance, Holds Decision Bar ... - * @param forDir: ENUM_X_DIRECTION member, Specified Bar Direction ... - * @param bar: XOHCL instance, represents Current Bar for Loopback ... - * - * @return ( bool ) - */ - bool DetectNearestDecisionBar( - XOHCL &decisionBar, - ENUM_X_DIRECTION forDir, - XOHCL &bar // - ) - { - // - bool result = false; - - // - decisionBar.Clean(); - - // - result = - bar.IsValid() && - forDir != X_DIRECTION_ALL && - forDir != X_DIRECTION_NONE; - if (!result) - { - return result; - } - - // - XOHCL mBar; - result = GetBar( - bar, - mBar // - ); - if (!result) - { - return result; - } - - // - int barIndex = mBar.Index(); - bool isBullish = IsBullish(forDir); - - // - bool canContinue = true; - while (canContinue) - { - // - barIndex++; - - // - XOHCL iBar; - canContinue = iBar.Init( - mBar.symbol, - mBar.period, - barIndex // - ); - if (!canContinue) - { - break; - } - - // - ENUM_X_DIRECTION decisionDir; - bool isDecisionBar = mBarAnalyser - .IsDecisionBar( - iBar, - decisionDir // - ); - if (isDecisionBar) - { - // - if (decisionDir == forDir) - { - // - decisionBar = mBar; - canContinue = false; - break; - } - } - - // - canContinue = !decisionBar.IsValid(); - } - - // - result = decisionBar - .IsValid(); - - // - return result; - } - - // - // Parabolic Sar Extensions ... - - /** - * Check Sar Changes and Save it ... - * - * @param change: XSarChange instance ... - * @param time: DateTime ... - * - * @return ( bool ) - */ - bool IsSarChanged( - XSarChange &change, - datetime time = NULL // - ) - { - // - bool result = false; - - // - change.Clean(); - - // - XOHCL bar; - result = GetBar( - bar, - time // - ); - if (!result) - { - return result; - } - - // - XOHCL prevBar; - result = bar.GetPreviousBar(prevBar); - if (!result) - { - return result; - } - - // - XOHCL prevPrevBar; - result = prevBar.GetPreviousBar(prevPrevBar); - if (!result) - { - return result; - } - - // - prevPrevBar = prevBar; - prevBar = bar; - - // - int index = prevBar.Index(); - - // - double current = mXCHSARHelper.GetC(index); - double prev = mXCHSARHelper.GetC(index + 1); - - // - bool isCurrentBullish = - current < prevBar.low; - bool isPrevBullish = - prev < prevPrevBar.low; - - // - bool isCurrentBearish = - current > prevBar.high; - bool isPrevBearish = - prev > prevPrevBar.high; - - // - bool isChangedToBullish = - isCurrentBullish && - !isPrevBullish; - - // - bool isChangedToBearish = - isCurrentBearish && - !isPrevBearish; - - // - result = isChangedToBullish || - isChangedToBearish; - if (!result) - { - return result; - } - ENUM_X_DIRECTION dir = - isChangedToBullish - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - result = change - .Init( - prev, - current, - prevBar.time, - dir // - ); - if (!result) - { - return result; - } - - // - XSarChange lastChange; - bool hasLastItem = GetLastItem( - lastChange, - sarChanges // - ); - bool canAdd = !hasLastItem - ? true - : lastChange.time < change.time; - if (canAdd) - { - // - AddRef( - change, - sarChanges // - ); - } - - // - CleanSarChanges(); - - // - return result; - } - - /** - * Cleanup Unused Sar Changes ... - */ - void CleanSarChanges() - { - // - int required = 10; - int count = ArraySize(sarChanges); - if (!IsValidSize(count) || count <= required) - { - return; - } - - // - int mustRemove = count - required; - ArrayRemove( - sarChanges, - 0, - mustRemove // - ); - } - - // - // XPV Extensions ... - - /** - * Detect First Pivot ... - * - * @param pivot: XPVPivot instance ... - * @param time: DateTime ... - * @param minRepetition: Integer, Minimum Repetition ... - * @param maxAllowedLoopbackBars: Integer, Max Allowed LoopBack Bars ... - * - * @return ( bool ) - */ - bool DetectLastPivot( - XPVPivot &pivot, - datetime time = NULL, - int minRepetition = 40, - int maxAllowedLoopbackBars = 576 // - ) - { - // - bool result = false; - - // - pivot.Clean(); - - // - int index = GetBarIndex(time); - result = DetectPivot( - pivot, - index, - minRepetition, - maxAllowedLoopbackBars // - ); - - // - return result; - } - - /** - * Detect Pivot ... - * - * @param pivot: XPVPivot instance ... - * @param barIndex: Integer ... - * @param minRepetition: Integer, Minimum Repetition ... - * @param maxAllowedLoopbackBars: Integer, Max Allowed LoopBack Bars ... - * - * @return ( bool ) - */ - bool DetectPivot( - XPVPivot &pivot, - int barIndex = 0, - int minRepetition = 40, - int maxAllowedLoopbackBars = 576 // - ) - { - // - bool result = false; - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - int start = barIndex; - int end = start + maxAllowedLoopbackBars; - - // - double peak = 0; - int peakRepeate = 0; - int peakToBarIndex = 0; - int peakFromBarIndex = 0; - - // - double vale = 0; - int valeRepeate = 0; - int valeToBarIndex = 0; - int valeFromBarIndex = 0; - - // - bool canLookupPeak = true; - bool canLookupVale = true; - bool canLookup = true; - while (canLookup) - { - // - // Check Peak ... - double iPeak = mXPVHelper.GetPeak(barIndex); - if (iPeak != peak) - { - // - if (peak != 0 && - peakRepeate >= minRepetition) - { - // - XPVPivot iPivot; - - // - iPivot.lower = 0; - iPivot.upper = peak; - iPivot.symbol = symbol; - iPivot.period = period; - iPivot.type = XPV_PEAK; - iPivot.repetition = peakRepeate; - iPivot.to = iTime( - symbol, - period, - peakToBarIndex // - ); - iPivot.from = iTime( - symbol, - period, - peakFromBarIndex // - ); - - // - iPivot.lower = iPivot.CalculateLower(); - - // - bool isValid = iPivot.IsValid(); - if (isValid) - { - // - pivot = iPivot; - break; - } - } - - // - peak = iPeak; - peakRepeate = 0; - peakFromBarIndex = 0; - peakToBarIndex = barIndex; - } - else if (iPeak == peak) - { - // - peakRepeate++; - peakFromBarIndex = barIndex; - } - - // - // Check Vale ... - double iVale = mXPVHelper.GetVale(barIndex); - if (iVale != vale) - { - // - if (vale != 0 && - valeRepeate >= minRepetition) - { - // - XPVPivot iPivot; - - // - iPivot.upper = 0; - iPivot.lower = vale; - iPivot.symbol = symbol; - iPivot.period = period; - iPivot.type = XPV_VALE; - iPivot.repetition = valeRepeate; - iPivot.to = iTime( - symbol, - period, - valeToBarIndex // - ); - iPivot.from = iTime( - symbol, - period, - valeFromBarIndex // - ); - - // - iPivot.upper = iPivot.CalculateUpper(); - - // - bool isValid = iPivot.IsValid(); - if (isValid) - { - // - pivot = iPivot; - break; - } - } - - // - vale = iVale; - valeRepeate = 0; - valeFromBarIndex = 0; - valeToBarIndex = barIndex; - } - else if (iVale == vale) - { - // - valeRepeate++; - valeFromBarIndex = barIndex; - } - - // - canLookupPeak = !pivot.IsValid(); - canLookupVale = !pivot.IsValid(); - canLookup = barIndex < end && - (canLookupPeak || - canLookupVale); - if (canLookup) - { - barIndex++; - } - } - - // - result = pivot.IsValid(); - if (result) - { - // - XPVPivot last; - bool hasLastPivot = GetLastPivot(last); - - // - if (hasLastPivot) - { - // - // Check For Pivot Update ... - bool isLastPivotSameAsCurrent = - pivot.IsValid() && - last.IsValid() && - pivot.from == last.from && - pivot.type == last.type; - if (!isLastPivotSameAsCurrent) - { - // - AddRef( - pivot, - pivots // - ); - - // - CleanPivots(); - } - else - { - // - // Update Last Pivot ... - RemoveLastItem(pivots); - - // - pivot.to = TimeCurrent(); - - // - AddRef( - pivot, - pivots // - ); - - // - CleanPivots(); - } - } - else - { - // - // Add New Pivot ... - AddRef( - pivot, - pivots // - ); - - // - CleanPivots(); - } - } - - // - // DetectOrderFlow(); - - // - return result; - } - - /** - * Retriece Last Pivot if Exists ... - * - * @param pivot: XPVPivot instane ... - * - * @return ( bool ) - */ - bool GetLastPivot(XPVPivot &pivot) - { - // - bool result = false; - - // - pivot.Clean(); - - // - int count = ArraySize(pivots); - if (!IsValidSize(count)) - { - return result; - } - - // - result = GetLastItem( - pivot, - pivots // - ); - - // - return result; - } - - /** - * Detect Order Flow ... - * - * @param dir: ENUM_X_DIRECTION member, Hold's Order Flow Direction ... - * @param minPivots: Integer, minimum Required Pivots for Order Flow ... - * - * @return ( bool ) - */ - bool DetectOrderFlow( - ENUM_X_DIRECTION &dir, - int minPivots = 3 // - ) - { - // - bool result = false; - - // - // Normalize Minimum Pivots ... - if (minPivots < 2) - { - minPivots = 2; - } - - // - Clean(orderFlow); - Copy( - pivots, - orderFlow // - ); - - // - // Sort Pivots ... - SortPivots(orderFlow); - - // - // Filter Broken Order Flows ... - FilterBrokenPivots(orderFlow); - - // - int count = ArraySize(orderFlow); - result = IsValidSize(count) && - count >= minPivots; - if (!result) - { - return result; - } - - // - // Detect Order Flow Direction ... - result = DetectPivotDirection( - orderFlow, - dir // - ); - if (!result) - { - return result; - } - - // - return result; - } - - /** - * Cleanup Unused Pivots ... - */ - void CleanPivots() - { - // - int required = 10; - int count = ArraySize(pivots); - if (!IsValidSize(count) || count <= required) - { - return; - } - - // - int mustRemove = count - required; - ArrayRemove( - pivots, - 0, - mustRemove // - ); - } - // // Virtuals ... @@ -1379,10 +352,7 @@ class XC121SMCCycleHelper : public XCBase void DeInit() { // - delete mXPVHelper; - delete mX3MAHelper; - delete mX3VWAPHelper; - delete mXCHSARHelper; + delete mX121Helper; // delete mBarAnalyser; @@ -1453,7 +423,7 @@ class XC121SMCCycleHelper : public XCBase string result = NULL; // - result = mXPVHelper.GetSymbol(); + result = mX121Helper.GetSymbol(); // return result; @@ -1470,7 +440,7 @@ class XC121SMCCycleHelper : public XCBase ENUM_TIMEFRAMES result = NULL; // - result = mXPVHelper.GetPeriod(); + result = mX121Helper.GetPeriod(); // return result; diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index a3560cea..bd2f9ee7 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -22,10 +22,7 @@ // // Imports ... #include "../../Classes/x-saherelm.base.class.mq5" -#include "../../Helpers/x-saherelm.x3ma.helper.mq5" -#include "../../Helpers/x-saherelm.x3vwap.helper.mq5" -#include "../../Helpers/x-saherelm.xchsar.helper.mq5" -#include "../../Helpers/x-saherelm.xpv.helper.mq5" +#include "../../Helpers/x-saherelm.x121.helper.mq5" #include "../../Libraries/x-saherelm.common.lib.mq5" #include "../../Libraries/x-saherelm.x-poi.lib.mq5" #include "../../Libraries/x-saherelm.x-trade.lib.mq5" @@ -436,10 +433,7 @@ struct X121SMCCycleConditions datetime time; // - XPVConditions xpvConditions; - X3MAConditions x3maConditions; - X3VWAPConditions x3vwapConditions; - XCHSARConditions xchsarConditions; + X121Conditions x121Conditions; // XPOIState state; @@ -465,10 +459,7 @@ struct X121SMCCycleConditions // state.Clean(); - xpvConditions.Clean(); - x3maConditions.Clean(); - x3vwapConditions.Clean(); - xchsarConditions.Clean(); + x121Conditions.Clean(); } /** @@ -492,94 +483,6 @@ struct X121SMCCycleConditions return result; } - /** - * Check Cycle Conditions Has Bullish State ... - * - * @param bar: XOHCL instance ... - * - * @return ( bool ) - */ - bool IsBullish( - XOHCL &bar // - ) - { - // - bool result = false; - - // - int index = bar.Index(); - - // - result = - // - // Check Conditions Validation ... - IsValid() && - // - // Check Bar Validation ... - bar.IsValid() && - // - // Check XCHSar Current is Bullish ... - xchsarConditions.isCBullish && - // - // Check X3VWAP is Bullish State ... - x3vwapConditions.isBullishState && - // - // Check X3VWAP is Bullish Ordered ... - x3vwapConditions.isBullishOrdered && - // - // Check Close Over X3MA Fast ... - bar.close > x3maConditions.fasts[index] - // - ; - - // - return result; - } - - /** - * Check Cycle Conditions Has Bearish State ... - * - * @param bar: XOHCL instance ... - * - * @return ( bool ) - */ - bool IsBearish( - XOHCL &bar // - ) - { - // - bool result = false; - - // - int index = bar.Index(); - - // - result = - // - // Check Conditions Validation ... - IsValid() && - // - // Check Bar Validation ... - bar.IsValid() && - // - // Check XCHSar Current is Bearish ... - xchsarConditions.isCBearish && - // - // Check X3VWAP is Bearish State ... - x3vwapConditions.isBearishState && - // - // Check X3VWAP is Bearish Ordered ... - x3vwapConditions.isBearishOrdered && - // - // Check Close Under X3MA Fast ... - bar.close < x3maConditions.fasts[index] - // - ; - - // - return result; - } - // // Reporter Functions ... @@ -607,15 +510,6 @@ struct X121SMCCycleConditions // double bullScore = 0; double bearScore = 0; - - // // - // // XPV ... - // pvConditions.GenerateScore( - // bullScore, - // bearScore // - // ); - // bullishScore += bullScore; - // bearishScore += bearScore; } /** @@ -656,19 +550,9 @@ struct X121SMCCycleConditions true // ); - // // - // // XPV ... - // string pvStr = pvConditions.GenerateSummary( - // false, - // true, - // false, - // ignoreFalseConditions // - // ); - // string conditionsStr = // - // pvStr + separator + "" // ; @@ -805,182 +689,6 @@ struct X121SMCStrategyConditions return result; } - /** - * Check Conditions has Ddirection or not ... - * - * @param dir: ENUM_X_DIRECTIOn member ... - * @param bar: XOHCL instance ... - * - * @return ( bool ) - */ - bool HasDirection( - ENUM_X_DIRECTION &dir, - XOHCL &bar // - ) - { - // - bool result = false; - - // - dir = X_DIRECTION_NONE; - - // - result = IsValid() && - bar.IsValid() && - bar.Index() > 0; - if (!result) - { - return result; - } - - // - int index = bar.Index(); - - // - // Parse Cycles Conditions ... - - // - // Vision ... - - // - bool isVisionBullish = - // - // XCHSar Current is Bullish ... - visionConditions.xchsarConditions.isCBullish && - // - // Close Over X3MA Fast ... - bar.close > visionConditions.x3maConditions.fasts[index] && - // - // X3VWap Fast is Bullish ... - visionConditions.x3vwapConditions.fastStates[index] == - X3VWAP_STATE_BULLISH - // - ; - - // - bool isVisionBearish = - // - // XCHSar Current is Bearish ... - visionConditions.xchsarConditions.isCBearish && - // - // Close Under X3MA Fast ... - bar.close < visionConditions.x3maConditions.fasts[index] && - // - // X3VWap Fast is Bearish ... - visionConditions.x3vwapConditions.fastStates[index] == - X3VWAP_STATE_BEARISH - // - ; - - // - // Check Vision Has Conditions or not ... - bool hasVisionConditions = - isVisionBullish || - isVisionBearish; - result = hasVisionConditions; - if (!result) - { - return result; - } - - // - // Consolidation ... - - // - bool isConsolidationBullish = consolidationConditions.IsBullish(bar); - bool isConsolidationBearish = consolidationConditions.IsBearish(bar); - bool hasConsolidationConditions = - isConsolidationBullish || - isConsolidationBearish; - result = hasConsolidationConditions; - if (!result) - { - return result; - } - - // - // Verification ... - - // - bool isVerificationBullish = verificationConditions.IsBullish(bar); - bool isVerificationBearish = verificationConditions.IsBearish(bar); - bool hasVerificationConditions = - isVerificationBullish || - isVerificationBearish; - result = hasVerificationConditions; - if (!result) - { - return result; - } - - // - // Analyse ... - - // - bool isAnalyseBullish = analyseConditions.IsBullish(bar); - bool isAnalyseBearish = analyseConditions.IsBearish(bar); - bool hasAnalyseConditions = - isAnalyseBullish || - isAnalyseBearish; - result = hasAnalyseConditions; - if (!result) - { - return result; - } - - // - // Decision ... - - // - bool isDecisionBullish = decisionConditions.IsBullish(bar); - bool isDecisionBearish = decisionConditions.IsBearish(bar); - bool hasDecisionConditions = - isDecisionBullish || - isDecisionBearish; - result = hasDecisionConditions; - if (!result) - { - return result; - } - - // - // Analyse Conditions ... - bool hasBullishConditions = - // - isVisionBullish && - isConsolidationBullish && - isVerificationBullish && - isAnalyseBullish && - isDecisionBullish - // - ; - bool hasBearishConditions = - // - isVisionBearish && - isConsolidationBearish && - isVerificationBearish && - isAnalyseBearish && - isDecisionBearish - // - ; - result = hasBullishConditions || - hasBearishConditions; - if (!result) - { - return result; - } - - // - // Specified Conditions Direction ... - dir = - hasBullishConditions - ? X_DIRECTION_BULLISH - : X_DIRECTION_BEARISH; - - // - return result; - } - // // Reporter Functions ... @@ -1008,15 +716,6 @@ struct X121SMCStrategyConditions // double bullScore = 0; double bearScore = 0; - - // // - // // XPV ... - // pvConditions.GenerateScore( - // bullScore, - // bearScore // - // ); - // bullishScore += bullScore; - // bearishScore += bearScore; } /** @@ -1057,19 +756,9 @@ struct X121SMCStrategyConditions true // ); - // // - // // XPV ... - // string pvStr = pvConditions.GenerateSummary( - // false, - // true, - // false, - // ignoreFalseConditions // - // ); - // string conditionsStr = // - // pvStr + separator + "" // ; diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index d9966caa..38726d5e 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -227,76 +227,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy { // Print("PRV: ", provider); - - // - ENUM_X_DIRECTION forDir = ToDirection(signal.type); - bool ignoreSwingHighs = false; - bool ignoreSwingLows = false; - bool ignoreSupportZones = false; - bool ignoreResistanceZones = false; - bool ignoreSupplyZones = false; - bool ignoreDemandZones = false; - bool ignoreBullishOrderBlocks = false; - bool ignoreBearishOrderBlocks = false; - bool ignoreBullishFairValueGaps = false; - bool ignoreBearishFairValueGaps = false; - bool ignoreBullishRejectionBars = false; - bool ignoreBearishRejectionBars = false; - bool ignoreBullishMomentumBars = false; - bool ignoreBearishMomentumBars = false; - if (IsBullish(forDir)) - { - // - ignoreSwingLows = false; - ignoreDemandZones = false; - ignoreSupportZones = false; - ignoreBullishOrderBlocks = false; - ignoreBullishFairValueGaps = false; - ignoreBullishRejectionBars = false; - ignoreBullishMomentumBars = false; - } - else - { - // - ignoreSwingHighs = true; - ignoreSupplyZones = true; - ignoreResistanceZones = true; - ignoreBearishOrderBlocks = true; - ignoreBearishFairValueGaps = false; - ignoreBearishRejectionBars = true; - ignoreBearishMomentumBars = true; - } - - // - RedrawOrderFlow( - true, // Force Clean ... - false, // Same Period ... - true, // Order Flow ... - true, // Order Flow State ... - false, // Only Last Order Flow ... - true, // Only Last Order Flow State ... - // - forDir, // Direction Force ... - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); DrawSignal(signal); - ClearDraws(); - - // - ResetOrderFlow(); } // @@ -406,111 +337,93 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // Trigger ... - mTriggerCycleHelper.GetConditions( + result = mTriggerCycleHelper.GetConditions( conditions.triggerConditions, zIndex, conditionsLoopback // ); + if (!result) + { + // + conditions.Clean(); + return result; + } conditions.triggerConditions.state = mTriggerState; // // Decision ... - mDecisionCycleHelper.GetConditions( + result = mDecisionCycleHelper.GetConditions( conditions.decisionConditions, zIndex, conditionsLoopback // ); + if (!result) + { + // + conditions.Clean(); + return result; + } conditions.decisionConditions.state = mDecisionState; // // Analyse ... - mAnalyseCycleHelper.GetConditions( + result = mAnalyseCycleHelper.GetConditions( conditions.analyseConditions, zIndex, conditionsLoopback // ); + if (!result) + { + // + conditions.Clean(); + return result; + } conditions.analyseConditions.state = mAnalyseState; // // Verification ... - mVerificationCycleHelper.GetConditions( + result = mVerificationCycleHelper.GetConditions( conditions.verificationConditions, zIndex, conditionsLoopback // ); + if (!result) + { + // + conditions.Clean(); + return result; + } conditions.verificationConditions.state = mVerificationState; // // Consolidation ... - mConsolidationCycleHelper.GetConditions( + result = mConsolidationCycleHelper.GetConditions( conditions.consolidationConditions, zIndex, conditionsLoopback // ); + if (!result) + { + // + conditions.Clean(); + return result; + } conditions.consolidationConditions.state = mConsolidationState; // // Vision ... - mVisionCycleHelper.GetConditions( + result = mVisionCycleHelper.GetConditions( conditions.visionConditions, zIndex, conditionsLoopback // ); - conditions.visionConditions.state = mVisionState; - - // - // Detect and Store Parabolic Sar Changes ... - XSarChange sarChange; - bool isSarChanged = mTriggerCycleHelper - .IsSarChanged( - sarChange, - cTime // - ); - - // - // Detect and Store Pivots ... - XPVPivot pivot; - bool isPivotDetected = mTriggerCycleHelper - .DetectPivot(pivot); - if (isPivotDetected) { + if (!result) + { // - Print("Pivot Detected ..."); - - // - ClearDraws(); - XCXPVPivotObject *iObj; - iObj = new XCXPVPivotObject(); - bool isCreated = iObj.Create( - mPOIDrawer.ChartIdentification(), - mPOIDrawer.SubWindowIdentification(), - pivot // - ); - if (isCreated) - { - // - if (pivot.IsPeak()) - { - // - iObj.PivotWidth(1); - iObj.PivotFill(false); - iObj.PivotColor(clrAqua); - iObj.PivotStyle(STYLE_SOLID); - } - - // - if (pivot.IsVale()) - { - // - iObj.PivotWidth(1); - iObj.PivotFill(false); - iObj.PivotStyle(STYLE_SOLID); - iObj.PivotColor(clrMagenta); - } - - // - AddObjectIfNotExists(iObj); - } + conditions.Clean(); + return result; } + conditions.visionConditions.state = mVisionState; // if (!result) @@ -524,2079 +437,6 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } - /** - * Detect XPV Based POI(s) ... - * - * @param barIndex: Start Bar Index ... - * @param minRepetition: minimum Repeate of POI for Validation ... - * @param requiredPivots: Number of Min Requirement POI(s) ... - * @param pivotHelper: XC121SMCCycleHelper instance Pointer ... - * @param orderFlow: XPVPivot instance Array Reference ... - * @param orderFlowDirection: ENUM_X_DIRECTION member Reference which represents OrderFlow Direction ... - * @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ... - * - * @return ( bool ) - */ - bool DetectOrderFlow( - int barIndex, - int minRepetition, - int requiredPivots, - XC121SMCCycleHelper *pivotHelper, // XPV Helper ... - XPVPivot &orderFlow[], // OrderFlows ... - ENUM_X_DIRECTION &orderFlowDirection, // Order Flow Direction ... - // - bool useVisionState = true, // Use Vision State ... - bool useConsolidationState = true, // Use Consolidation State ... - bool useVerificationState = true, // Use Verification State ... - bool useAnalyseState = true, // Use Analyse State ... - bool useDecisionState = true, // Use Decision State ... - bool useTriggerState = true, // Use Trigger State ... - // - int maxAllowedLoopbackBars = 576 // - ) - { - // - bool result = false; - - // - orderFlowDirection = X_DIRECTION_NONE; - - // - if (maxAllowedLoopbackBars <= 0) - { - maxAllowedLoopbackBars = 1000; - } - - // - int start = barIndex; - int end = start + maxAllowedLoopbackBars; - - // - Clean(orderFlow); - - // - result = minRepetition > 0 && - requiredPivots > 0 && - pivotHelper != NULL; - if (!result) - { - return result; - } - - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - double peak = 0; - XPVPivot peaks[]; - int peakRepeate = 0; - int peakToBarIndex = 0; - int peakFromBarIndex = 0; - - // - double vale = 0; - XPVPivot vales[]; - int valeRepeate = 0; - int valeToBarIndex = 0; - int valeFromBarIndex = 0; - - // - bool canLookupPeak = true; - bool canLookupVale = true; - bool canLookup = true; - while (canLookup) - { - // - // Check Peak ... - double iPeak = pivotHelper.mXPVHelper.GetPeak(barIndex); - if (iPeak != peak) - { - // - if (peak != 0 && - peakRepeate >= minRepetition) - { - // - bool isExists = false; - int count = ArraySize(peaks); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = peaks[i]; - - // - if (iPivot.upper == iPeak) - { - // - isExists = true; - break; - } - } - } - if (!isExists) - { - // - XPVPivot iPivot; - - // - iPivot.lower = 0; - iPivot.upper = peak; - iPivot.symbol = symbol; - iPivot.period = period; - iPivot.type = XPV_PEAK; - iPivot.repetition = peakRepeate; - iPivot.to = iTime( - symbol, - period, - peakToBarIndex // - ); - iPivot.from = iTime( - symbol, - period, - peakFromBarIndex // - ); - - // - iPivot.lower = iPivot.CalculateLower(); - - // - bool isValid = iPivot.IsValid(); - if (isValid) - { - // - AddRef( - iPivot, - peaks // - ); - } - } - } - - // - peak = iPeak; - peakRepeate = 0; - peakFromBarIndex = 0; - peakToBarIndex = barIndex; - } - else if (iPeak == peak) - { - // - peakRepeate++; - peakFromBarIndex = barIndex; - } - - // - // Check Vale ... - double iVale = pivotHelper.mXPVHelper.GetVale(barIndex); - if (iVale != vale) - { - // - if (vale != 0 && - valeRepeate >= minRepetition) - { - // - bool isExists = false; - int count = ArraySize(vales); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XPVPivot iPivot = vales[i]; - - // - if (iPivot.lower == iVale) - { - // - isExists = true; - break; - } - } - } - if (!isExists) - { - // - XPVPivot iPivot; - - // - iPivot.upper = 0; - iPivot.lower = vale; - iPivot.symbol = symbol; - iPivot.period = period; - iPivot.type = XPV_VALE; - iPivot.repetition = valeRepeate; - iPivot.to = iTime( - symbol, - period, - valeToBarIndex // - ); - iPivot.from = iTime( - symbol, - period, - valeFromBarIndex // - ); - - // - iPivot.upper = iPivot.CalculateUpper(); - - // - bool isValid = iPivot.IsValid(); - if (isValid) - { - // - AddRef( - iPivot, - vales // - ); - } - } - } - - // - vale = iVale; - valeRepeate = 0; - valeFromBarIndex = 0; - valeToBarIndex = barIndex; - } - else if (iVale == vale) - { - // - valeRepeate++; - valeFromBarIndex = barIndex; - } - - // - canLookupPeak = ArraySize(peaks) < requiredPivots; - canLookupVale = ArraySize(vales) < requiredPivots; - canLookup = barIndex < end && - (canLookupPeak || - canLookupVale); - if (canLookup) - { - barIndex++; - } - } - - // - result = IsValidSize(ArraySize(peaks)) || - IsValidSize(ArraySize(vales)); - if (!result) - { - return result; - } - - // - // Detect Order Flow ... - Copy( - peaks, - orderFlow, - false // - ); - Copy( - vales, - orderFlow, - false // - ); - int count = ArraySize(orderFlow); - result = IsValidSize(orderFlow); - if (!result) - { - return result; - } - - // - // Sort Pivots ... - SortPivots(orderFlow); - - // - // Filter Broken Order Flows ... - FilterBrokenPivots(orderFlow); - - // - // Detect Order Flow Direction ... - result = DetectPivotDirection( - orderFlow, - orderFlowDirection // - ); - if (!result) - { - return result; - } - - // - // Find State Inside Pivots and Attached Them to Pivot ... - int orderFlowCount = ArraySize(mOrderFlow); - if (IsValidSize(orderFlowCount)) - { - // - // Loop Through Order Flow ... - for (int i = 0; i < orderFlowCount; i++) - { - // - FillPivotSate( - i, - useVisionState, // Use Vision State ... - useConsolidationState, // Use Consolidation State ... - useVerificationState, // Use Verification State ... - useAnalyseState, // Use Analyse State ... - useDecisionState, // Use Decision State ... - useTriggerState // Use Trigger State ... - ); - } - } - - // - return result; - } - - /** - * Filling Specified Orer Flow Index ... - * - * @param pivotIDX: Integer ... - * @param lookupSwingHighs: Boolean ... - * @param lookupSwingLows: Boolean ... - * @param lookupSupportZones: Boolean ... - * @param lookupResistanceZones: Boolean ... - * @param lookupSupplyZones: Boolean ... - * @param lookupDemandZones: Boolean ... - * @param lookupBullishOrderBlocks: Boolean ... - * @param lookupBearishOrderBlocks: Boolean ... - * @param lookupBullishFairValueGaps: Boolean ... - * @param lookupBearishFairValueGaps: Boolean ... - * @param lookupBullishRejectionBars: Boolean ... - * @param lookupBearishRejectionBars: Boolean ... - * @param lookupBullishMomentumBars: Boolean ... - * @param lookupBearishMomentumBars: Boolean ... - */ - void FillPivotSate( - int pivotIDX, // - bool useVisionState = true, // Use Vision State ... - bool useConsolidationState = true, // Use Consolidation State ... - bool useVerificationState = true, // Use Verification State ... - bool useAnalyseState = true, // Use Analyse State ... - bool useDecisionState = true, // Use Decision State ... - bool useTriggerState = true, // Use Trigger State ... - bool lookupSwingHighs = true, - bool lookupSwingLows = true, - bool lookupSupportZones = true, - bool lookupResistanceZones = true, - bool lookupSupplyZones = true, - bool lookupDemandZones = true, - bool lookupBullishOrderBlocks = true, - bool lookupBearishOrderBlocks = true, - bool lookupBullishFairValueGaps = true, - bool lookupBearishFairValueGaps = true, - bool lookupBullishRejectionBars = true, - bool lookupBearishRejectionBars = true, - bool lookupBullishMomentumBars = true, - bool lookupBearishMomentumBars = true // - ) - { - // - CalculatePivotTickZone(pivotIDX); - - // - // Trigger ... - XPOIState mPivotTriggerState; - if (useTriggerState && - mTriggerState.HasChild()) - { - // - DetectPivotPOIs( - mOrderFlow[pivotIDX], - mTriggerState, - mPivotTriggerState, - lookupSwingHighs, - lookupSwingLows, - lookupSupportZones, - lookupResistanceZones, - lookupSupplyZones, - lookupDemandZones, - lookupBullishOrderBlocks, - lookupBearishOrderBlocks, - lookupBullishFairValueGaps, - lookupBearishFairValueGaps, - lookupBullishRejectionBars, - lookupBearishRejectionBars, - lookupBullishMomentumBars, - lookupBearishMomentumBars // - ); - - // - if (mPivotTriggerState.HasChild()) - { - mPivotTriggerState.Fill(mOrderFlow[pivotIDX].state); - } - } - - // - // Decision ... - XPOIState mPivotDecisionState; - if (useDecisionState && - mDecisionState.HasChild()) - { - // - DetectPivotPOIs( - mOrderFlow[pivotIDX], - mDecisionState, - mPivotDecisionState, - lookupSwingHighs, - lookupSwingLows, - lookupSupportZones, - lookupResistanceZones, - lookupSupplyZones, - lookupDemandZones, - lookupBullishOrderBlocks, - lookupBearishOrderBlocks, - lookupBullishFairValueGaps, - lookupBearishFairValueGaps, - lookupBullishRejectionBars, - lookupBearishRejectionBars, - lookupBullishMomentumBars, - lookupBearishMomentumBars // - ); - - // - if (mPivotDecisionState.HasChild()) - { - mPivotDecisionState.Fill(mOrderFlow[pivotIDX].state); - } - } - - // - // Analyse ... - XPOIState mPivotAnalyseState; - if (useAnalyseState && - mAnalyseState.HasChild()) - { - // - DetectPivotPOIs( - mOrderFlow[pivotIDX], - mAnalyseState, - mPivotAnalyseState, - lookupSwingHighs, - lookupSwingLows, - lookupSupportZones, - lookupResistanceZones, - lookupSupplyZones, - lookupDemandZones, - lookupBullishOrderBlocks, - lookupBearishOrderBlocks, - lookupBullishFairValueGaps, - lookupBearishFairValueGaps, - lookupBullishRejectionBars, - lookupBearishRejectionBars, - lookupBullishMomentumBars, - lookupBearishMomentumBars // - ); - - // - if (mPivotAnalyseState.HasChild()) - { - mPivotAnalyseState.Fill(mOrderFlow[pivotIDX].state); - } - } - - // - // Verification ... - XPOIState mPivotVerificationState; - if (useVerificationState && - mVerificationState.HasChild()) - { - // - DetectPivotPOIs( - mOrderFlow[pivotIDX], - mVerificationState, - mPivotVerificationState, - lookupSwingHighs, - lookupSwingLows, - lookupSupportZones, - lookupResistanceZones, - lookupSupplyZones, - lookupDemandZones, - lookupBullishOrderBlocks, - lookupBearishOrderBlocks, - lookupBullishFairValueGaps, - lookupBearishFairValueGaps, - lookupBullishRejectionBars, - lookupBearishRejectionBars, - lookupBullishMomentumBars, - lookupBearishMomentumBars // - ); - - // - if (mPivotVerificationState.HasChild()) - { - mPivotVerificationState.Fill(mOrderFlow[pivotIDX].state); - } - } - - // - // Consolidation ... - XPOIState mPivotConsolidationState; - if (useConsolidationState && - mConsolidationState.HasChild()) - { - // - DetectPivotPOIs( - mOrderFlow[pivotIDX], - mConsolidationState, - mPivotConsolidationState, - lookupSwingHighs, - lookupSwingLows, - lookupSupportZones, - lookupResistanceZones, - lookupSupplyZones, - lookupDemandZones, - lookupBullishOrderBlocks, - lookupBearishOrderBlocks, - lookupBullishFairValueGaps, - lookupBearishFairValueGaps, - lookupBullishRejectionBars, - lookupBearishRejectionBars, - lookupBullishMomentumBars, - lookupBearishMomentumBars // - ); - - // - if (mPivotConsolidationState.HasChild()) - { - mPivotConsolidationState.Fill(mOrderFlow[pivotIDX].state); - } - } - - // - // Vision ... - XPOIState mPivotVisionState; - if (useVisionState && - mVisionState.HasChild()) - { - // - DetectPivotPOIs( - mOrderFlow[pivotIDX], - mVisionState, - mPivotVisionState, - lookupSwingHighs, - lookupSwingLows, - lookupSupportZones, - lookupResistanceZones, - lookupSupplyZones, - lookupDemandZones, - lookupBullishOrderBlocks, - lookupBearishOrderBlocks, - lookupBullishFairValueGaps, - lookupBearishFairValueGaps, - lookupBullishRejectionBars, - lookupBearishRejectionBars, - lookupBullishMomentumBars, - lookupBearishMomentumBars // - ); - - // - if (mPivotVisionState.HasChild()) - { - mPivotVisionState.Fill(mOrderFlow[pivotIDX].state); - } - } - } - - /** - * When a BOS Happens ... - * we have to Update Order Flow ... - */ - void UpdateOrderFlow() - { - ResetOrderFlow(); - } - - /** - * Fill Pivot Tick Zone ... - * - * @param pivotIDX: Integer ... - */ - void CalculatePivotTickZone(int pivotIDX) - { - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - - // - bool isInited = false; - - // - datetime from = mOrderFlow[pivotIDX].from; - XOHCL iFromBar; - int iFromBarIndex = iBarShift( - symbol, - period, - from // - ); - isInited = iFromBar.Init( - symbol, - period, - iFromBarIndex // - ); - if (!isInited) - { - return; - } - - // - datetime to = mOrderFlow[pivotIDX].to; - XOHCL iToBar; - int iToBarIndex = iBarShift( - symbol, - period, - to // - ); - isInited = iToBar.Init( - symbol, - period, - iToBarIndex // - ); - if (!isInited) - { - return; - } - - // - XCTicksZone *iZone; - iZone = new XCTicksZone(); - - // - int ticksLevels = mTriggerDetector.TicksRangeZoneLevel(); - int ticksRange = mTriggerDetector.TicksRangeZoneRange(); - isInited = ticksLevels > 0 && - ticksRange > 0; - if (!isInited) - { - return; - } - - // - isInited = iZone.Init( - iFromBar, - iToBar // - ); - if (!isInited) - { - return; - } - - // - mOrderFlow[pivotIDX].state.ticksZone = iZone; - } - - /** - * Validate Order Flow ... - * - * @return ( bool ) - */ - bool HasValidOrderFlow() - { - // - bool result = false; - - // - int orderFlowCount = ArraySize(mOrderFlow); - result = - IsValidSize(orderFlowCount) && - mOrderFlowDir != X_DIRECTION_ALL && - mOrderFlowDir != X_DIRECTION_NONE; - - // - return result; - } - - /** - * Reset Order Flow ... - */ - void ResetOrderFlow() - { - // - Clean(mOrderFlow); - mOrderFlowDir = X_DIRECTION_NONE; - - // - ClearDraws(); - } - - /** - * Detect Breaker Bar ... - * - * @param bar: XOHCL instance ... - * @param breakerBar: XOHCL instance, Breaker Bar ... - * @param pivot: XPVPivot instance ... - * @param forDir: ENUM_X_DIRECTION member, Market Structure Direction ... - * - * @return ( bool ) - */ - bool DetectLastBreakerBar( - XOHCL &bar, - XOHCL &breakerBar, - XPVPivot &pivot, - ENUM_X_DIRECTION forDir // - ) - { - // - bool result = false; - - // - result = - bar.IsValid() && - pivot.IsValid() && - forDir != X_DIRECTION_ALL && - forDir != X_DIRECTION_NONE; - if (!result) - { - return result; - } - - // - // FVG ... - result = DetectLastFVGBreakerBar( - bar, - breakerBar, - pivot, - forDir // - ); - if (result) - { - return result; - } - - // - // Order Block ... - // result = DetectLastOBBreakerBar( - // bar, - // breakerBar, - // pivot, - // forDir // - // ); - // if (result) - // { - // return result; - // } - - // - return result; - } - - bool DetectLastFVGBreakerBar( - XOHCL &bar, - XOHCL &breakerBar, - XPVPivot &pivot, - ENUM_X_DIRECTION forDir // - ) - { - // - bool result = false; - - // - result = - bar.IsValid() && - pivot.IsValid() && - forDir != X_DIRECTION_ALL && - forDir != X_DIRECTION_NONE; - if (!result) - { - return result; - } - - // - bool isBullishDir = IsBullish(forDir); - - // - int fvgsCount = - isBullishDir - ? pivot.state.CountBullishFairValueGaps() - : pivot.state.CountBearishFairValueGaps(); - result = IsValidSize(fvgsCount); - if (!result) - { - return result; - } - - // - int idx = -1; - XCFVG *zone = NULL; - for (int i = 0; i < fvgsCount; i++) - { - // - if (isBullishDir) - { - // - // Bullish FVG ... - if (zone == NULL) - { - // - zone = pivot.state.bullishFairValueGaps[i]; - - // - bool isBreaked = CheckZoneBreak( - forDir, - bar, - breakerBar, - zone // - ); - if (isBreaked) - { - idx = i; - } - } - else - { - // - bool isNewer = ((int)zone.From() - (int)bar.time) > ((int)pivot.state.bullishFairValueGaps[i].From() - (int)bar.time); - if (isNewer) - { - // - zone = pivot.state.bullishFairValueGaps[i]; - - // - bool isBreaked = CheckZoneBreak( - forDir, - bar, - breakerBar, - zone // - ); - if (isBreaked) - { - idx = i; - } - } - } - } - else - { - // - // Bearish FVG ... - if (zone == NULL) - { - // - zone = pivot.state.bearishFairValueGaps[i]; - - // - bool isBreaked = CheckZoneBreak( - forDir, - bar, - breakerBar, - zone // - ); - if (isBreaked) - { - idx = i; - } - } - else - { - // - bool isNewer = ((int)zone.From() - (int)bar.time) > ((int)pivot.state.bearishFairValueGaps[i].From() - (int)bar.time); - if (isNewer) - { - // - zone = pivot.state.bearishFairValueGaps[i]; - - // - bool isBreaked = CheckZoneBreak( - forDir, - bar, - breakerBar, - zone // - ); - if (isBreaked) - { - idx = i; - } - } - } - } - } - - // - result = - breakerBar.IsValid() && - IsValidIndex(idx) && - zone.IsValid(); - if (!result) - { - return result; - } - - // - return result; - } - - /** - * Check an FVG is Breaked or not ... - * - * @param forDir: ENUM_X_DIRECTION member, Market Structure Direction ... - * @param bar: XOHCL instance ... - * @param breakerBar: XOHCL instance, Breaker Bar ... - * - * @return ( bool ) - */ - bool CheckZoneBreak( - ENUM_X_DIRECTION forDir, - XOHCL &bar, - XOHCL &breakerBar, - XCFVG *&zone // - ) - { - // - bool result = false; - - // - breakerBar.Clean(); - - // - result = bar.IsValid() && - zone.IsValid() && - forDir != X_DIRECTION_ALL && - forDir != X_DIRECTION_NONE; - if (!result) - { - return result; - } - - // - int start = bar.Index(); - int end = iBarShift( - bar.symbol, - bar.period, - zone.From()); - for (int i = start; i < end; i++) - { - // - XOHCL iBar; - result = iBar.Init( - bar.symbol, - bar.period, - i // - ); - if (!result) - { - break; - } - - // - if (IsBullish(forDir)) - { - // - // Bullish Break ... - result = iBar.low < zone.Upper() && - iBar.high > zone.Upper() && - iBar.GetDown() < zone.Upper() && - iBar.GetUp() > zone.Upper() && - iBar.IsBullish(); - } - else - { - // - // Bearish Break ... - result = iBar.low < zone.Lower() && - iBar.high > zone.Lower() && - iBar.GetDown() < zone.Lower() && - iBar.GetUp() > zone.Lower() && - iBar.IsBearish(); - } - - // - if (result) - { - // - breakerBar = iBar; - break; - } - } - - // - result = breakerBar.IsValid(); - - // - return result; - } - - /** - * Detect most Upper and Lower Order Blocks ... - * - * @return ( bool ) - */ - bool DetectOrderBlocks( - XCOrderBlock *bullOBBoundary, - XCOrderBlock *bearOBBoundary, - XCOrderBlock *&bullOB, - XCOrderBlock *&bearOB, - XOHCL &bar, - XPOIState &state // - ) - { - // - bool result = false; - - // - result = bar.IsValid() && - state.IsValid(); - if (!result) - { - return result; - } - - // - XCOrderBlock *mBullOB = NULL; - if (bullOB == NULL) - { - // - for (int i = 0; i < state.CountBullishOrderBlocks(); i++) - { - // - XCOrderBlock *ob = state.bullishOrderBlocks[i]; - bool isPricePassed = bar.low > ob.Upper(); - if (isPricePassed) - { - // - bool isBoundaryPassed = - bullOBBoundary == NULL - ? true - : ob.Lower() < bullOBBoundary.Upper(); - if (isBoundaryPassed) - { - // - if (mBullOB == NULL) - { - mBullOB = ob; - } - else - { - // - bool isRefined = - mBullOB.Upper() < ob.Upper(); - if (isRefined) - { - mBullOB = ob; - } - } - } - } - } - - // - if (mBullOB != NULL) - { - bullOB = mBullOB; - } - } - - // - XCOrderBlock *mBearOB = NULL; - if (bearOB == NULL) - { - // - for (int i = 0; i < state.CountBearishOrderBlocks(); i++) - { - // - XCOrderBlock *ob = state.bearishOrderBlocks[i]; - bool isPricePassed = bar.high < ob.Lower(); - if (isPricePassed) - { - // - bool isBoundaryPassed = - bearOBBoundary == NULL - ? true - : ob.Upper() > bearOBBoundary.Lower(); - if (isBoundaryPassed) - { - // - if (mBearOB == NULL) - { - mBearOB = ob; - } - else - { - // - bool isRefined = - mBearOB.Lower() > ob.Lower(); - if (isRefined) - { - mBearOB = ob; - } - } - } - } - } - - // - if (mBearOB != NULL) - { - bearOB = mBearOB; - } - } - - // - result = bullOB != NULL && - bearOB != NULL; - - // - return result; - } - - // - // Drawings ... - - /** - * Draw Order Flow ... - */ - void RedrawOrderFlow( - bool forceClearDraws = true, - bool forceDrawSamePeriod = true, - bool drawOrderFlow = true, - bool drawOrderFlowState = true, - bool drawOnlyLastOrderFlow = false, - bool drawOnlyLastOrderFlowState = true, - // - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, - // - // Ignores List ... - bool ignoreSwingHighs = false, - bool ignoreSwingLows = false, - bool ignoreSupportZones = false, - bool ignoreResistanceZones = false, - bool ignoreSupplyZones = false, - bool ignoreDemandZones = false, - bool ignoreBullishOrderBlocks = false, - bool ignoreBearishOrderBlocks = false, - bool ignoreBullishFairValueGaps = false, - bool ignoreBearishFairValueGaps = false, - bool ignoreBullishRejectionBars = false, - bool ignoreBearishRejectionBars = false, - bool ignoreBullishMomentumBars = false, - bool ignoreBearishMomentumBars = false, - // - // States Drawing ... - bool drawVisionState = false, - bool drawConsolidationState = false, - bool drawVerificationState = false, - bool drawAnalyseState = false, - bool drawDecisionState = false, - bool drawTriggerState = false // - ) - { - // - if (forceClearDraws) - { - ClearDraws(); - } - - // - if (!drawOrderFlow || - !HasValidOrderFlow()) - { - return; - } - - // - int orderFlowCount = ArraySize(mOrderFlow); - for (int i = 0; i < orderFlowCount; i++) - { - // - bool isLast = i == orderFlowCount - 1; - bool canDraw = - !drawOnlyLastOrderFlow || - (isLast && - drawOnlyLastOrderFlow); - if (!canDraw) - { - continue; - } - - // - XPVPivot iPivot = mOrderFlow[i]; - - // - XCXPVPivotObject *iObj; - iObj = new XCXPVPivotObject(); - bool isCreated = iObj.Create( - mPOIDrawer.ChartIdentification(), - mPOIDrawer.SubWindowIdentification(), - iPivot // - ); - if (isCreated) - { - // - bool canDrawState = - drawOrderFlowState && - (!drawOnlyLastOrderFlowState || - (isLast && - drawOnlyLastOrderFlowState)); - if (canDrawState) - { - // - CustomStateDrawing( - iPivot.state, - forceDrawSamePeriod, - forDir, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - - // - if (iPivot.IsPeak()) - { - // - iObj.PivotWidth(1); - iObj.PivotFill(false); - iObj.PivotColor(clrAqua); - iObj.PivotStyle(STYLE_SOLID); - } - - // - if (iPivot.IsVale()) - { - // - iObj.PivotWidth(1); - iObj.PivotFill(false); - iObj.PivotStyle(STYLE_SOLID); - iObj.PivotColor(clrMagenta); - } - - // - AddObjectIfNotExists(iObj); - } - } - - // - // Draw States ... - - // - // Vision ... - if (drawVisionState) - { - // - CustomStateDrawing( - mVisionState, - false, - forDir, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - - // - // Consolidation ... - if (drawConsolidationState) - { - // - CustomStateDrawing( - mConsolidationState, - false, - forDir, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - - // - // Verification ... - if (drawVerificationState) - { - // - CustomStateDrawing( - mVerificationState, - false, - forDir, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - - // - // Analyse ... - if (drawAnalyseState) - { - // - CustomStateDrawing( - mAnalyseState, - false, - forDir, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - - // - // Decision ... - if (drawDecisionState) - { - // - CustomStateDrawing( - mDecisionState, - false, - forDir, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - - // - // Trigger ... - if (drawTriggerState) - { - // - CustomStateDrawing( - mTriggerState, - false, - forDir, - ignoreSwingHighs, - ignoreSwingLows, - ignoreSupportZones, - ignoreResistanceZones, - ignoreSupplyZones, - ignoreDemandZones, - ignoreBullishOrderBlocks, - ignoreBearishOrderBlocks, - ignoreBullishFairValueGaps, - ignoreBearishFairValueGaps, - ignoreBullishRejectionBars, - ignoreBearishRejectionBars, - ignoreBullishMomentumBars, - ignoreBearishMomentumBars // - ); - } - } - - /** - * Custom Drawing State ... - * - * @param state: XPOIState instance reference, Specified Which state to Draw ... - * @param forceDrawSamePeriod: Boolean ... - */ - void CustomStateDrawing( - XPOIState &state, - bool forceDrawSamePeriod = false, - ENUM_X_DIRECTION forDir = X_DIRECTION_NONE, - // - // Ignores List ... - bool ignoreSwingHighs = false, - bool ignoreSwingLows = false, - bool ignoreSupportZones = false, - bool ignoreResistanceZones = false, - bool ignoreSupplyZones = false, - bool ignoreDemandZones = false, - bool ignoreBullishOrderBlocks = false, - bool ignoreBearishOrderBlocks = false, - bool ignoreBullishFairValueGaps = false, - bool ignoreBearishFairValueGaps = false, - bool ignoreBullishRejectionBars = false, - bool ignoreBearishRejectionBars = false, - bool ignoreBullishMomentumBars = false, - bool ignoreBearishMomentumBars = false // - ) - { - // - XPOIState tmpState = state; - if (forceDrawSamePeriod) - { - // - int count = 0; - ENUM_TIMEFRAMES period = GetPeriod(); - - // - count = state.CountSwingHighs(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing iSwing = state.swingHighs[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.swingHighs, - i, - 1 // - ); - } - } - } - - // - count = state.CountSwingLows(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSwing iSwing = state.swingLows[i]; - - // - XOHCL iBar; - bool isFilled = iSwing.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.swingLows, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishMomentumBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar iMomentum = state.bullishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishMomentumBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishMomentumBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCMomentumBar iMomentum = state.bearishMomentumBars[i]; - - // - XOHCL iBar; - bool isFilled = iMomentum.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishMomentumBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishRejectionBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar iRejection = state.bullishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishRejectionBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishRejectionBars(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCRejectionBar iRejection = state.bearishRejectionBars[i]; - - // - XOHCL iBar; - bool isFilled = iRejection.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishRejectionBars, - i, - 1 // - ); - } - } - } - - // - count = state.CountSupportZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupportZone iZone = state.supportZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.supportZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountResistanceZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCResistanceZone iZone = state.resistanceZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.resistanceZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountSupplyZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCSupplyZone iZone = state.supplyZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.supplyZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountDemandZones(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCDemandZone iZone = state.demandZones[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.demandZones, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock iZone = state.bullishOrderBlocks[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishOrderBlocks, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishOrderBlocks(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCOrderBlock iZone = state.bearishOrderBlocks[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishOrderBlocks, - i, - 1 // - ); - } - } - } - - // - count = state.CountBullishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG iZone = state.bullishFairValueGaps[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillStartBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bullishFairValueGaps, - i, - 1 // - ); - } - } - } - - // - count = state.CountBearishFairValueGaps(); - if (IsValidSize(count)) - { - // - for (int i = 0; i < count; i++) - { - // - XCFVG iZone = state.bearishFairValueGaps[i]; - - // - XOHCL iBar; - bool isFilled = iZone.FillStartBar(iBar); - if (!isFilled) - { - continue; - } - - // - bool isSamePeriod = iBar.period == period; - if (!isSamePeriod) - { - // - ArrayRemove( - tmpState.bearishFairValueGaps, - i, - 1 // - ); - } - } - } - - // - } - - // - bool drawSwingHighs = true; - bool drawSwingLows = true; - bool drawSupportZones = true; - bool drawResistanceZones = true; - bool drawSupplyZones = true; - bool drawDemandZones = true; - bool drawBullishOrderBlocks = true; - bool drawBearishOrderBlocks = true; - bool drawBullishFairValueGaps = true; - bool drawBearishFairValueGaps = true; - bool drawBullishRejectionBars = true; - bool drawBearishRejectionBars = true; - bool drawBullishMomentumBars = true; - bool drawBearishMomentumBars = true; - - // - // Change Drawing Specs Conditions based on - // Provided Direction ... - if (forDir == X_DIRECTION_BULLISH) - { - // - drawSwingLows = true; - drawDemandZones = true; - drawSupportZones = true; - drawBullishOrderBlocks = true; - drawBullishFairValueGaps = true; - drawBullishRejectionBars = true; - drawBullishMomentumBars = true; - - // - drawSwingHighs = false; - drawSupplyZones = false; - drawResistanceZones = false; - drawBearishOrderBlocks = false; - drawBearishFairValueGaps = false; - drawBearishRejectionBars = false; - drawBearishMomentumBars = false; - } - else if (forDir == X_DIRECTION_BEARISH) - { - // - drawSwingLows = false; - drawDemandZones = false; - drawSupportZones = false; - drawBullishOrderBlocks = false; - drawBullishFairValueGaps = false; - drawBullishRejectionBars = false; - drawBullishMomentumBars = false; - - // - drawSwingHighs = true; - drawSupplyZones = true; - drawResistanceZones = true; - drawBearishOrderBlocks = true; - drawBearishFairValueGaps = true; - drawBearishRejectionBars = true; - drawBearishMomentumBars = true; - } - - // - // Apply Ignore List ... - - // - if (ignoreSwingHighs) - { - drawSwingHighs = false; - } - - // - if (ignoreSwingLows) - { - drawSwingLows = false; - } - - // - if (ignoreSupportZones) - { - drawSupportZones = false; - } - - // - if (ignoreResistanceZones) - { - drawResistanceZones = false; - } - - // - if (ignoreSupplyZones) - { - drawSupplyZones = false; - } - - // - if (ignoreDemandZones) - { - drawDemandZones = false; - } - - // - if (ignoreBullishOrderBlocks) - { - drawBullishOrderBlocks = false; - } - - // - if (ignoreBearishOrderBlocks) - { - drawBearishOrderBlocks = false; - } - - // - if (ignoreBullishFairValueGaps) - { - drawBullishFairValueGaps = false; - } - - // - if (ignoreBearishFairValueGaps) - { - drawBearishFairValueGaps = false; - } - - // - if (ignoreBullishRejectionBars) - { - drawBullishRejectionBars = false; - } - - // - if (ignoreBearishRejectionBars) - { - drawBearishRejectionBars = false; - } - - // - if (ignoreBullishMomentumBars) - { - drawBullishMomentumBars = false; - } - - // - if (ignoreBearishMomentumBars) - { - drawBearishMomentumBars = false; - } - - // - DrawState( - tmpState, // State ... - true, // Update To of all Drawings Till now ... - drawSwingHighs, // Draw SwingHighs .. - drawSwingLows, // Draw SwingLows .. - drawSupportZones, // Draw SupportZones .. - drawResistanceZones, // Draw ResistanceZones .. - drawSupplyZones, // Draw SupplyZones .. - drawDemandZones, // Draw DemandZones .. - drawBullishOrderBlocks, // Draw BullishOrderBlocks .. - drawBearishOrderBlocks, // Draw BearishOrderBlocks .. - drawBullishFairValueGaps, // Draw BullishFairValueGaps .. - drawBearishFairValueGaps, // Draw BearishFairValueGaps .. - drawBullishRejectionBars, // Draw BullishRejectionBars .. - drawBearishRejectionBars, // Draw BearishRejectionBars .. - drawBullishMomentumBars, // Draw BullishMomentumBars .. - drawBearishMomentumBars, // Draw BearishMomentumBars .. - true // Draw Ticks Zone ... - ); - } - // // Private ... private: @@ -2634,88 +474,20 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // XPV ... - XPVInputs xpvInputs; + X121Inputs x121Inputs; // - xpvInputs.Default(); + x121Inputs.Default(); // - xpvInputs.scMethod = scMethod; - xpvInputs.scPeriod = scPeriod; - xpvInputs.mcMethod = mcMethod; - xpvInputs.mcPeriod = mcPeriod; - xpvInputs.lcMethod = lcMethod; - xpvInputs.lcPeriod = lcPeriod; - xpvInputs.hcMethod = hcMethod; - xpvInputs.hcPeriod = hcPeriod; - - // - xpvInputs.showPeaksAndVales = true; - xpvInputs.showLevels = false; - xpvInputs.showConsolidations = false; - xpvInputs.showFibo1Levels = false; - xpvInputs.showFibo2Levels = false; - xpvInputs.showFibo3Levels = false; - xpvInputs.showFibo4Levels = false; - xpvInputs.showFibo5Levels = false; - - // - // X3MA ... - X3MAInputs x3maInputs; - - // - x3maInputs.Default(); - - // - // x3maInputs.fastLength = 10; - // x3maInputs.midLength = 25; - // x3maInputs.slowLength = 50; - - // - x3maInputs.showFast = true; - x3maInputs.showMid = false; - x3maInputs.showSlow = false; - - // - // X3VWAP ... - X3VWAPInputs x3vwapInputs; - - // - x3vwapInputs.Default(); - - // - // x3vwapInputs.fastLength = 10; - // x3vwapInputs.midLength = 25; - // x3vwapInputs.slowLength = 50; - - // - x3vwapInputs.showFast = true; - x3vwapInputs.showMid = true; - x3vwapInputs.showSlow = true; - - // - // XCHSAR ... - XCHSARInputs xchsarInputs; - - // - xchsarInputs.Default(); - - // - xchsarInputs.scMethod = scMethod; - xchsarInputs.scPeriod = scPeriod; - xchsarInputs.mcMethod = mcMethod; - xchsarInputs.mcPeriod = mcPeriod; - xchsarInputs.lcMethod = lcMethod; - xchsarInputs.lcPeriod = lcPeriod; - xchsarInputs.hcMethod = hcMethod; - xchsarInputs.hcPeriod = hcPeriod; - - // - xchsarInputs.showCurrent = true; - xchsarInputs.showShort = false; - xchsarInputs.showMedium = false; - xchsarInputs.showLong = false; - xchsarInputs.showHind = false; + x121Inputs.scMethod = scMethod; + x121Inputs.scPeriod = scPeriod; + x121Inputs.mcMethod = mcMethod; + x121Inputs.mcPeriod = mcPeriod; + x121Inputs.lcMethod = lcMethod; + x121Inputs.lcPeriod = lcPeriod; + x121Inputs.hcMethod = hcMethod; + x121Inputs.hcPeriod = hcPeriod; // // Initialize Cycle Helpers ... @@ -2725,10 +497,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy mTriggerCycleHelper.Init( symbol, PERIOD_M1, - xpvInputs, - x3maInputs, - x3vwapInputs, - xchsarInputs // + x121Inputs // ); // @@ -2736,10 +505,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy mDecisionCycleHelper.Init( symbol, PERIOD_M5, - xpvInputs, - x3maInputs, - x3vwapInputs, - xchsarInputs // + x121Inputs // ); // @@ -2747,10 +513,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy mAnalyseCycleHelper.Init( symbol, PERIOD_M15, - xpvInputs, - x3maInputs, - x3vwapInputs, - xchsarInputs // + x121Inputs // ); // @@ -2758,10 +521,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy mVerificationCycleHelper.Init( symbol, PERIOD_M30, - xpvInputs, - x3maInputs, - x3vwapInputs, - xchsarInputs // + x121Inputs // ); // @@ -2769,10 +529,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy mConsolidationCycleHelper.Init( symbol, PERIOD_H1, - xpvInputs, - x3maInputs, - x3vwapInputs, - xchsarInputs // + x121Inputs // ); // @@ -2780,10 +537,7 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy mVisionCycleHelper.Init( symbol, PERIOD_H4, - xpvInputs, - x3maInputs, - x3vwapInputs, - xchsarInputs // + x121Inputs // ); }