/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class // ------------------------------------------------- // Name: XCXCATBEASignaller ... // Description: Class for XCATBEA Signaller ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm XCXCATBEASignaller Class" #property strict // // Imports ... #include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../../Classes/x-saherelm.x-guard.class.mq5" #include "../../Helpers/x-saherelm.x121.xcatb.helper.mq5" #include "../Classes/xcatbea.x-poi.detector.class.mq5" #include "../Classes/xcatbea.x-poi.drawer.class.mq5" #include "../Libraries/xcatbea.lib.mq5" #include "../Libraries/xcatbea.signaller.lib.mq5" #include "../Libraries/xcatbea.x-poi.extensions.lib.mq5" // // Definitions ... // struct XCATBEASignallerInputs { // // Pros ... string symbol; string provider; bool allowDraws; bool allowGuards; int riskToRewardRatio; ENUM_TIMEFRAMES period; double slATRMultiplier; X121XCatbInputs catbInputs; XTriggerBlockFilters filters; XTriggerBlockValidationRules validations; // // Constructor(s) ... XCATBEASignallerInputs() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // symbol = NULL; period = NULL; provider = NULL; filters.Clean(); catbInputs.Clean(); allowDraws = false; validations.Clean(); allowGuards = false; slATRMultiplier = 0; riskToRewardRatio = 0; // ZeroMemory(this); } // // Validate ... bool IsValid() { // bool result = false; // result = IsValid(symbol) && IsValid(period) && IsValid(provider) && catbInputs.IsValid() && riskToRewardRatio > 0; // return result; } // }; class XCXCATBEASignaller : XCBase { // // Public ... public: // // Props ... // bool allowDraws; // Allow Draws or not ... bool allowGuards; // Allow Guards or not ... int riskToRewardRatio; // Signals R2R ... double slATRMultiplier; // SL ATR Multiplier ... // XBarTracker barTraker; // Bar Tracker ... XCX121XCatbHelper *helper; // XCATB Helper Class instance ... XCBarAnalyser *barAnalyser; // Bar Analyser ... XCXCATBEAPOIDrawer *drawer; // POI Drawer ... XTriggerBlockFilters filters; // Trigger Block Filters ... XCXCATBEAPOIDetector *detector; // POI Detector ... XTriggerBlockValidationRules validations; // Trigger Block Validations ... // XBoxZone unavailableZones[]; // Un Available Zones ... // XCATBEAStrategyConditions mConditions; XCATBEAStrategyConditions mConditionsCollection[]; // // Constructor ... XCXCATBEASignaller(XCATBEASignallerInputs &inputs) { Init(inputs); } // // Deconstructor ... ~XCXCATBEASignaller() { DeInit(); } // // Properties ... // string GetSymbol() { return symbol; } // string GetProvider() { return provider; } // ENUM_TIMEFRAMES GetPeriod() { return period; } // double GetR2R() { return riskToRewardRatio; } // // Tick Analyser ... /** * Process Tick ... */ void ProcessTick( XPosition &positions[], XGuard &guards[], XCATBEAStrategyConditions &conditions, bool isActiveSession = true // ) { // Clean(guards); conditions.Clean(); // XOHCL bar; int count = 0; bool has = false; int barIndex = 0; // // Check Guards ... has = DetectGuards( guards, positions, barIndex // ); // // Check Triggered Conditions ... has = HasChild(mConditionsCollection); if (has) { // int selectedIDX = -1; count = ArraySize(mConditionsCollection); for (int i = 0; i < count; i++) { // // Select indexed Conditions ... XCATBEAStrategyConditions iConditions = mConditionsCollection[i]; // // Check Conditions Triggered ... has = DetectSignalTrigger( iConditions, barIndex // ); if (has) { // selectedIDX = i; conditions = iConditions; iConditions.Clean(); // break; } // // When Setup Invalidated // Signaller Clean Conditions ... if (!has && !iConditions.IsValid()) { // selectedIDX = i; break; } // // Cleanup Resources ... iConditions.Clean(); } // // Check Can Trigger ... has = IsValidIndex(selectedIDX) && conditions.IsValid() && conditions.IsSetuped() && conditions.CanTrigger(); if (has) { // ArrayRemove( mConditionsCollection, selectedIDX, 1 // ); } else { // // Check Selected Index for Invalid Conditions ... if (IsValidIndex(selectedIDX)) { // // Remove Invalidated Conditions ... ArrayRemove( mConditionsCollection, selectedIDX, 1 // ); } // // Cleanup Resource ... conditions.Clean(); } } // // Check Bar Processing ... if (!barTraker.CanProcessBar()) { return; } // // Initialize Bar ... bar.Init( symbol, period, barIndex // ); // // Detect POI(s) ... detector.Detect(barIndex); // // Validate POI(s) ... detector.Validate( unavailableZones, barIndex // ); // // Draw POI(s) ... if (allowDraws) { drawer.Draw(bar.time); } // // Here we Check Active Session ... // and Prevent Moving forward if there is not // Session actives ... // for improvement Calculation Speeds ... if (isActiveSession) { // // Check Signal Setups ... has = DetectSignalSetup(barIndex); if (has) { // barTraker.Waits(); // AddConditionsIfNotExists(); // mConditions.Clean(); } } // // Cleanup Resources ... bar.Clean(); } // // Signalling Tools ... /** * Detect Setup Conditions based on Signalling ... * * @param maxAllowedSLDistanceInPoint: int, Max Allowed SL Distance in Points (if Bigger thn Zero Provided) ... * * @return ( bool ) */ bool DetectSignalSetup(int barIndex = 0) { // bool result = false; // // Normalize Args ... barIndex = NormalizeInt(barIndex, 0); // // Update All Required Buffers ... helper.Update(barIndex); // // Trigger Block Detection ... result = DetectTriggerBlock( helper, barAnalyser, mConditions.triggerBlock, mConditions.conditions, validations, filters, barIndex, 10 // Loopback ... ); if (result) { // // Prepare Condition ... // // Prepare Signal ... mConditions.dir = mConditions .triggerBlock .GetDirection(); mConditions.symbol = symbol; mConditions.period = period; mConditions.provider = provider; mConditions.reward = riskToRewardRatio; mConditions.time = mConditions.conditions.bars[0].time; mConditions.setupTime = mConditions.conditions.bars[0].time; // // Prepare Target ... double targets[]; for (int i = 1; i <= riskToRewardRatio; i++) { // Add( (double)i, targets // ); } // // Calculate SL Additions ... double iATR = 0; if (barIndex > 0 && barIndex < ArraySize(helper.atrBuffer)) { iATR = helper.atrBuffer[barIndex]; } double slAdditional = slATRMultiplier * iATR; // // Preparing Signal ... result = ToSignal( mConditions.triggerBlock.trigger, mConditions.triggerBlock.signal, targets, slAdditional // ); if (result) { // mConditions.triggerBlock.signal.provider = provider; mConditions.sl = mConditions.triggerBlock.signal.sl; mConditions.tp = mConditions.triggerBlock.signal.tp; mConditions.pivot = mConditions.triggerBlock.signal.sl; mConditions.entry = mConditions.triggerBlock.signal.entry; mConditions.point = mConditions.triggerBlock.signal.entry; mConditions.type = ToPositionType(mConditions.triggerBlock.signal.type); // // Draw Trigger Block ... if (allowDraws) { // DrawTriggerBlock( mConditions.triggerBlock, drawer.drawer, mObjects, NULL, // To ... false // Draw Signal ... ); } } } // result = mConditions.IsValid() && mConditions.IsSetuped(); // // Cleanup Resource ... // return result; } /** * Detect Trigger Conditions for Specified Signal ... * * @param conditions: XCATBEAStrategyConditions instance Reference, Specified Signal Conditions ... * @param maxAllowedSetupAge: specified Setup Age for Expiration (if bigger than Zero) ... * * @return ( bool ) */ bool DetectSignalTrigger( XCATBEAStrategyConditions &conditions, int barIndex = 0 // ) { // bool result = false; // // Normalize Args ... barIndex = NormalizeInt(barIndex, 0); // // Validate Setup ... result = conditions.IsSetuped(); if (!result) { return result; } // bool isBullish = IsBullish(conditions.dir); bool isBearish = IsBearish(conditions.dir); // // Validate Direction of Setuped Conditions ... result = result && (isBullish || isBearish); // // Do Triggering Senario based on Trigger Block ... if (result && conditions.triggerBlock.IsValid()) { // // Checking Score ... double bullishScore = 0; double bearishScore = 0; conditions .conditions .GenerateScore( bullishScore, bearishScore // ); bool isScorePassed = isBullish ? bullishScore > bearishScore : bearishScore > bullishScore; // // Complete Conditions Here ... if (isScorePassed) { conditions.triggerTime = TimeCurrent(); } } // // Do Other Validation Senarios ... // result = conditions.IsValid() && conditions.IsSetuped() && conditions.CanTrigger(); // // Check Setup Age or Setup Validations here ... if (!result) { } // // Cleanup Resources ... // return result; } /** * Detect Guards bsed on Signalling Class ... * * @param guards: XCAEAGuard instance Collection, Holds Provided Guards ... * @param positions: XPosition instance Collection, Provides Signalling Based Positions for Apply Guards on them ... * @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ... * * @return ( bool ) */ bool DetectGuards( XGuard &guards[], const XPosition &positions[], int barIndex = 0 // ) { // bool result = false; // // Normalize Args ... Clean(guards); barIndex = NormalizeInt(barIndex, 0); // result = allowGuards && HasChild(positions); if (!result) { return result; } // // TODO: Implement this ... // result = HasChild(guards); // // Cleanup Resources ... // if (!result) { Clean(guards); } // return result; } // // Protected ... protected: // /** * Initialize ... */ void Init(XCATBEASignallerInputs &inputs) { // bool has = inputs.IsValid(); if (!has) { return; } // symbol = inputs.symbol; period = inputs.period; filters = inputs.filters; provider = inputs.provider; allowDraws = inputs.allowDraws; allowGuards = inputs.allowGuards; validations = inputs.validations; slATRMultiplier = inputs.slATRMultiplier; riskToRewardRatio = inputs.riskToRewardRatio; // mObjects = new CArrayObj(); // // Initialize Bar Tracker ... has = barTraker.Init( symbol, period // ); if (!has) { return; } // // Initialize Bar Analyser ... barAnalyser = new XCBarAnalyser(); // // initialize Helper ... helper = new XCX121XCatbHelper(); has = helper.Init( symbol, period, inputs.catbInputs // ); if (!has) { return; } // mConditions.Clean(); Clean(mConditionsCollection); // InitPOI(); } /** * DeInitialize ... */ void DeInit() { // mObjects.Clear(); delete mObjects; ZeroMemory(mObjects); // drawer.Clear(); delete drawer; ZeroMemory(drawer); // detector.CleanPivots(); delete detector; ZeroMemory(detector); // delete helper; ZeroMemory(helper); // delete barAnalyser; ZeroMemory(barAnalyser); // barTraker.Clean(); } /** * Add Conditions to Conditions Collection if not Exists ... * * @param maxAllowed: int, Specified Max Allowed Holding Conditions ... * * @return ( int ) */ int AddConditionsIfNotExists( int maxAllowed = 10 // ) { // int result = 0; // bool isSetuped = IsValid(mConditions.setupTime) && HasDirection(mConditions.dir); if (!isSetuped) { return result; } // int count = ArraySize(mConditionsCollection); if (IsValidSize(count)) { // // Copy Original Items ... XCATBEAStrategyConditions tmpItems[]; Copy( mConditionsCollection, tmpItems // ); // // Prese Item Data ... bool isBullish = IsBullish(mConditions.dir); // for (int i = 0; i < count; i++) { // XCATBEAStrategyConditions iItem = tmpItems[i]; // bool canRemove = mConditions.dir == iItem.dir && mConditions.pivot == iItem.pivot; if (canRemove) { // ArrayRemove( mConditionsCollection, i, 1 // ); } } // Clean(tmpItems); } // AddRef( mConditions, mConditionsCollection // ); // // Remove Olds ... CleanupArray( mConditionsCollection, maxAllowed // ); // result = ArraySize(mConditionsCollection); // return result; } // // Private ... private: // // Props ... string symbol; string provider; CArrayObj *mObjects; ENUM_TIMEFRAMES period; // // Initialize and Configure POI Detector and Drawer ... void InitPOI() { // // Initialize POI Detector ... bool has = helper != NULL; if (has) { // detector = new XCXCATBEAPOIDetector(helper); // // Configure ... detector.detectPeakPivots = true; detector.detectValePivots = true; } // // Initialize POI Drawer ... has = detector != NULL; if (has) { // drawer = new XCXCATBEAPOIDrawer(detector); // // Configure ... drawer.drawPeakPivots = true; drawer.drawValePivots = true; // XCATBPivotStyle iStyle; // // Styling Peak Pivot ... iStyle.width = 1; iStyle.clr = clrMagenta; iStyle.style = STYLE_SOLID; // drawer.peakPivotStyle = iStyle; // // Styling Vale Pivot ... iStyle.width = 1; iStyle.clr = clrAqua; iStyle.style = STYLE_SOLID; // drawer.valePivotStyle = iStyle; // // Cleanup Resources ... // iStyle.Clean(); } } // };