/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: XCAEASignaller Lib // Description: Library for XCAEA Signaller ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm Library for XCAEA Signaller" #property strict // // Imports ... #include "../../Libraries/x-saherelm.common.lib.mq5" #include "../../Libraries/x-saherelm.x-poi.lib.mq5" #include "../../Libraries/x-saherelm.x-trade.lib.mq5" #include "../Classes/xcaea.x-poi.detector.class.mq5" #include "../Helpers/xcaea.helper.mq5" // // Enumeration ... // // Guard Actions ... enum ENUM_GUARD_ACTIONS { X_GUARD_ACTION_NONE, // Nothing to Do X_GUARD_ACTION_CLOSE, // Close Specified Position X_GUARD_ACTION_CLOSE_ALL, // Close All Positions X_GUARD_ACTION_CLOSE_LONGS, // Close All Long Positions X_GUARD_ACTION_CLOSE_SHORTS, // Close All Short Position X_GUARD_ACTION_PARTIAL_CLOSE, // Partial Close Specified Position X_GUARD_ACTION_TRAIL_STOP, // Trail Stop of Specified Position X_GUARD_ACTION_TRAIL_TARGET, // Trail Target of Specified Position X_GUARD_ACTION_HEDGE, // Hedge Specified Positions }; // // Definitions ... // // Conditions Struct ... struct XCAEAStrategyConditions { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // // Setup Props ... // double sl; double tp; double pivot; double point; string provider; double targets[]; // datetime time; datetime setupTime; datetime triggerTime; // XBoxZone signalBox; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; XCAEAConditions conditions; // // Constructor ... XCAEAStrategyConditions() { Clean(); } // // Tools ... /** * Cleaning Up ... */ void Clean() { // sl = 0; tp = 0; pivot = 0; point = 0; // symbol = NULL; period = NULL; provider = NULL; // time = NULL; setupTime = NULL; triggerTime = NULL; // Clean(targets); // signalBox.Clean(); conditions.Clean(); // dir = X_DIRECTION_NONE; type = X_POSITION_TYPE_NONE; // } // // Signalling ... /** * Validate ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = IsSpecifiedValid(symbol) && IsSpecifiedValid(period) && IsSpecifiedValid(time); // return result; } /** * Check Conditions Has Valid Bullish Signal ... * * @return ( bool ) */ bool HasBullishSignal() { // bool result = false; // result = (sl > 0 || tp > 0) && IsValid() && HasDirection(dir); if (!result) { return result; } // result = IsBullish(dir); // return result; } /** * Check Conditions Has Valid Bearish Signal ... * * @return ( bool ) */ bool HasBearishSignal() { // bool result = false; // result = (sl > 0 || tp > 0) && IsValid() && HasDirection(dir); if (!result) { return result; } // result = IsBearish(dir); // return result; } // // Setting Up and Triggering Up ... /** * Check Condition is Setting Up ... * * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... * * @return ( bool ) */ bool IsSetuped() { // bool result = false; // result = IsValid(setupTime) && HasDirection(dir); if (!result) { return result; } // return result; } /** * Calculate Setup Age ... * * @return ( int ) */ int GetSetupAge() { // int result = 0; // if (!IsSetuped()) { return result; } // result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); // return result; } /** * Detect How we Can Trigger Signal ... * * @return ( bool ) */ bool CanTrigger() { // bool result = false; // result = // sl > 0 && IsValid(symbol) && IsValid(period) && IsValid(triggerTime) && type != X_POSITION_TYPE_ALL && type != X_POSITION_TYPE_NONE // ; // return result; } // }; // // Model a Guard Action ... struct XCAEAGuard { // // Props ... ENUM_GUARD_ACTIONS action; datetime time; // string symbol; string provider; // // Specified Position ... ulong ticket; // // Partial Close ... double volumeMultiplier; // // SL Trial ... double sl; // // TP Trial ... double tp; // // Constructor ... XCAEAGuard() { Clean(); } // // Tools ... /** * Cleanup ... */ void Clean() { // time = NULL; action = X_GUARD_ACTION_NONE; // symbol = NULL; provider = NULL; // ticket = 0; // volumeMultiplier = 0; // sl = 0; tp = 0; // ZeroMemory(this); } /** * Validate ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // IsValid(time) && IsValid(symbol) && IsValid(provider) && action != X_GUARD_ACTION_NONE // ; if (!result) { return result; } // // Validate Model Based On Specified Guard Actions ... // return result; } }; /** * Add Guard to Collection ... * * @param guard: XCAEAGuard instance ... * @param guards: XCAEAGuard instance Collection ... * * @return ( int ) */ int AddGuard( XCAEAGuard &guard, XCAEAGuard &guards[] // ) { // int result = 0; // if (!guard.IsValid()) { return result; } // AddRef( guard, guards // ); // result = ArraySize(guards); // return result; } // bool DetectXCAEAConditions( XBoxZone &boxes[], XCAEAConditions &conditions, XBoxZone &box, ENUM_X_DIRECTION &dir, XCXCAEAHelper *helper, int barIndex = 0, int loopback = 10 // ) { // bool result = false; // int idx = -1; int count = 0; bool has = false; // box.Clean(); conditions.Clean(); dir = X_DIRECTION_NONE; // if (barIndex < 0) { barIndex = 0; } loopback = NormalizeInt(loopback, 5); // string symbol = helper.GetSymbol(); ENUM_TIMEFRAMES period = helper.GetPeriod(); // result = helper.GetConditions( conditions, barIndex, loopback // ); if (!result) { // conditions.Clean(); return result; } // int zIDX = barIndex; int cIDX = zIDX + 1; int pIDX = cIDX + 1; int p2IDX = pIDX + 1; int p3IDX = p2IDX + 1; int p4IDX = p3IDX + 1; // XOHCL zBar; XOHCL cBar; XOHCL pBar; XOHCL p2Bar; XOHCL p3Bar; XOHCL p4Bar; result = zBar.Init( symbol, period, zIDX // ); result = result && zBar.GetPreviousBar(cBar); result = result && cBar.GetPreviousBar(pBar); result = result && pBar.GetPreviousBar(p2Bar); result = result && p2Bar.GetPreviousBar(p3Bar); result = result && p3Bar.GetPreviousBar(p4Bar); if (!result) { // zBar.Clean(); cBar.Clean(); pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); p4Bar.Clean(); // box.Clean(); conditions.Clean(); // return result; } // bool isBarBullishVPattern = pBar.IsBullish() && cBar.low > pBar.low && p2Bar.low > pBar.low; // bool isBarBearishVPattern = pBar.IsBearish() && cBar.high < pBar.high && p2Bar.high < pBar.high; // // Detect Selected Box ... XBoxZone selectedBox; bool hasBoxes = HasChild(boxes); if (hasBoxes) { // // Detect Selected Boxes ... XBoxZone tmp[]; Copy( boxes, tmp // ); while (HasChild(tmp)) { // idx = GetYoungest(tmp); has = IsValidIndex(idx); if (!has) { break; } // XBoxZone iBox; iBox = tmp[idx]; ArrayRemove( tmp, idx, 1 // ); // // Check Selected Box not RSI or CCI ... has = iBox.type == ToString(XCA_PEAKSWHRES) || iBox.type == ToString(XCA_VALESWLSUP); if (!has) { continue; } // bool isBullish = iBox.IsBullish(); bool isBearish = iBox.IsBearish(); // double rejectedCheckPrice = isBullish ? iBox.upper : iBox.lower; // // Check Box Selecting Senarios ... // // Selecting Rejected Boxes ... bool isRejected = cBar.IsRejected( rejectedCheckPrice, iBox.dir, false, false // ); // // Selecting Activation Boxes ... // bool isBullishActivated = isBullish && isBarBullishVPattern && cBar.GetUp() > rejectedCheckPrice && cBar.GetDown() < rejectedCheckPrice; // bool isBearishActivated = isBearish && isBarBearishVPattern && cBar.GetUp() > rejectedCheckPrice && cBar.GetDown() < rejectedCheckPrice; // bool isActivated = isBullishActivated || isBearishActivated; // has = // isRejected || isActivated; if (has) { // selectedBox = iBox; // iBox.Clean(); break; } // iBox.Clean(); } // Clean(tmp); } // // Force Conditions to Have Selected Box ... result = hasBoxes && selectedBox.IsValid(); if (!result) { // zBar.Clean(); cBar.Clean(); pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); p4Bar.Clean(); // box.Clean(); conditions.Clean(); selectedBox.Clean(); // return result; } // // Bars Conditions ... // ENUM_X_DIRECTION cBarDir; // // Hammer ... bool isCBarHammer = helper .barAnalyser .IsHammer( cBar, cBarDir // ); bool isCBarBullishHammer = isCBarHammer && IsBullish(cBarDir); bool isCBarBearishHammer = isCBarHammer && IsBearish(cBarDir); // // Rejected ... bool isCBarRejected = helper .barAnalyser .IsRejected( cBar, cBarDir, false, // Force Type ... true // Force Fibo Pressure ... ); bool isCBarBullishRejected = isCBarRejected && IsBullish(cBarDir); bool isCBarBearishRejected = isCBarRejected && IsBearish(cBarDir); // // Engulfed ... bool isCBarEngulfed = helper .barAnalyser .IsEngulfed( cBar, cBarDir // ); bool isCBarBullishEngulfed = isCBarEngulfed && IsBullish(cBarDir); bool isCBarBearishEngulfed = isCBarEngulfed && IsBearish(cBarDir); // // Momentum ... bool isCBarMomentum = helper .barAnalyser .IsMomentum( cBar, cBarDir, 1 // ); bool isCBarBullishMomentum = isCBarMomentum && IsBullish(cBarDir); bool isCBarBearishMomentum = isCBarMomentum && IsBearish(cBarDir); // // Bar Sumarise ... // bool isCBarValidForBullish = (isCBarBullishHammer || isCBarBullishRejected || isCBarBullishMomentum || isCBarBullishEngulfed); // bool isCBarValidForBearish = (isCBarBearishHammer || isCBarBearishRejected || isCBarBearishMomentum || isCBarBearishEngulfed); // // Score ... // double bullishScore = 0; double bearishScore = 0; conditions.GenerateScore( bullishScore, bearishScore // ); // bool isScoreBullish = bullishScore > bearishScore; // bool isScoreBearish = bearishScore > bullishScore; // string summary = conditions .GenerateSummary(); // // Conditions ... // // Reading Values ... // // KI ... // double cKI = conditions.kiBuffer[cIDX]; double pKI = conditions.kiBuffer[pIDX]; double p2KI = conditions.kiBuffer[p2IDX]; // double cKIState = conditions.kiStateBuffer[cIDX]; double pKIState = conditions.kiStateBuffer[pIDX]; double p2KIState = conditions.kiStateBuffer[p2IDX]; // // TKI ... // double cTKI = conditions.tkiBuffer[cIDX]; double pTKI = conditions.tkiBuffer[pIDX]; double p2TKI = conditions.tkiBuffer[p2IDX]; // double cTKIState = conditions.tkiStateBuffer[cIDX]; double pTKIState = conditions.tkiStateBuffer[pIDX]; double p2TKIState = conditions.tkiStateBuffer[p2IDX]; // // TREND ... // double cTrend = conditions.trendBuffer[cIDX]; double pTrend = conditions.trendBuffer[pIDX]; double p2Trend = conditions.trendBuffer[p2IDX]; // double ctrendState = conditions.trendStateBuffer[cIDX]; double ptrendState = conditions.trendStateBuffer[pIDX]; double p2trendState = conditions.trendStateBuffer[p2IDX]; // // SWING Low ... // double cSWL = conditions.swingLowBuffer[cIDX]; double pSWL = conditions.swingLowBuffer[pIDX]; double p2SWL = conditions.swingLowBuffer[p2IDX]; // // SWING High ... // double cSWH = conditions.swingHighBuffer[cIDX]; double pSWH = conditions.swingHighBuffer[pIDX]; double p2SWH = conditions.swingHighBuffer[p2IDX]; // // PEAK ... // double cPeak = conditions.peakBuffer[cIDX]; double pPeak = conditions.peakBuffer[pIDX]; double p2Peak = conditions.peakBuffer[p2IDX]; // // VALE ... // double cVale = conditions.valeBuffer[cIDX]; double pVale = conditions.valeBuffer[pIDX]; double p2Vale = conditions.valeBuffer[p2IDX]; // // COMPLEX ... // double iKTIRNDs[] = { cKI, cTKI, cTrend // }; // double iKTIRNDMax = GetMax(iKTIRNDs); double iKTIRNDMin = GetMin(iKTIRNDs); // // Conditions Preparing ... // bool isTKITRNDBullish = cKIState > 0 && cTKIState > 0 && ctrendState > 0; // bool isTKITRNDBullishPrev = pKIState > 0 && pTKIState > 0 && ptrendState > 0; // bool isTKITRNDBearish = cKIState < 0 && cTKIState < 0 && ctrendState < 0; // bool isTKITRNDBearishPrev = pKIState < 0 && pTKIState < 0 && ptrendState < 0; // bool isTKITRNDSwitchedToBullish = isTKITRNDBullish && !isTKITRNDBullishPrev; // bool isTKITRNDSwitchedToBearish = isTKITRNDBearish && !isTKITRNDBearishPrev; // bool isCond1Bullish = // conditions.isRSIOS && // conditions.isValeIsPivot && // isTKITRNDSwitchedToBullish conditions.isKISwitchedToBullish // ; // bool isCond1Bearish = // conditions.isRSIOB && // conditions.isPeakIsPivot && // isTKITRNDSwitchedToBearish conditions.isKISwitchedToBearish // ; // if (isCond1Bullish || isCond1Bearish) { // Print("Cond1"); } // // Summarise Conditions ... // bool isBullish = // false // ; // bool isBearish = // false // ; // result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // double entry = GetEntry( conditions.symbol, dir // ); double sl = 0; // conditions.kijunSenBuffer[cIDX]; // box.dir = dir; box.symbol = conditions.symbol; box.period = conditions.period; // box.upper = isBullish ? entry : sl; // box.lower = isBullish ? sl : entry; // box.to = zBar.time; box.from = p4Bar.time; // box.type = ToString(dir) + "_Signal_" + conditions.symbol + "_" + ToString(conditions.period); } // result = box.IsValid() && HasDirection(dir); // // Cleanup Resources ... // if (!result) { // box.Clean(); conditions.Clean(); } // zBar.Clean(); cBar.Clean(); pBar.Clean(); p2Bar.Clean(); p3Bar.Clean(); p4Bar.Clean(); // return result; } //