diff --git a/Documents/BKP/1/signallers.tmp.mq5 b/Documents/BKP/1/signallers.tmp.mq5 new file mode 100644 index 00000000..f0300681 --- /dev/null +++ b/Documents/BKP/1/signallers.tmp.mq5 @@ -0,0 +1,124 @@ + // + // Parsing Pivots ... + + // + // Detect Selected Pivot ... + XBoxZone lastOSCPivot; + double providedSL = 0; + bool hasNewOSC = false; + bool hasPivots = HasChild(pivots); + if (hasPivots) + { + // + // Detect Selected Pivots ... + count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = pivots[i]; + + // + // Detect Selected Last OSC Pivots ... + bool isOSC = + Contains( + "XCA_RSI", + iPivot.type // + ) || + Contains( + "XCA_CCI", + iPivot.type // + ); + bool canSetOSC = + !isOSC + ? false + : !lastOSCPivot.IsValid() + ? true + : lastOSCPivot.from < iPivot.from; + if (canSetOSC) + { + // + lastOSCPivot = iPivot; + + // + // Detect New OSC Pivot Happens ... + hasNewOSC = lastOSCPivot.IsValid() && + cBar.time == lastOSCPivot.to; + } + + // + // Check Pivot Box Type ... + bool isPVPivot = + Contains( + "XCA_PEAKSWHRES", + iPivot.type // + ) || + Contains( + "XCA_VALESWLSUP", + iPivot.type // + ); + if (isPVPivot) + { + // + // Select Box for OSC ... + if (hasNewOSC) + { + // + bool canSelectBox = + pivotBox.IsValid() + ? false + : lastOSCPivot.dir == iPivot.dir && + (IsBullish(iPivot.dir) + ? lastOSCPivot.upper > iPivot.upper && + lastOSCPivot.lower < iPivot.upper && + lastOSCPivot.lower <= iPivot.lower + : lastOSCPivot.lower < iPivot.lower && + lastOSCPivot.upper > iPivot.lower && + lastOSCPivot.upper >= iPivot.upper); + if (canSelectBox) + { + pivotBox = iPivot; + } + } + } + + // + iPivot.Clean(); + + // + } + } + + // + // Signaller Summarization ... + + // + // Cond1 Act Using PEAK VALE Box Activation or Rejection ... + + // + bool isCond1Bullish = + // + hasNewOSC && + (cVale < pVale || + pVale < p2Vale) && + pivotBox.IsValid() && + pivotBox.IsBullish() && + lastOSCPivot.IsBullish() && + conditions.isValeIsPivot + // + ; + + // + bool isCond1Bearish = + // + hasNewOSC && + (cPeak > pPeak || + pPeak > p2Peak) && + pivotBox.IsValid() && + pivotBox.IsBearish() && + lastOSCPivot.IsBearish() && + conditions.isPeakIsPivot + // + ; + +//////////////////////////////////////////////////////////////////// + diff --git a/Helpers/x-saherelm.x121.x3ma.helper.mq5 b/Helpers/x-saherelm.x121.x3ma.helper.mq5 new file mode 100644 index 00000000..b03a004f --- /dev/null +++ b/Helpers/x-saherelm.x121.x3ma.helper.mq5 @@ -0,0 +1,1320 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCX121X3MAHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.x-helper.class.mq5" + +// +// Definitions ... + +// +// Buffers ... +enum ENUM_X121_X3MA_BUFFERS +{ + // + X121_X3MA_FAST = 0, + X121_X3MA_FAST_COLOR = 1, + X121_X3MA_FAST_STATE = 6, + X121_X3MA_MEDIUM = 2, + X121_X3MA_MEDIUM_COLOR = 3, + X121_X3MA_MEDIUM_STATE = 7, + X121_X3MA_SLOW = 4, + X121_X3MA_SLOW_COLOR = 5, + X121_X3MA_SLOW_STATE = 8, +}; + +// +// Input Models ... +struct X121X3MAInputs +{ + // + // Props ... + + // + // FAST ... + int fastLength; + ENUM_MA_METHOD fastMethod; + ENUM_APPLIED_PRICE fastAppliedTo; + + // + // MEDIUM ... + int mediumLength; + ENUM_MA_METHOD mediumMethod; + ENUM_APPLIED_PRICE mediumAppliedTo; + + // + // SLOW ... + int slowLength; + ENUM_MA_METHOD slowMethod; + ENUM_APPLIED_PRICE slowAppliedTo; + + // + // Presentation ... + + // + int startCalculationForLastBars; + + // + bool applyColor; + + // + bool showFast; + bool showSlow; + bool showMedium; + + // + // Constructor ... + X121X3MAInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + // FAST ... + fastLength = 0; + fastMethod = MODE_SMA; + fastAppliedTo = PRICE_CLOSE; + + // + // MEDIUM ... + mediumLength = 0; + mediumMethod = MODE_SMA; + mediumAppliedTo = PRICE_CLOSE; + + // + // SLOW ... + slowLength = 0; + slowMethod = MODE_SMA; + slowAppliedTo = PRICE_CLOSE; + + // + startCalculationForLastBars = 0; + + // + applyColor = false; + + // + showFast = false; + showSlow = false; + showMedium = false; + } + + // + // Default ... + void Default() + { + // + // FAST ... + fastLength = 6; + fastMethod = MODE_SMA; + fastAppliedTo = PRICE_CLOSE; + + // + // MEDIUM ... + mediumLength = 21; + mediumMethod = MODE_SMA; + mediumAppliedTo = PRICE_CLOSE; + + // + // SLOW ... + slowLength = 34; + slowMethod = MODE_SMA; + slowAppliedTo = PRICE_CLOSE; + + // + startCalculationForLastBars = 1000; + + // + applyColor = true; + + // + showFast = true; + showSlow = true; + showMedium = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + fastLength > 2 && + mediumLength > 2 && + slowLength > 2 && + mediumLength > fastLength && + mediumLength < slowLength + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(fastLength, mediumLength); + result = MathMax(result, slowLength); + + // + return result; + } +}; + +// +// Conditions ... +struct X121X3MAConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + + // + double fastBuffer[]; + double mediumBuffer[]; + double slowBuffer[]; + double fastStateBuffer[]; + double mediumStateBuffer[]; + double slowStateBuffer[]; + + // + // Conditions ... + + // + bool isFastOverMedium; + bool isFastUnderMedium; + + // + bool isFastCrossedOverMedium; + bool isFastCrossedUnderMedium; + + // + bool isFastOverSlow; + bool isFastUnderSlow; + + // + bool isFastCrossedOverSlow; + bool isFastCrossedUnderSlow; + + // + bool isMediumOverSlow; + bool isMediumUnderSlow; + + // + bool isMediumCrossedOverSlow; + bool isMediumCrossedUnderSlow; + + // + // Constructor ... + X121X3MAConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + symbol = NULL; + period = NULL; + time = NULL; + + // + // Buffers ... + + // + Clean(fastBuffer); + Clean(mediumBuffer); + Clean(slowBuffer); + Clean(fastStateBuffer); + Clean(mediumStateBuffer); + Clean(slowStateBuffer); + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(mediumBuffer, true); + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(fastStateBuffer, true); + ArraySetAsSeries(mediumStateBuffer, true); + ArraySetAsSeries(slowStateBuffer, true); + + // + // Conditions ... + + // + isFastOverMedium = false; + isFastUnderMedium = false; + + // + isFastCrossedOverMedium = false; + isFastCrossedUnderMedium = false; + + // + isFastOverSlow = false; + isFastUnderSlow = false; + + // + isFastCrossedOverSlow = false; + isFastCrossedUnderSlow = false; + + // + isMediumOverSlow = false; + isMediumUnderSlow = false; + + // + isMediumCrossedOverSlow = false; + isMediumCrossedUnderSlow = false; + } + + /** + * Generate Conditions Scores ... + * + * @param bullishScore: Double, Directional Scores Reference ... + * @param bearishScore: Double, Directional Scores Reference ... + */ + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + double score = 1; + double minScore = 0.5; + double highScore = 1.5; + + // + if (isFastOverSlow) + { + bullishScore += minScore; + } + if (isFastOverMedium) + { + bullishScore += minScore; + } + if (isMediumOverSlow) + { + bullishScore += minScore; + } + if (isFastCrossedOverSlow) + { + bullishScore += score; + } + if (isFastCrossedOverMedium) + { + bullishScore += score; + } + if (isMediumCrossedOverSlow) + { + bullishScore += score; + } + + // + if (isFastUnderSlow) + { + bearishScore += minScore; + } + if (isMediumUnderSlow) + { + bearishScore += minScore; + } + if (isFastUnderMedium) + { + bearishScore += minScore; + } + if (isFastCrossedUnderSlow) + { + bearishScore += score; + } + if (isFastCrossedUnderMedium) + { + bearishScore += score; + } + if (isMediumCrossedUnderSlow) + { + bearishScore += score; + } + } + + /** + * Generate Summary String for Represent Conditions State ... + * + * @param onlyCommons: Boolean, Just Generate Only Commons Conditions ... + * @param onlyConditions: Boolean, Just Generate Only Conditions ... + * @param includeScores: Boolean, Attach Scores Representations on Result ... + * @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ... + * @param separator: String, Separate Lines ... + * + * @return ( string ) + */ + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + "-----------------------" + separator + + "X3MA: " + separator + + "-----------------------" + separator + + ToString("isFastOverMedium", isFastOverMedium, ignoreFalseConditions, separator) + + ToString("isFastUnderMedium", isFastUnderMedium, ignoreFalseConditions, separator) + + ToString("isFastCrossedOverMedium", isFastCrossedOverMedium, ignoreFalseConditions, separator) + + ToString("isFastCrossedUnderMedium", isFastCrossedUnderMedium, ignoreFalseConditions, separator) + + ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions, separator) + + ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions, separator) + + ToString("isFastCrossedOverSlow", isFastCrossedOverSlow, ignoreFalseConditions, separator) + + ToString("isFastCrossedUnderSlow", isFastCrossedUnderSlow, ignoreFalseConditions, separator) + + ToString("isMediumOverSlow", isMediumOverSlow, ignoreFalseConditions, separator) + + ToString("isMediumUnderSlow", isMediumUnderSlow, ignoreFalseConditions, separator) + + ToString("isMediumCrossedOverSlow", isMediumCrossedOverSlow, ignoreFalseConditions, separator) + + ToString("isMediumCrossedUnderSlow", isMediumCrossedUnderSlow, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + /** + * Retrieve nique Tag Identifier ... + * + * @return ( string ) + */ + string GetTag() + { + return GetTypeName(this); + } + + // +}; + +// +// Class ... +class XCX121X3MAHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCX121X3MAHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121X3MAHelper() + { + // + mInputs.Clean(); + + // + Clean(fastBuffer); + Clean(mediumBuffer); + Clean(slowBuffer); + Clean(fastStateBuffer); + Clean(mediumStateBuffer); + Clean(slowStateBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121X3MAInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(mediumBuffer, true); + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(fastStateBuffer, true); + ArraySetAsSeries(mediumStateBuffer, true); + ArraySetAsSeries(slowStateBuffer, true); + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.x3ma", + "", // FAST ... + mInputs.fastLength, + mInputs.fastMethod, + mInputs.fastAppliedTo, + "", // MEDIUM ... + mInputs.mediumLength, + mInputs.mediumMethod, + mInputs.mediumAppliedTo, + "", // SLOW ... + mInputs.slowLength, + mInputs.slowMethod, + mInputs.slowAppliedTo, + "", // Presentation ... + mInputs.startCalculationForLastBars, + mInputs.applyColor, + mInputs.showFast, + mInputs.showSlow, + mInputs.showMedium + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X121X3MAInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121X3MAInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Readers ... + + // + // FAST ... + + // + double GetFast( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(fastBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastBuffer[barIndex]; + } + + // + int CopyFast( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + fastBuffer, + buffer, + forceClean + // + ); + } + + // + // FAST STATE ... + + // + double GetFastState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(fastStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return fastStateBuffer[barIndex]; + } + + // + int CopyFastState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + fastStateBuffer, + buffer, + forceClean + // + ); + } + + // + // MEDIUM ... + + // + double GetMedium( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mediumBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mediumBuffer[barIndex]; + } + + // + int CopyMedium( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + mediumBuffer, + buffer, + forceClean + // + ); + } + + // + // MEDIUM STATE ... + + // + double GetMediumState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mediumStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mediumStateBuffer[barIndex]; + } + + // + int CopyMediumState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + mediumStateBuffer, + buffer, + forceClean + // + ); + } + + // + // SLOW ... + + // + double GetSlow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(slowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowBuffer[barIndex]; + } + + // + int CopySlow( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + slowBuffer, + buffer, + forceClean + // + ); + } + + // + // SLOW STATE ... + + // + double GetSlowState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(slowStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return slowStateBuffer[barIndex]; + } + + // + int CopySlowState( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(start); + + // + // Copy Items ... + return Copy( + 0, + count, + slowStateBuffer, + buffer, + forceClean + // + ); + } + + // + void Free() override + { + Cleanup(10); + } + + // + bool GetConditions( + X121X3MAConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + 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 ... + + // + // FAST ... + + // + CopyFast( + zIndex, + loopback, + conditions.fastBuffer // + ); + + // + CopyFastState( + zIndex, + loopback, + conditions.fastStateBuffer // + ); + + // + // MEDIUM ... + + // + CopyMedium( + zIndex, + loopback, + conditions.mediumBuffer // + ); + + // + CopyMediumState( + zIndex, + loopback, + conditions.mediumStateBuffer // + ); + + // + // SLOW ... + + // + CopySlow( + zIndex, + loopback, + conditions.slowBuffer // + ); + + // + CopySlowState( + zIndex, + loopback, + conditions.slowStateBuffer // + ); + + // + // Conditions ... + + // + int zIDX = 0; + int cIDX = 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + // Calculate ... + + // + // FAST ... + + // + double cFast = conditions.fastBuffer[cIDX]; + double pFast = conditions.fastBuffer[pIDX]; + double p2Fast = conditions.fastBuffer[p2IDX]; + + // + double cFastState = conditions.fastStateBuffer[cIDX]; + double pFastState = conditions.fastStateBuffer[pIDX]; + double p2FastState = conditions.fastStateBuffer[p2IDX]; + + // + // MEDIUM ... + + // + double cMedium = conditions.mediumBuffer[cIDX]; + double pMedium = conditions.mediumBuffer[pIDX]; + double p2Medium = conditions.mediumBuffer[p2IDX]; + + // + double cMediumState = conditions.mediumStateBuffer[cIDX]; + double pMediumState = conditions.mediumStateBuffer[pIDX]; + double p2MediumState = conditions.mediumStateBuffer[p2IDX]; + + // + // FAST ... + + // + double cSlow = conditions.slowBuffer[cIDX]; + double pSlow = conditions.slowBuffer[pIDX]; + double p2Slow = conditions.slowBuffer[p2IDX]; + + // + double cSlowState = conditions.slowStateBuffer[cIDX]; + double pSlowState = conditions.slowStateBuffer[pIDX]; + double p2SlowState = conditions.slowStateBuffer[p2IDX]; + + // + // Conditions ... + + // + bool isFastOverMedium = cFast > cMedium; + bool isFastOverMediumPrev = pFast > pMedium; + bool isFastCrossedOverMedium = isFastOverMedium && + !isFastOverMediumPrev; + + // + bool isFastUnderMedium = cFast < cMedium; + bool isFastUnderMediumPrev = pFast < pMedium; + bool isFastCrossedUnderMedium = isFastUnderMedium && + !isFastUnderMediumPrev; + + // + bool isFastOverSlow = cFast > cSlow; + bool isFastOverSlowPrev = pFast > pSlow; + bool isFastCrossedOverSlow = isFastOverSlow && + !isFastOverSlowPrev; + + // + bool isFastUnderSlow = cFast < cSlow; + bool isFastUnderSlowPrev = pFast < pSlow; + bool isFastCrossedUnderSlow = isFastUnderSlow && + !isFastUnderSlowPrev; + + // + bool isMediumOverSlow = cMedium > cSlow; + bool isMediumOverSlowPrev = pMedium > pSlow; + bool isMediumCrossedOverSlow = isMediumOverSlow && + !isMediumOverSlowPrev; + + // + bool isMediumUnderSlow = cMedium < cSlow; + bool isMediumUnderSlowPrev = pMedium < pSlow; + bool isMediumCrossedUnderSlow = isMediumUnderSlow && + !isMediumUnderSlowPrev; + + // + conditions.isFastOverSlow = isFastOverSlow; + conditions.isFastUnderSlow = isFastUnderSlow; + conditions.isFastOverMedium = isFastOverMedium; + conditions.isMediumOverSlow = isMediumOverSlow; + conditions.isFastUnderMedium = isFastUnderMedium; + conditions.isMediumUnderSlow = isMediumUnderSlow; + conditions.isFastCrossedOverSlow = isFastCrossedOverSlow; + conditions.isFastCrossedUnderSlow = isFastCrossedUnderSlow; + conditions.isFastCrossedOverMedium = isFastCrossedOverMedium; + conditions.isMediumCrossedOverSlow = isMediumCrossedOverSlow; + conditions.isFastCrossedUnderMedium = isFastCrossedUnderMedium; + conditions.isMediumCrossedUnderSlow = isMediumCrossedUnderSlow; + + // + Cleanup(); + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121X3MAInputs mInputs; // Inputs ... + + // + // Buffers ... + double fastBuffer[]; + double mediumBuffer[]; + double slowBuffer[]; + double fastStateBuffer[]; + double mediumStateBuffer[]; + double slowStateBuffer[]; + + // + void Calculate( + int barIndex = 0, + int maxRequiredBars = 100 // + ) + { + // + // Buffers ... + if (barIndex < 0) + { + barIndex = 0; + } + + // + // FAST ... + + // + CopyBuffer( + mHandler, + X121_X3MA_FAST, + barIndex, + maxRequiredBars, + fastBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_X3MA_FAST_STATE, + barIndex, + maxRequiredBars, + mediumBuffer // + ); + + // + // MEDIUM ... + + // + CopyBuffer( + mHandler, + X121_X3MA_MEDIUM, + barIndex, + maxRequiredBars, + mediumStateBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_X3MA_MEDIUM_STATE, + barIndex, + maxRequiredBars, + slowStateBuffer // + ); + + // + // SLOW ... + + // + CopyBuffer( + mHandler, + X121_X3MA_SLOW, + barIndex, + maxRequiredBars, + slowBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_X3MA_SLOW_STATE, + barIndex, + maxRequiredBars, + fastStateBuffer // + ); + } + + // + void Cleanup( + int maxAllowed = 100 // + ) + { + // + CleanupArray( + fastBuffer, + maxAllowed // + ); + + // + CleanupArray( + mediumBuffer, + maxAllowed // + ); + + // + CleanupArray( + slowBuffer, + maxAllowed // + ); + + // + CleanupArray( + fastStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + mediumStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + slowStateBuffer, + maxAllowed // + ); + } + + // +}; + +// \ No newline at end of file diff --git a/Helpers/x-saherelm.x121.xca.helper.mq5 b/Helpers/x-saherelm.x121.xca.helper.mq5 index d70cb78c..eb796b78 100644 --- a/Helpers/x-saherelm.x121.xca.helper.mq5 +++ b/Helpers/x-saherelm.x121.xca.helper.mq5 @@ -28,7 +28,7 @@ // Definitions ... // -// Definitions ... +// Buffers ... enum ENUM_X121_XCA_BUFFERS { // diff --git a/Indicators/x-saherelm.x121.x3ma.mq5 b/Indicators/x-saherelm.x121.x3ma.mq5 new file mode 100644 index 00000000..249c4f6e --- /dev/null +++ b/Indicators/x-saherelm.x121.x3ma.mq5 @@ -0,0 +1,788 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 X3MA +// Description: X3MA ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm X121 X3MA Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 X3MA" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Fast ... +input group "Fast"; +input int fastLength = 6; // Length +input ENUM_MA_METHOD fastMethod = MODE_SMA; // Mwethod +input ENUM_APPLIED_PRICE fastAppliedTo = PRICE_CLOSE; // Applied To + +// +// Medium ... +input group "Medium"; +input int mediumLength = 21; // Length +input ENUM_MA_METHOD mediumMethod = MODE_SMA; // Mwethod +input ENUM_APPLIED_PRICE mediumAppliedTo = PRICE_CLOSE; // Applied To + +// +// Slow ... +input group "Slow"; +input int slowLength = 34; // Length +input ENUM_MA_METHOD slowMethod = MODE_SMA; // Mwethod +input ENUM_APPLIED_PRICE slowAppliedTo = PRICE_CLOSE; // Applied To + +// +// Presentation ... +input group "Presentation"; + +// +input int startCalculationForLastBars = 1000; // Calculate Last n Bars + +// +input bool applyColor = false; + +// +input bool showFast = true; // Show Fast +input bool showSlow = true; // Show Medium +input bool showMedium = true; // Show Slow + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +#define bullishState 1 +#define neuturalState 0 +#define bearishState -1 + +// +#define emptyValue 0.0 + +// +#property indicator_chart_window + +// +#property indicator_buffers 9 +#property indicator_plots 3 + +// +// Plot Buffers ... + +// +// FAST ... + +// +#define fastBufferIndex 0 +double fastBuffer[]; + +// +#define fastColorBufferIndex 1 +double fastColorBuffer[]; + +// +#property indicator_label1 "X121 X3MA Fast" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrYellow, clrChocolate, clrGray +#property indicator_style1 STYLE_SOLID +#property indicator_width1 2 + +// +// MEDIUM ... + +// +#define mediumBufferIndex 2 +double mediumBuffer[]; + +// +#define mediumColorBufferIndex 3 +double mediumColorBuffer[]; + +// +#property indicator_label2 "X121 X3MA Medium" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrAqua, clrMagenta, clrGray +#property indicator_style2 STYLE_DASHDOTDOT +#property indicator_width2 2 + +// +// SLOW ... + +// +#define slowBufferIndex 4 +double slowBuffer[]; + +// +#define slowColorBufferIndex 5 +double slowColorBuffer[]; + +// +#property indicator_label3 "X121 X3MA Slow" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_style3 STYLE_DASH +#property indicator_width3 2 + +// +// Data Buffers ... + +#define mLastBufferIndex 5 + +// +#define fastStateBufferIndex mLastBufferIndex + 1 +double fastStateBuffer[]; + +// +#define mediumStateBufferIndex mLastBufferIndex + 2 +double mediumStateBuffer[]; + +// +#define slowStateBufferIndex mLastBufferIndex + 3 +double slowStateBuffer[]; + +// +// Variables, Properties and etc ... + +// +// this counts Available Bars ... +int limit; + +// +int maxLength; + +// +int fastHandler = INVALID_HANDLE; +int mediumHandler = INVALID_HANDLE; +int slowHandler = INVALID_HANDLE; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize Indicator Handlers ... + + // + // FAST ... + fastHandler = iMA( + _Symbol, + _Period, + fastLength, + 0, + fastMethod, + fastAppliedTo // + ); + bool isInited = fastHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // MEDIUM ... + mediumHandler = iMA( + _Symbol, + _Period, + mediumLength, + 0, + mediumMethod, + mediumAppliedTo // + ); + isInited = mediumHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // SLOW ... + slowHandler = iMA( + _Symbol, + _Period, + slowLength, + 0, + slowMethod, + slowAppliedTo // + ); + isInited = slowHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +/** + * De Initialize Indicator ... + * + * @param reason: Integer, De Initialization Reason ... + */ +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + IndicatorRelease(fastHandler); + IndicatorRelease(mediumHandler); + IndicatorRelease(slowHandler); +} + +/** + * Calculate Bars ... + * + * @param rates_total: Integer, Total Bars on Chart ... + * @param prev_calculated: Integer, Total Calculated Bars on Charts ... + * @param time: DateTime Array, History of Open Time ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param low: Double Array, History of Low Prices ... + * @param close: Double Array, History of Close Prices ... + * @param tick_volume: Long, History of Tick Volumes on Bar ... + * @param volume: Long, History of Trade Volumes ... + * @param spread: Double, History of Spread Price ... + * + * @return ( int ) + */ +int OnCalculate( + const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[] // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // Validate Calculated Bars ... + + // + // FAST ... + int fastCalculatedBars = BarsCalculated(fastHandler); + + // + // MEDIUM ... + int mediumCalculatedBars = BarsCalculated(mediumHandler); + + // + // SLOW ... + int slowCalculatedBars = BarsCalculated(slowHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // FAST ... + fastCalculatedBars >= maxLength && + // + // MEDIUM ... + mediumCalculatedBars >= maxLength && + // + // SLOW ... + slowCalculatedBars >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // FAST ... + int copiedFasts = CopyBuffer(fastHandler, 0, 0, limit, fastBuffer); + + // + // MEDIUM ... + int copiedMediumss = CopyBuffer(mediumHandler, 0, 0, limit, mediumBuffer); + + // + // SLOW ... + int copiedSlows = CopyBuffer(slowHandler, 0, 0, limit, slowBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // FAST ... + copiedFasts >= limit && + // + // MEDIUM ... + copiedMediumss >= limit && + // + // SLOW ... + copiedSlows >= limit + // + ; + if (!isPassedRequiredCopiedItems) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + close, + low, + tick_volume // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + fastLength > 2 && + mediumLength > 2 && + slowLength > 2 && + mediumLength > fastLength && + mediumLength < slowLength + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(fastLength, mediumLength); + result = MathMax(result, slowLength); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // Plot Buffers ... + + // + // FAST ... + + // + ArraySetAsSeries(fastBuffer, true); + SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(fastBufferIndex, PLOT_SHOW_DATA, showFast); + + // + PlotIndexSetDouble(fastBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(fastColorBuffer, true); + SetIndexBuffer(fastColorBufferIndex, fastColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM ... + + // + ArraySetAsSeries(mediumBuffer, true); + SetIndexBuffer(mediumBufferIndex, mediumBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mediumBufferIndex, PLOT_SHOW_DATA, showMedium); + + // + PlotIndexSetDouble(mediumBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(mediumColorBuffer, true); + SetIndexBuffer(mediumColorBufferIndex, mediumColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SLOW ... + + // + ArraySetAsSeries(slowBuffer, true); + SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(slowBufferIndex, PLOT_SHOW_DATA, showSlow); + + // + PlotIndexSetDouble(slowBufferIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(slowColorBuffer, true); + SetIndexBuffer(slowColorBufferIndex, slowColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Data Buffers ... + + // + // FAST State ... + ArraySetAsSeries(fastStateBuffer, true); + SetIndexBuffer(fastStateBufferIndex, fastStateBuffer, INDICATOR_CALCULATIONS); + + // + // MEDIUM State ... + ArraySetAsSeries(mediumStateBuffer, true); + SetIndexBuffer(mediumStateBufferIndex, mediumStateBuffer, INDICATOR_CALCULATIONS); + + // + // SLOW State ... + ArraySetAsSeries(slowStateBuffer, true); + SetIndexBuffer(slowStateBufferIndex, slowStateBuffer, INDICATOR_CALCULATIONS); +} + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Calculate Custom Buffers ... + * + * @param bar_index: Integer, Represent Current Bar ... + * @param prevCalculated: Integer, Represent Previous Calculated Bars ... + * @param ratesTotal: Integer, Represents All Available Bars ... + * @param open: Double Array, History of Open Prices ... + * @param high: Double Array, History of High Prices ... + * @param close: Double Array, History of Close Prices ... + * @param low: Double Array, History of Low Prices ... + * @param tickVolume: Long, History of Tick Volumes on Bar ... + */ +void CalculateBuffers( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int barsLimit = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : 0; + // + // bool canCalculate = true; + bool canCalculate = + barsLimit == 0 || + bar_index <= barsLimit; + if (canCalculate) + { + // + // Calculate Values ... + CalculateValues( + bar_index, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + } + else + { + FillBuffersZero(bar_index); + } +} + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + // FAST ... + fastBuffer[barIndex] = emptyValue; + fastColorBuffer[barIndex] = hideColorIDX; + fastStateBuffer[barIndex] = neuturalState; + + // + // MEDIUM ... + mediumBuffer[barIndex] = emptyValue; + mediumColorBuffer[barIndex] = hideColorIDX; + mediumStateBuffer[barIndex] = neuturalState; + + // + // SLOW ... + slowBuffer[barIndex] = emptyValue; + slowColorBuffer[barIndex] = hideColorIDX; + slowStateBuffer[barIndex] = neuturalState; +} + +/** + * Calculate Values ... + * + * @param bar_index: int, Specified Bar Index ... + * @param prevCalculated: int, Provides Previous Calculated Bars ... + * @param ratesTotal: int, Provides All Availabled Bars ... + * @param open: double Collection, Provides Open Prices Time Series ... + * @param high: double Collection, Provides High Prices Time Series ... + * @param close: double Collection, Provides Close Prices Time Series ... + * @param low: double Collection, Provides Low Prices Time Series ... + * @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ... + */ +void CalculateValues( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Check Prev Bar ... + + // + int lastBarIndex = bar_index + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? bar_index == startCalculationForLastBars + : bar_index == ratesTotal; + + // + double iLow = low[bar_index]; + double iHigh = high[bar_index]; + double iClose = close[bar_index]; + + // + // FAST ... + + // + double iFast = fastBuffer[bar_index]; + + // + double iFastState = + iLow > iFast + ? bullishState + : iHigh < iFast + ? bearishState + : neuturalState; + double iFastColor = hideColorIDX; + if (showFast) + { + // + if (applyColor) + { + // + iFastColor = + iFastState == bullishState + ? bullishColorIDX + : iFastState == bearishState + ? bearishColorIDX + : neuturalColorIDX; + } + else + { + iFastColor = bullishColorIDX; + } + } + fastColorBuffer[bar_index] = iFastColor; + fastStateBuffer[bar_index] = iFastState; + + // + // MEDIUM ... + + // + double iMedium = mediumBuffer[bar_index]; + + // + double iMediumState = + iLow > iMedium + ? bullishState + : iHigh < iMedium + ? bearishState + : neuturalState; + double iMediumColor = hideColorIDX; + if (showMedium) + { + // + if (applyColor) + { + // + iMediumColor = + iMediumState == bullishState + ? bullishColorIDX + : iMediumState == bearishState + ? bearishColorIDX + : neuturalColorIDX; + } + else + { + iMediumColor = bullishColorIDX; + } + } + mediumColorBuffer[bar_index] = iMediumColor; + mediumStateBuffer[bar_index] = iMediumState; + + // + // SLOW ... + + // + double iSlow = slowBuffer[bar_index]; + + // + double iSlowState = + iLow > iSlow + ? bullishState + : iHigh < iSlow + ? bearishState + : neuturalState; + double iSlowColor = hideColorIDX; + if (showSlow) + { + // + if (applyColor) + { + // + iSlowColor = + iSlowState == bullishState + ? bullishColorIDX + : iSlowState == bearishState + ? bearishColorIDX + : neuturalColorIDX; + } + else + { + iSlowColor = bullishColorIDX; + } + } + slowColorBuffer[bar_index] = iSlowColor; + slowStateBuffer[bar_index] = iSlowState; +} + +// \ No newline at end of file diff --git a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 index 5d2a5120..cdadc0de 100644 --- a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 +++ b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 @@ -474,6 +474,7 @@ struct XCAPVFVG { // double value; + datetime from; XBoxZone fvgs[]; ENUM_X_DIRECTION dir; @@ -492,6 +493,7 @@ struct XCAPVFVG // value = 0; Clean(fvgs); + from = NULL; dir = X_DIRECTION_NONE; } @@ -503,6 +505,7 @@ struct XCAPVFVG // result = value > 0 && + IsValid(from) && HasChild(fvgs) && HasDirection(dir); @@ -599,6 +602,51 @@ struct XCAPVFVG // }; +// +int GetOldest(XCAPVFVG &items[]) +{ + // + int result = -1; + + // + bool has = HasChild(items); + if (!has) + { + return result; + } + + // + XCAPVFVG item; + int count = ArraySize(items); + for (int i = 0; i < count; i++) + { + // + XCAPVFVG iPVFVG = items[i]; + + // + bool canSet = + !item.IsValid() + ? true + : item.from > iPVFVG.from; + if (canSet) + { + // + result = i; + item = iPVFVG; + } + + // + iPVFVG.Clean(); + } + + // + has = IsValidIndex(result); + item.Clean(); + + // + return result; +} + // // Implementations ... class XCXCAEAPOIDetector : public XCBase @@ -623,6 +671,10 @@ class XCXCAEAPOIDetector : public XCBase XBoxZone trendPivotC; // Current Pivot of Market Trend ... ENUM_X_DIRECTION trendDir; // Trend Direction ... + // + // Breaked Pivots ... + XBoxZone invalidPivots[]; + // // TICK Pivots ... @@ -641,7 +693,6 @@ class XCXCAEAPOIDetector : public XCBase // RSI Peak Pivot ... // - XCAPivot rsiPeakPivot; bool detectRSIPeakPivots; XBoxZone rsiPeakPivots[]; bool newRSIPeakPivotDetected; @@ -650,7 +701,6 @@ class XCXCAEAPOIDetector : public XCBase // RSI Vale Pivot ... // - XCAPivot rsiValePivot; bool detectRSIValePivots; XBoxZone rsiValePivots[]; bool newRSIValePivotDetected; @@ -659,7 +709,6 @@ class XCXCAEAPOIDetector : public XCBase // CCI Peak Pivot ... // - XCAPivot cciPeakPivot; bool detectCCIPeakPivots; XBoxZone cciPeakPivots[]; bool newCCIPeakPivotDetected; @@ -668,7 +717,6 @@ class XCXCAEAPOIDetector : public XCBase // CCI Vale Pivot ... // - XCAPivot cciValePivot; bool detectCCIValePivots; XBoxZone cciValePivots[]; bool newCCIValePivotDetected; @@ -723,6 +771,38 @@ class XCXCAEAPOIDetector : public XCBase XCAPVFVG pvFVGBearishPivots[]; bool newPVFVGBearishPivotDetected; + // + // RSI Crossed Over OS Pivot ... + + // + bool detectRSICrossedOverOSPivots; + XBoxZone rsiCrossedOverOSPivots[]; + bool newRSICrossedOverOSPivotDetected; + + // + // RSI Crossed Under OB Pivot ... + + // + bool detectRSICrossedUnderOBPivots; + XBoxZone rsiCrossedUnderOBPivots[]; + bool newRSICrossedUnderOBPivotDetected; + + // + // CCI Crossed Over OS Pivot ... + + // + bool detectCCICrossedOverOSPivots; + XBoxZone cciCrossedOverOSPivots[]; + bool newCCICrossedOverOSPivotDetected; + + // + // CCI Crossed Under OB Pivot ... + + // + bool detectCCICrossedUnderOBPivots; + XBoxZone cciCrossedUnderOBPivots[]; + bool newCCICrossedUnderOBPivotDetected; + // // Constructors ... XCXCAEAPOIDetector( @@ -743,10 +823,6 @@ class XCXCAEAPOIDetector : public XCBase ~XCXCAEAPOIDetector() { // - rsiPeakPivot.Clean(); - rsiValePivot.Clean(); - cciPeakPivot.Clean(); - cciValePivot.Clean(); valeSupSWLPivot.Clean(); peakResSWHPivot.Clean(); @@ -793,6 +869,10 @@ class XCXCAEAPOIDetector : public XCBase detectPeakResSWHPivots = true; detectPVFVGBullishPivots = true; detectPVFVGBearishPivots = true; + detectRSICrossedOverOSPivots = true; + detectRSICrossedUnderOBPivots = true; + detectCCICrossedOverOSPivots = true; + detectCCICrossedUnderOBPivots = true; // trendDir = X_DIRECTION_NONE; @@ -829,6 +909,10 @@ class XCXCAEAPOIDetector : public XCBase newPeakResSWHPivotDetected = false; newPVFVGBullishPivotDetected = false; newPVFVGBearishPivotDetected = false; + newRSICrossedOverOSPivotDetected = false; + newRSICrossedUnderOBPivotDetected = false; + newCCICrossedOverOSPivotDetected = false; + newCCICrossedUnderOBPivotDetected = false; // int zIDX = 0; @@ -851,6 +935,10 @@ class XCXCAEAPOIDetector : public XCBase start, 5 // ); + if (!has) { + conditions.Clean(); + continue; + } // // Retrieve Bars ... @@ -1899,6 +1987,314 @@ class XCXCAEAPOIDetector : public XCBase } } + // + // RSI Crossed Over OS ... + if (detectRSICrossedOverOSPivots) + { + // + bool checkingCondition = + // isRSIVale && + // isCBarHasBullishPower && + conditions.isRSICrossedOverOS; + + // + if (checkingCondition) + { + // + XCAPivot iPivot; + + // + iPivot.to = cBar.time; + iPivot.value = pBar.low; + iPivot.from = p2Bar.time; + iPivot.type = XCA_RSI_COOS; + iPivot.symbol = cBar.symbol; + iPivot.period = cBar.period; + + // + Add( + cBar.high, + iPivot.values // + ); + Add( + pBar.high, + iPivot.values // + ); + Add( + p2Bar.high, + iPivot.values // + ); + Add( + cBar.low, + iPivot.values // + ); + Add( + pBar.low, + iPivot.values // + ); + Add( + p2Bar.low, + iPivot.values // + ); + + // + iPivot.value = GetMin(iPivot.values); + iPivot.reserve = GetMax(iPivot.values); + + // + XBoxZone iBox; + has = iPivot.IsValid(); + if (has) + { + // + has = iPivot.AsBox(iBox); + if (has) + { + // + newRSICrossedOverOSPivotDetected = AddBox( + iBox, + rsiCrossedOverOSPivots // + ); + } + } + + // + iBox.Clean(); + iPivot.Clean(); + } + } + + // + // RSI Crossed Under OB ... + if (detectRSICrossedUnderOBPivots) + { + // + bool checkingCondition = + // isRSIPeak && + // isCBarHasBearishPower && + conditions.isRSICrossedUnderOB; + + // + if (checkingCondition) + { + // + XCAPivot iPivot; + + // + iPivot.to = cBar.time; + iPivot.from = p2Bar.time; + iPivot.value = pBar.high; + iPivot.type = XCA_RSI_CUOB; + iPivot.symbol = cBar.symbol; + iPivot.period = cBar.period; + + // + Add( + cBar.high, + iPivot.values // + ); + Add( + pBar.high, + iPivot.values // + ); + Add( + p2Bar.high, + iPivot.values // + ); + Add( + cBar.low, + iPivot.values // + ); + Add( + pBar.low, + iPivot.values // + ); + Add( + p2Bar.low, + iPivot.values // + ); + + // + iPivot.value = GetMax(iPivot.values); + iPivot.reserve = GetMin(iPivot.values); + + // + XBoxZone iBox; + has = iPivot.IsValid(); + if (has) + { + // + has = iPivot.AsBox(iBox); + if (has) + { + // + newRSICrossedUnderOBPivotDetected = AddBox( + iBox, + rsiCrossedUnderOBPivots // + ); + } + } + + // + iBox.Clean(); + iPivot.Clean(); + } + } + + // + // CCI Crossed Over OS ... + if (detectCCICrossedOverOSPivots) + { + // + bool checkingCondition = + isCCIVale && + // isCBarHasBullishPower && + conditions.isCCICrossedOverOS; + + // + if (checkingCondition) + { + // + XCAPivot iPivot; + + // + iPivot.to = cBar.time; + iPivot.value = pBar.low; + iPivot.from = p2Bar.time; + iPivot.type = XCA_CCI_COOS; + iPivot.symbol = cBar.symbol; + iPivot.period = cBar.period; + + // + Add( + cBar.high, + iPivot.values // + ); + Add( + pBar.high, + iPivot.values // + ); + Add( + p2Bar.high, + iPivot.values // + ); + Add( + cBar.low, + iPivot.values // + ); + Add( + pBar.low, + iPivot.values // + ); + Add( + p2Bar.low, + iPivot.values // + ); + + // + iPivot.value = GetMin(iPivot.values); + iPivot.reserve = GetMax(iPivot.values); + + // + XBoxZone iBox; + has = iPivot.IsValid(); + if (has) + { + // + has = iPivot.AsBox(iBox); + if (has) + { + // + newCCICrossedOverOSPivotDetected = AddBox( + iBox, + cciCrossedOverOSPivots // + ); + } + } + + // + iBox.Clean(); + iPivot.Clean(); + } + } + + // + // CCI Crossed Under OB ... + if (detectCCICrossedUnderOBPivots) + { + // + bool checkingCondition = + isCCIPeak && + // isCBarHasBearishPower && + conditions.isCCICrossedUnderOB; + + // + if (checkingCondition) + { + // + XCAPivot iPivot; + + // + iPivot.to = cBar.time; + iPivot.from = p2Bar.time; + iPivot.value = pBar.high; + iPivot.type = XCA_CCI_CUOB; + iPivot.symbol = cBar.symbol; + iPivot.period = cBar.period; + + // + Add( + cBar.high, + iPivot.values // + ); + Add( + pBar.high, + iPivot.values // + ); + Add( + p2Bar.high, + iPivot.values // + ); + Add( + cBar.low, + iPivot.values // + ); + Add( + pBar.low, + iPivot.values // + ); + Add( + p2Bar.low, + iPivot.values // + ); + + // + iPivot.value = GetMax(iPivot.values); + iPivot.reserve = GetMin(iPivot.values); + + // + XBoxZone iBox; + has = iPivot.IsValid(); + if (has) + { + // + has = iPivot.AsBox(iBox); + if (has) + { + // + newCCICrossedUnderOBPivotDetected = AddBox( + iBox, + cciCrossedUnderOBPivots // + ); + } + } + + // + iBox.Clean(); + iPivot.Clean(); + } + } + // start++; @@ -1912,8 +2308,7 @@ class XCXCAEAPOIDetector : public XCBase } // - // Detect Market Trend ... - DetectMarketTrend(); + SortPivots(); } // @@ -1932,7 +2327,6 @@ class XCXCAEAPOIDetector : public XCBase } // - XBoxZone tmp[]; bool has = false; // @@ -1974,46 +2368,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( rsiPeakPivots, - tmp // + unAvailableBoxes // ); - Clean(rsiPeakPivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - rsiPeakPivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2024,46 +2382,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( rsiValePivots, - tmp // + unAvailableBoxes // ); - Clean(rsiValePivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - rsiValePivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2074,46 +2396,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( cciPeakPivots, - tmp // + unAvailableBoxes // ); - Clean(cciPeakPivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - cciPeakPivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2124,46 +2410,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( cciValePivots, - tmp // + unAvailableBoxes // ); - Clean(cciValePivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - cciValePivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2174,46 +2424,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( fvgBullishPivots, - tmp // + unAvailableBoxes // ); - Clean(fvgBullishPivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - fvgBullishPivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2224,46 +2438,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( fvgBearishPivots, - tmp // + unAvailableBoxes // ); - Clean(fvgBearishPivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - fvgBearishPivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2274,46 +2452,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( valeSupSWLPivots, - tmp // + unAvailableBoxes // ); - Clean(valeSupSWLPivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - valeSupSWLPivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2324,46 +2466,10 @@ class XCXCAEAPOIDetector : public XCBase if (has) { // - // Copy Items and Cleanup Collection ... - Copy( + ApplyValidationOnBox( peakResSWHPivots, - tmp // + unAvailableBoxes // ); - Clean(peakResSWHPivots); - - // - // Do Validation ... - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - peakResSWHPivots // - ); - } - - // - iBox.Clean(); - } - - // - Clean(tmp); } // @@ -2395,39 +2501,10 @@ class XCXCAEAPOIDetector : public XCBase 0, 1 // ); - Copy( + ApplyValidationOnBox( iPVFVG.fvgs, - tmp // + unAvailableBoxes // ); - Clean(iPVFVG.fvgs); - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - iPVFVG.fvgs // - ); - } - - // - iBox.Clean(); - } // if (iPVFVG.IsValid()) @@ -2441,7 +2518,6 @@ class XCXCAEAPOIDetector : public XCBase } // - Clean(tmp); Clean(tmpPVFVG); } @@ -2474,39 +2550,10 @@ class XCXCAEAPOIDetector : public XCBase 0, 1 // ); - Copy( + ApplyValidationOnBox( iPVFVG.fvgs, - tmp // + unAvailableBoxes // ); - Clean(iPVFVG.fvgs); - while (HasChild(tmp)) - { - // - XBoxZone iBox = tmp[0]; - ArrayRemove( - tmp, - 0, - 1 // - ); - - // - has = ValidateBox( - iBox, - unAvailableBoxes, - barIndex // - ); - if (has) - { - // - AddRef( - iBox, - iPVFVG.fvgs // - ); - } - - // - iBox.Clean(); - } // if (iPVFVG.IsValid()) @@ -2520,19 +2567,67 @@ class XCXCAEAPOIDetector : public XCBase } // - Clean(tmp); Clean(tmpPVFVG); } // - Clean(tmp); + // RSI Crossed Over OS ... // - ReversePivots(); + has = HasRSICrossedOverOSPivots(); + if (has) + { + // + ApplyValidationOnBox( + rsiCrossedOverOSPivots, + unAvailableBoxes // + ); + } // - // Detect Market Trend ... - DetectMarketTrend(); + // RSI Crossed Under OB ... + + // + has = HasRSICrossedUnderOBPivots(); + if (has) + { + // + ApplyValidationOnBox( + rsiCrossedUnderOBPivots, + unAvailableBoxes // + ); + } + + // + // CCI Crossed Over OS ... + + // + has = HasCCICrossedOverOSPivots(); + if (has) + { + // + ApplyValidationOnBox( + cciCrossedOverOSPivots, + unAvailableBoxes // + ); + } + + // + // CCI Crossed Under OB ... + + // + has = HasCCICrossedUnderOBPivots(); + if (has) + { + // + ApplyValidationOnBox( + cciCrossedUnderOBPivots, + unAvailableBoxes // + ); + } + + // + SortPivots(); } // @@ -2599,6 +2694,20 @@ class XCXCAEAPOIDetector : public XCBase false // ); + // + Copy( + rsiCrossedOverOSPivots, + pivots, + false // + ); + + // + Copy( + cciCrossedOverOSPivots, + pivots, + false // + ); + // has = HasPVFVGBullishPivots(); if (has) @@ -2657,6 +2766,20 @@ class XCXCAEAPOIDetector : public XCBase false // ); + // + Copy( + rsiCrossedUnderOBPivots, + pivots, + false // + ); + + // + Copy( + cciCrossedUnderOBPivots, + pivots, + false // + ); + // has = HasPVFVGBearishPivots(); if (has) @@ -2711,6 +2834,21 @@ class XCXCAEAPOIDetector : public XCBase // // Counters ... + // + // INVALID Pivots ... + + // + bool HasInvalidPivots() + { + return HasChild(invalidPivots); + } + + // + int CountInvalidPivots() + { + return ArraySize(invalidPivots); + } + // // TICK Pivot ... @@ -2891,6 +3029,66 @@ class XCXCAEAPOIDetector : public XCBase return ArraySize(pvFVGBearishPivots); } + // + // RSI Crossed Over OS Pivots ... + + // + bool HasRSICrossedOverOSPivots() + { + return HasChild(rsiCrossedOverOSPivots); + } + + // + int CountRSICrossedOverOSPivots() + { + return ArraySize(rsiCrossedOverOSPivots); + } + + // + // RSI Crossed Under OB Pivots ... + + // + bool HasRSICrossedUnderOBPivots() + { + return HasChild(rsiCrossedUnderOBPivots); + } + + // + int CountRSICrossedUnderOBPivots() + { + return ArraySize(rsiCrossedUnderOBPivots); + } + + // + // CCI Crossed Over OS Pivots ... + + // + bool HasCCICrossedOverOSPivots() + { + return HasChild(cciCrossedOverOSPivots); + } + + // + int CountCCICrossedOverOSPivots() + { + return ArraySize(rsiCrossedOverOSPivots); + } + + // + // CCI Crossed Under OB Pivots ... + + // + bool HasCCICrossedUnderOBPivots() + { + return HasChild(cciCrossedUnderOBPivots); + } + + // + int CountCCICrossedUnderOBPivots() + { + return ArraySize(cciCrossedUnderOBPivots); + } + // // Protected ... protected: @@ -2911,19 +3109,12 @@ class XCXCAEAPOIDetector : public XCBase // bool AddBox( XBoxZone &box, - XBoxZone &boxes[], - int maxAllowed = 0 // + XBoxZone &boxes[] // ) { // bool result = false; - // - if (maxAllowed <= 0) - { - maxAllowed = maxAllowedPivots; - } - // result = box.IsValid(); if (!result) @@ -2946,31 +3137,18 @@ class XCXCAEAPOIDetector : public XCBase // int before = ArraySize(boxes); - if (IsValidSize(before)) - { - ArrayReverse(boxes); - } // AddRef( box, boxes // ); + + // int after = ArraySize(boxes); // result = after > before; - if (result) - { - // - ArrayReverse(boxes); - - // - CleanupArray( - boxes, - maxAllowed // - ); - } // return result; @@ -3010,10 +3188,10 @@ class XCXCAEAPOIDetector : public XCBase box, unAvailableBoxes // ); - result = isUnAvailable; + result = !isUnAvailable; if (!result) { - return !result; + return result; } } @@ -3156,6 +3334,9 @@ class XCXCAEAPOIDetector : public XCBase // void CleanPivots() { + // + Clean(invalidPivots); + // Clean(tickPivots); Clean(volumePivots); @@ -3169,24 +3350,315 @@ class XCXCAEAPOIDetector : public XCBase Clean(peakResSWHPivots); Clean(pvFVGBullishPivots); Clean(pvFVGBearishPivots); + Clean(rsiCrossedOverOSPivots); + Clean(rsiCrossedUnderOBPivots); + Clean(cciCrossedOverOSPivots); + Clean(cciCrossedUnderOBPivots); } // - void ReversePivots() + void SortPivots() { // - ArrayReverse(tickPivots); - ArrayReverse(volumePivots); - ArrayReverse(rsiPeakPivots); - ArrayReverse(rsiValePivots); - ArrayReverse(cciPeakPivots); - ArrayReverse(cciValePivots); - ArrayReverse(fvgBullishPivots); - ArrayReverse(fvgBearishPivots); - ArrayReverse(valeSupSWLPivots); - ArrayReverse(peakResSWHPivots); - ArrayReverse(pvFVGBullishPivots); - ArrayReverse(pvFVGBearishPivots); + bool has = false; + + // + // RSI Peak ... + has = HasRSIPeakPivots(); + if (has) + { + ApplySortOnBox(rsiPeakPivots); + } + + // + // RSI Vale ... + has = HasRSIValePivots(); + if (has) + { + ApplySortOnBox(rsiValePivots); + } + + // + // CCI Peak ... + has = HasCCIPeakPivots(); + if (has) + { + ApplySortOnBox(cciPeakPivots); + } + + // + // CCI Vale ... + has = HasCCIValePivots(); + if (has) + { + ApplySortOnBox(cciValePivots); + } + + // + // FVG Bullish ... + has = HasFVGBullishPivots(); + if (has) + { + ApplySortOnBox(fvgBullishPivots); + } + + // + // FVG Bearish ... + has = HasFVGBearishPivots(); + if (has) + { + ApplySortOnBox(fvgBearishPivots); + } + + // + // VALE SUP SWL ... + has = HasValeSupSWLPivots(); + if (has) + { + ApplySortOnBox(valeSupSWLPivots); + } + + // + // PEAK REs SWH ... + has = HasPeakResSWHPivots(); + if (has) + { + ApplySortOnBox(peakResSWHPivots); + } + + // + // PVFVG Bullish ... + has = HasPVFVGBullishPivots(); + if (has) + { + ApplySortOnPVFVG(pvFVGBullishPivots); + } + + // + // PVFVG Bearish ... + has = HasPVFVGBearishPivots(); + if (has) + { + ApplySortOnPVFVG(pvFVGBearishPivots); + } + + // + // RSI Crossed Over OS ... + has = HasRSICrossedOverOSPivots(); + if (has) + { + ApplySortOnBox(rsiCrossedOverOSPivots); + } + + // + // RSI Crossed Under OB ... + has = HasRSICrossedUnderOBPivots(); + if (has) + { + ApplySortOnBox(rsiCrossedUnderOBPivots); + } + + // + // CCI Crossed Over OS ... + has = HasCCICrossedOverOSPivots(); + if (has) + { + ApplySortOnBox(cciCrossedOverOSPivots); + } + + // + // CCI Crossed Under OB ... + has = HasCCICrossedUnderOBPivots(); + if (has) + { + ApplySortOnBox(cciCrossedUnderOBPivots); + } + + // + // INVALID Pivots ... + has = HasInvalidPivots(); + if (has) + { + ApplySortOnBox(invalidPivots); + } + } + + // + void ApplyValidationOnBox( + XBoxZone &items[], + XBoxZone &unAvailableItems[], + int barIndex = 0 // + ) + { + // + bool has = false; + + // + has = HasChild(items); + if (!has) + { + return; + } + + // + XBoxZone tmp[]; + Copy( + items, + tmp // + ); + Clean(items); + while (HasChild(tmp)) + { + // + XBoxZone iBox = tmp[0]; + ArrayRemove( + tmp, + 0, + 1 // + ); + + // + has = ValidateBox( + iBox, + unAvailableItems, + barIndex // + ); + if (has) + { + // + AddRef( + iBox, + items // + ); + } + + // + iBox.Clean(); + // + } + + // + Clean(tmp); + } + + // + void ApplySortOnBox( + XBoxZone &items[] // + ) + { + // + int idx = -1; + bool has = false; + + // + has = HasChild(items); + if (!has) + { + return; + } + + // + XBoxZone tmp[]; + Copy( + items, + tmp // + ); + Clean(items); + + // + while (HasChild(tmp)) + { + // + idx = GetOldest(tmp); + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + XBoxZone iBox = tmp[idx]; + ArrayRemove( + tmp, + idx, + 1 // + ); + + // + AddRef( + iBox, + items // + ); + } + + // + CleanupArray( + items, + maxAllowedPivots // + ); + + // + Clean(tmp); + } + + // + void ApplySortOnPVFVG( + XCAPVFVG &items[] // + ) + { + // + int idx = -1; + bool has = false; + + // + has = HasChild(items); + if (!has) + { + return; + } + + // + XCAPVFVG tmp[]; + Copy( + items, + tmp // + ); + Clean(items); + + // + while (HasChild(tmp)) + { + // + idx = GetOldest(items); + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + XCAPVFVG iPVFVG = tmp[idx]; + ArrayRemove( + tmp, + idx, + 1 // + ); + + // + AddRef( + iPVFVG, + items // + ); + } + + // + CleanupArray( + items, + maxAllowedPivots // + ); + + // + Clean(tmp); } // @@ -3362,13 +3834,42 @@ class XCXCAEAPOIDetector : public XCBase // XBoxZone tmp[]; - count = FillPivots(tmp); + has = HasPeakResSWHPivots(); + if (has) + { + // + Copy( + peakResSWHPivots, + tmp, + false // + ); + } + has = HasValeSupSWLPivots(); + if (has) + { + // + Copy( + valeSupSWLPivots, + tmp, + false // + ); + } + count = ArraySize(tmp); has = HasChild(tmp); if (!has) { return; } + // + has = HasDirection(trendDir); + if (!has) + { + // + trendPivotC.Clean(); + trendPivotP.Clean(); + } + // XBoxZone cPivot; XBoxZone pPivot; @@ -3387,36 +3888,19 @@ class XCXCAEAPOIDetector : public XCBase } // + iPivot = tmp[idx]; ArrayRemove( tmp, idx, 1 // ); - // - // Check Pivot Type is Peak or Vale ... - has = - Contains( - "XCA_PEAKSWHRES", - iPivot.type // - ) || - Contains( - "XCA_VALESWLSUP", - iPivot.type // - ); - if (!has) - { - // - iPivot.Clean(); - break; - } - // // Check Can Set CPivot ... bool canSetCPivot = !cPivot.IsValid() ? true - : cPivot.from < iPivot.from; + : iPivot.from > cPivot.from; if (canSetCPivot) { // @@ -3437,7 +3921,7 @@ class XCXCAEAPOIDetector : public XCBase : iPivot.from < cPivot.from ? !pPivot.IsValid() ? true - : cPivot.from < iPivot.from + : iPivot.from > pPivot.from : false; if (canSetPPivot) { diff --git a/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 b/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 index 1a778a75..c68e7c78 100644 --- a/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 +++ b/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 @@ -56,6 +56,10 @@ class XCXCAEAPOIDrawer : public XCBase bool drawPeakResSWHPivots; bool drawPVFVGBullishPivots; bool drawPVFVGBearishPivots; + bool drawRSICrossedOverOSPivots; + bool drawRSICrossedUnderOBPivots; + bool drawCCICrossedOverOSPivots; + bool drawCCICrossedUnderOBPivots; // // Colors ... @@ -79,7 +83,11 @@ class XCXCAEAPOIDrawer : public XCBase color trendLineBearishColor; color pvFVGBullishPivotsColor; color pvFVGBearishPivotsColor; - + color rsiCrossedOverOSPivotsColor; + color rsiCrossedUnderOBPivotsColor; + color cciCrossedOverOSPivotsColor; + color cciCrossedUnderOBPivotsColor; + // // Width ... @@ -102,6 +110,10 @@ class XCXCAEAPOIDrawer : public XCBase int trendLineBearishWidth; int pvFVGBullishPivotsWidth; int pvFVGBearishPivotsWidth; + int rsiCrossedOverOSPivotsWidth; + int rsiCrossedUnderOBPivotsWidth; + int cciCrossedOverOSPivotsWidth; + int cciCrossedUnderOBPivotsWidth; // // Style ... @@ -125,6 +137,10 @@ class XCXCAEAPOIDrawer : public XCBase ENUM_LINE_STYLE trendLineBearishStyle; ENUM_LINE_STYLE pvFVGBullishPivotsStyle; ENUM_LINE_STYLE pvFVGBearishPivotsStyle; + ENUM_LINE_STYLE rsiCrossedOverOSPivotsStyle; + ENUM_LINE_STYLE rsiCrossedUnderOBPivotsStyle; + ENUM_LINE_STYLE cciCrossedOverOSPivotsStyle; + ENUM_LINE_STYLE cciCrossedUnderOBPivotsStyle; // // Colorize Props ... @@ -187,6 +203,10 @@ class XCXCAEAPOIDrawer : public XCBase drawPeakResSWHPivots = false; drawPVFVGBullishPivots = false; drawPVFVGBearishPivots = false; + drawRSICrossedOverOSPivots = false; + drawRSICrossedUnderOBPivots = false; + drawCCICrossedOverOSPivots = false; + drawCCICrossedUnderOBPivots = false; // defaultBullishColor = clrLime; @@ -203,7 +223,9 @@ class XCXCAEAPOIDrawer : public XCBase valeSupSWLPivotsColor = defaultBullishColor; trendLineBullishColor = defaultBullishColor; pvFVGBullishPivotsColor = defaultBullishColor; - + rsiCrossedOverOSPivotsColor = defaultBullishColor; + cciCrossedOverOSPivotsColor = defaultBullishColor; + // rsiPeakPivotsColor = defaultBearishColor; cciPeakPivotsColor = defaultBearishColor; @@ -211,15 +233,17 @@ class XCXCAEAPOIDrawer : public XCBase peakResSWHPivotsColor = defaultBearishColor; trendLineBearishColor = defaultBearishColor; pvFVGBearishPivotsColor = defaultBearishColor; - + rsiCrossedUnderOBPivotsColor = defaultBearishColor; + cciCrossedUnderOBPivotsColor = defaultBearishColor; + // defaultBullishWidth = 1; defaultBearishWidth = 1; - + // tickPivotsWidth = defaultBullishWidth; volumePivotsWidth = defaultBearishWidth; - + // rsiValePivotsWidth = defaultBullishWidth; cciValePivotsWidth = defaultBullishWidth; @@ -227,7 +251,9 @@ class XCXCAEAPOIDrawer : public XCBase valeSupSWLPivotsWidth = defaultBullishWidth; trendLineBullishWidth = defaultBullishWidth; pvFVGBullishPivotsWidth = defaultBullishWidth; - + rsiCrossedOverOSPivotsWidth = defaultBullishWidth; + cciCrossedOverOSPivotsWidth = defaultBullishWidth; + // rsiPeakPivotsWidth = defaultBearishWidth; cciPeakPivotsWidth = defaultBearishWidth; @@ -235,15 +261,17 @@ class XCXCAEAPOIDrawer : public XCBase peakResSWHPivotsWidth = defaultBearishWidth; trendLineBearishWidth = defaultBearishWidth; pvFVGBearishPivotsWidth = defaultBearishWidth; - + rsiCrossedUnderOBPivotsWidth = defaultBearishWidth; + cciCrossedUnderOBPivotsWidth = defaultBearishWidth; + // defaultBullishStyle = STYLE_SOLID; defaultBearishStyle = STYLE_SOLID; - + // tickPivotsStyle = defaultBullishStyle; volumePivotsStyle = defaultBearishStyle; - + // rsiValePivotsStyle = defaultBullishStyle; cciValePivotsStyle = defaultBullishStyle; @@ -251,7 +279,9 @@ class XCXCAEAPOIDrawer : public XCBase valeSupSWLPivotsStyle = defaultBullishStyle; trendLineBullishStyle = defaultBullishStyle; pvFVGBullishPivotsStyle = defaultBullishStyle; - + rsiCrossedOverOSPivotsStyle = defaultBullishStyle; + cciCrossedOverOSPivotsStyle = defaultBullishStyle; + // rsiPeakPivotsStyle = defaultBearishStyle; cciPeakPivotsStyle = defaultBearishStyle; @@ -259,6 +289,8 @@ class XCXCAEAPOIDrawer : public XCBase peakResSWHPivotsStyle = defaultBearishStyle; trendLineBearishStyle = defaultBearishStyle; pvFVGBearishPivotsStyle = defaultBearishStyle; + rsiCrossedUnderOBPivotsStyle = defaultBearishStyle; + cciCrossedUnderOBPivotsStyle = defaultBearishStyle; } // @@ -278,6 +310,10 @@ class XCXCAEAPOIDrawer : public XCBase DrawPeakResSWHPivots(to); DrawPVFVGBullishPivots(to); DrawPVFVGBearishPivots(to); + DrawRSICrossedOverOSPivots(to); + DrawRSICrossedUnderOBPivots(to); + DrawCCICrossedOverOSPivots(to); + DrawCCICrossedUnderOBPivots(to); } // @@ -297,6 +333,10 @@ class XCXCAEAPOIDrawer : public XCBase mPeakResSWHPivotObjects.Clear(); mPVFVGBullishPivotObjects.Clear(); mPVFVGBearishPivotObjects.Clear(); + mRSICrossedOverOSPivotObjects.Clear(); + mRSICrossedUnderOBPivotObjects.Clear(); + mCCICrossedOverOSPivotObjects.Clear(); + mCCICrossedUnderOBPivotObjects.Clear(); } // @@ -312,6 +352,9 @@ class XCXCAEAPOIDrawer : public XCBase return; } + // + mTrendLineObjects.Clear(); + // ENUM_X_DIRECTION trend = X_DIRECTION_NONE; bool has = detector.MarketTrend(trend); @@ -333,7 +376,7 @@ class XCXCAEAPOIDrawer : public XCBase : detector.trendPivotP.upper; // - datetime pTime = detector.trendPivotC.from; + datetime pTime = detector.trendPivotP.from; // double cPrice = hasBullishTrend @@ -384,6 +427,7 @@ class XCXCAEAPOIDrawer : public XCBase iObj.Color(tlColor); iObj.Width(tlWidth); iObj.Style(tlStyle); + iObj.RayRight(true); // // Store Object ... @@ -1124,6 +1168,270 @@ class XCXCAEAPOIDrawer : public XCBase } } + // + void DrawRSICrossedOverOSPivots(datetime to = NULL) + { + // + bool has = drawRSICrossedOverOSPivots; + if (!has) + { + return; + } + + // + has = detector.HasRSICrossedOverOSPivots(); + if (!has) + { + return; + } + + // + if (ignoreUpdateOSCTos) + { + to = NULL; + } + + // + bool canUpdateTo = IsValid(to); + + // + int count = detector.CountRSICrossedOverOSPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.rsiCrossedOverOSPivots[i]; + + // + if (canUpdateTo) + { + iBox.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + iBox, + iObj // + ); + + // + if (has) + { + // + // Style Object ... + iObj.BoxColor(rsiCrossedOverOSPivotsColor); + iObj.BoxWidth(rsiCrossedOverOSPivotsWidth); + iObj.BoxStyle(rsiCrossedOverOSPivotsStyle); + + // + // Store Object ... + mRSICrossedOverOSPivotObjects.Add(iObj); + } + + // + iBox.Clean(); + ZeroMemory(iObj); + } + } + + // + void DrawRSICrossedUnderOBPivots(datetime to = NULL) + { + // + bool has = drawRSICrossedUnderOBPivots; + if (!has) + { + return; + } + + // + has = detector.HasRSICrossedUnderOBPivots(); + if (!has) + { + return; + } + + // + if (ignoreUpdateOSCTos) + { + to = NULL; + } + + // + bool canUpdateTo = IsValid(to); + + // + int count = detector.CountRSICrossedUnderOBPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.rsiCrossedUnderOBPivots[i]; + + // + if (canUpdateTo) + { + iBox.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + iBox, + iObj // + ); + + // + if (has) + { + // + // Style Object ... + iObj.BoxColor(rsiCrossedUnderOBPivotsColor); + iObj.BoxWidth(rsiCrossedUnderOBPivotsWidth); + iObj.BoxStyle(rsiCrossedUnderOBPivotsStyle); + + // + // Store Object ... + mRSICrossedUnderOBPivotObjects.Add(iObj); + } + + // + iBox.Clean(); + ZeroMemory(iObj); + } + } + + // + void DrawCCICrossedOverOSPivots(datetime to = NULL) + { + // + bool has = drawCCICrossedOverOSPivots; + if (!has) + { + return; + } + + // + has = detector.HasCCICrossedOverOSPivots(); + if (!has) + { + return; + } + + // + if (ignoreUpdateOSCTos) + { + to = NULL; + } + + // + bool canUpdateTo = IsValid(to); + + // + int count = detector.CountCCICrossedOverOSPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.cciCrossedOverOSPivots[i]; + + // + if (canUpdateTo) + { + iBox.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + iBox, + iObj // + ); + + // + if (has) + { + // + // Style Object ... + iObj.BoxColor(cciCrossedOverOSPivotsColor); + iObj.BoxWidth(cciCrossedOverOSPivotsWidth); + iObj.BoxStyle(cciCrossedOverOSPivotsStyle); + + // + // Store Object ... + mCCICrossedOverOSPivotObjects.Add(iObj); + } + + // + iBox.Clean(); + ZeroMemory(iObj); + } + } + + // + void DrawCCICrossedUnderOBPivots(datetime to = NULL) + { + // + bool has = drawCCICrossedUnderOBPivots; + if (!has) + { + return; + } + + // + has = detector.HasCCICrossedUnderOBPivots(); + if (!has) + { + return; + } + + // + if (ignoreUpdateOSCTos) + { + to = NULL; + } + + // + bool canUpdateTo = IsValid(to); + + // + int count = detector.CountCCICrossedUnderOBPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = detector.cciCrossedUnderOBPivots[i]; + + // + if (canUpdateTo) + { + iBox.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + iBox, + iObj // + ); + + // + if (has) + { + // + // Style Object ... + iObj.BoxColor(cciCrossedUnderOBPivotsColor); + iObj.BoxWidth(cciCrossedUnderOBPivotsWidth); + iObj.BoxStyle(cciCrossedUnderOBPivotsStyle); + + // + // Store Object ... + mCCICrossedUnderOBPivotObjects.Add(iObj); + } + + // + iBox.Clean(); + ZeroMemory(iObj); + } + } + // // Protected ... protected: @@ -1154,6 +1462,10 @@ class XCXCAEAPOIDrawer : public XCBase CArrayObj mPeakResSWHPivotObjects; CArrayObj mPVFVGBullishPivotObjects; CArrayObj mPVFVGBearishPivotObjects; + CArrayObj mRSICrossedOverOSPivotObjects; + CArrayObj mRSICrossedUnderOBPivotObjects; + CArrayObj mCCICrossedOverOSPivotObjects; + CArrayObj mCCICrossedUnderOBPivotObjects; // }; diff --git a/XCAEA/Helpers/xcaea.helper.mq5 b/XCAEA/Helpers/xcaea.helper.mq5 index be344d02..14f669f0 100644 --- a/XCAEA/Helpers/xcaea.helper.mq5 +++ b/XCAEA/Helpers/xcaea.helper.mq5 @@ -28,6 +28,7 @@ #include "../../Helpers/x-saherelm.x121.xca.helper.mq5" #include "../../Helpers/x-saherelm.x121.xcc.helper.mq5" #include "../../Helpers/x-saherelm.x121.xct.helper.mq5" +#include "../../Helpers/x-saherelm.x121.x3ma.helper.mq5" #include "../../Helpers/x-saherelm.x121.xoscs.helper.mq5" // @@ -51,6 +52,7 @@ struct XCAEAInputs X121XCTInputs ctInputs; X121XCCInputs ccInputs; X121XCAInputs caInputs; + X121X3MAInputs x3maInputs; X121XOCSInputs oscsInputs; // @@ -85,6 +87,7 @@ struct XCAEAInputs ctInputs.Clean(); ccInputs.Clean(); caInputs.Clean(); + x3maInputs.Clean(); oscsInputs.Clean(); // @@ -100,6 +103,7 @@ struct XCAEAInputs ctInputs.Default(); ccInputs.Default(); caInputs.Default(); + x3maInputs.Default(); oscsInputs.Default(); } @@ -119,7 +123,8 @@ struct XCAEAInputs ctInputs.IsValid() && ccInputs.IsValid() && caInputs.IsValid() && - oscsInputs.IsValid() + x3maInputs.IsValid() && + oscsInputs.IsValid() // ; @@ -142,11 +147,13 @@ struct XCAEAInputs int ccMax = ccInputs.Max(); int caMax = caInputs.Max(); int ocsMax = oscsInputs.Max(); + int x3maMax = x3maInputs.Max(); // result = MathMax(ctMax, ccMax); result = MathMax(result, caMax); result = MathMax(result, ocsMax); + result = MathMax(result, x3maMax); // return result; @@ -167,6 +174,47 @@ struct XCAEAConditions datetime to; datetime from; + // + // X3MA ... + + // + // Buffers ... + + // + double fastBuffer[]; + double mediumBuffer[]; + double slowBuffer[]; + double fastStateBuffer[]; + double mediumStateBuffer[]; + double slowStateBuffer[]; + + // + // Conditions ... + + // + bool isFastOverMedium; + bool isFastUnderMedium; + + // + bool isFastCrossedOverMedium; + bool isFastCrossedUnderMedium; + + // + bool isFastOverSlow; + bool isFastUnderSlow; + + // + bool isFastCrossedOverSlow; + bool isFastCrossedUnderSlow; + + // + bool isMediumOverSlow; + bool isMediumUnderSlow; + + // + bool isMediumCrossedOverSlow; + bool isMediumCrossedUnderSlow; + // // XCA ... @@ -673,6 +721,55 @@ struct XCAEAConditions from = NULL; time = NULL; + // + // X3MA ... + + // + // Buffers ... + + // + Clean(fastBuffer); + Clean(mediumBuffer); + Clean(slowBuffer); + Clean(fastStateBuffer); + Clean(mediumStateBuffer); + Clean(slowStateBuffer); + + // + ArraySetAsSeries(fastBuffer, true); + ArraySetAsSeries(mediumBuffer, true); + ArraySetAsSeries(slowBuffer, true); + ArraySetAsSeries(fastStateBuffer, true); + ArraySetAsSeries(mediumStateBuffer, true); + ArraySetAsSeries(slowStateBuffer, true); + + // + // Conditions ... + + // + isFastOverMedium = false; + isFastUnderMedium = false; + + // + isFastCrossedOverMedium = false; + isFastCrossedUnderMedium = false; + + // + isFastOverSlow = false; + isFastUnderSlow = false; + + // + isFastCrossedOverSlow = false; + isFastCrossedUnderSlow = false; + + // + isMediumOverSlow = false; + isMediumUnderSlow = false; + + // + isMediumCrossedOverSlow = false; + isMediumCrossedUnderSlow = false; + // // XCA ... @@ -1158,9 +1255,64 @@ struct XCAEAConditions double minScore = 0.5; double highScore = 1.5; + // + // X3MA ... + // // XCA ... + // + if (isFastOverSlow) + { + bullishScore += minScore; + } + if (isFastOverMedium) + { + bullishScore += minScore; + } + if (isMediumOverSlow) + { + bullishScore += minScore; + } + if (isFastCrossedOverSlow) + { + bullishScore += score; + } + if (isFastCrossedOverMedium) + { + bullishScore += score; + } + if (isMediumCrossedOverSlow) + { + bullishScore += score; + } + + // + if (isFastUnderSlow) + { + bearishScore += minScore; + } + if (isMediumUnderSlow) + { + bearishScore += minScore; + } + if (isFastUnderMedium) + { + bearishScore += minScore; + } + if (isFastCrossedUnderSlow) + { + bearishScore += score; + } + if (isFastCrossedUnderMedium) + { + bearishScore += score; + } + if (isMediumCrossedUnderSlow) + { + bearishScore += score; + } + // // KI ... @@ -1931,6 +2083,22 @@ struct XCAEAConditions // string conditionsStr = // + // + "-----------------------" + separator + + "X3MA: " + separator + + "-----------------------" + separator + + ToString("isFastOverMedium", isFastOverMedium, ignoreFalseConditions, separator) + + ToString("isFastUnderMedium", isFastUnderMedium, ignoreFalseConditions, separator) + + ToString("isFastCrossedOverMedium", isFastCrossedOverMedium, ignoreFalseConditions, separator) + + ToString("isFastCrossedUnderMedium", isFastCrossedUnderMedium, ignoreFalseConditions, separator) + + ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions, separator) + + ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions, separator) + + ToString("isFastCrossedOverSlow", isFastCrossedOverSlow, ignoreFalseConditions, separator) + + ToString("isFastCrossedUnderSlow", isFastCrossedUnderSlow, ignoreFalseConditions, separator) + + ToString("isMediumOverSlow", isMediumOverSlow, ignoreFalseConditions, separator) + + ToString("isMediumUnderSlow", isMediumUnderSlow, ignoreFalseConditions, separator) + + ToString("isMediumCrossedOverSlow", isMediumCrossedOverSlow, ignoreFalseConditions, separator) + + ToString("isMediumCrossedUnderSlow", isMediumCrossedUnderSlow, ignoreFalseConditions, separator) + "-----------------------" + separator + "XCA: " + separator + "-----------------------" + separator + @@ -2159,6 +2327,7 @@ class XCXCAEAHelper : XCBase XCX121XCTHelper *ctHelper; XCX121XCAHelper *caHelper; XCX121XOCSHelper *ocsHelper; + XCX121X3MAHelper *x3maHelper; // // Constructor ... @@ -2180,6 +2349,7 @@ class XCXCAEAHelper : XCBase ZeroMemory(ctHelper); ZeroMemory(caHelper); ZeroMemory(ocsHelper); + ZeroMemory(x3maHelper); // ZeroMemory(poiDrawer); @@ -2310,6 +2480,17 @@ class XCXCAEAHelper : XCBase mInputs.oscsInputs // ); + // + // X3MA ... + x3maHelper = new XCX121X3MAHelper(); + result = + result && + x3maHelper.Init( + symbol, + period, + mInputs.x3maInputs // + ); + // if (!result) { @@ -2318,6 +2499,7 @@ class XCXCAEAHelper : XCBase ZeroMemory(ctHelper); ZeroMemory(caHelper); ZeroMemory(ocsHelper); + ZeroMemory(x3maHelper); // ZeroMemory(poiDrawer); @@ -2539,6 +2721,7 @@ class XCXCAEAHelper : XCBase ZeroMemory(ctHelper); ZeroMemory(caHelper); ZeroMemory(ocsHelper); + ZeroMemory(x3maHelper); // IndicatorRelease(acHandler); @@ -2564,6 +2747,35 @@ class XCXCAEAHelper : XCBase // // Conditions Readers ... + /** + * Retrieve Conditions ... + * + * @param conditions: Argument 1 + * @param barIndex: int, Specified Bar Index ... + * @param loopback: int, Loopback looking for others ... + * + * @return ( bool ) + */ + bool Get3MAConditions( + X121X3MAConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = false; + + // + result = x3maHelper.GetConditions( + conditions, + barIndex, + loopback // + ); + + // + return result; + } + /** * Retrieve Conditions ... * @@ -2631,6 +2843,7 @@ class XCXCAEAHelper : XCBase // caHelper.Free(); ocsHelper.Free(); + x3maHelper.Free(); } // @@ -2672,6 +2885,7 @@ class XCXCAEAHelper : XCBase // X121XCAConditions xcaConditions; X121XOCSConditions xocsConditions; + X121X3MAConditions x3maConditions; // result = zBar.Init( @@ -2682,7 +2896,7 @@ class XCXCAEAHelper : XCBase result = result && zBar.GetPreviousBar(cBar); - result = + result = result && cBar.GetPreviousBar(pBar); result = @@ -2715,6 +2929,16 @@ class XCXCAEAHelper : XCBase loopback // ); + // + // X3MA ... + result = + result && + Get3MAConditions( + x3maConditions, + barIndex, + loopback // + ); + // // Check Result ... if (!result) @@ -2728,6 +2952,7 @@ class XCXCAEAHelper : XCBase // xcaConditions.Clean(); xocsConditions.Clean(); + x3maConditions.Clean(); // return result; @@ -2745,6 +2970,65 @@ class XCXCAEAHelper : XCBase int cIDX = 1; int pIDX = cIDX + 1; + // + // X3MA ... + + // + // Buffers ... + + // + Copy ( + x3maConditions.fastBuffer, + conditions.fastBuffer // + ); + + // + Copy ( + x3maConditions.mediumBuffer, + conditions.mediumBuffer // + ); + + // + Copy ( + x3maConditions.slowBuffer, + conditions.slowBuffer // + ); + + // + Copy ( + x3maConditions.fastStateBuffer, + conditions.fastStateBuffer // + ); + + // + Copy ( + x3maConditions.mediumStateBuffer, + conditions.mediumStateBuffer // + ); + + // + Copy ( + x3maConditions.slowStateBuffer, + conditions.slowStateBuffer // + ); + + // + // Conditions ... + + // + conditions.isFastOverSlow = x3maConditions.isFastOverSlow; + conditions.isFastUnderSlow = x3maConditions.isFastUnderSlow; + conditions.isFastOverMedium = x3maConditions.isFastOverMedium; + conditions.isMediumOverSlow = x3maConditions.isMediumOverSlow; + conditions.isFastUnderMedium = x3maConditions.isFastUnderMedium; + conditions.isMediumUnderSlow = x3maConditions.isMediumUnderSlow; + conditions.isFastCrossedOverSlow = x3maConditions.isFastCrossedOverSlow; + conditions.isFastCrossedUnderSlow = x3maConditions.isFastCrossedUnderSlow; + conditions.isFastCrossedOverMedium = x3maConditions.isFastCrossedOverMedium; + conditions.isMediumCrossedOverSlow = x3maConditions.isMediumCrossedOverSlow; + conditions.isFastCrossedUnderMedium = x3maConditions.isFastCrossedUnderMedium; + conditions.isMediumCrossedUnderSlow = x3maConditions.isMediumCrossedUnderSlow; + // // XCA ... diff --git a/XCAEA/Libraries/xcaea.signaller.lib.mq5 b/XCAEA/Libraries/xcaea.signaller.lib.mq5 index 6d03334e..c9ff8a81 100644 --- a/XCAEA/Libraries/xcaea.signaller.lib.mq5 +++ b/XCAEA/Libraries/xcaea.signaller.lib.mq5 @@ -665,76 +665,39 @@ bool DetectXCAEAConditions( // // Conditions ... + // + double zPeak = conditions.peakBuffer[zIDX]; + double cPeak = conditions.peakBuffer[cIDX]; + double pPeak = conditions.peakBuffer[pIDX]; + double p2Peak = conditions.peakBuffer[p2IDX]; + + // + double zVale = conditions.valeBuffer[zIDX]; + double cVale = conditions.valeBuffer[cIDX]; + double pVale = conditions.valeBuffer[pIDX]; + double p2Vale = conditions.valeBuffer[p2IDX]; + // // Parsing Pivots ... - + // // Detect Selected Pivot ... - XBoxZone lastOSCPivot; + XBoxZone rejectedPivot; double providedSL = 0; bool hasPivots = HasChild(pivots); if (hasPivots) { // - // Detect Selected Pivots ... - count = ArraySize(pivots); - for (int i = 0; i < count; i++) - { - // - XBoxZone iPivot = pivots[i]; - - // - // Detect Selected Last OSC Pivots ... - bool isOSC = - Contains( - "XCA_RSI", - iPivot.type // - ) || - Contains( - "XCA_CCI", - iPivot.type // - ); - bool canSetOSC = - !isOSC - ? false - : !lastOSCPivot.IsValid() - ? true - : lastOSCPivot.from < iPivot.from; - if (canSetOSC) - { - lastOSCPivot = iPivot; - } - - // - iPivot.Clean(); - - // - } - } - - // - // Detect New OSC Pivot Happens ... - bool hasNewOSC = lastOSCPivot.IsValid() && - cBar.time == lastOSCPivot.to; - if (hasNewOSC) - { - // - XCBoxObject *iObj; - has = helper.poiDrawer.DrawBox( - lastOSCPivot, - iObj // + has = SelectRejectedBox( + rejectedPivot, + pivots, + zBar, + cBar, + pBar, + p2Bar, + true, + true // ); - if (has) - { - // - iObj.BoxWidth(2); - - // - Print("OSC Box Detected ..."); - } - - // - ZeroMemory(iObj); } // @@ -773,6 +736,8 @@ bool DetectXCAEAConditions( // Print("Cond1"); + isCond1Bullish = false; + isCond1Bearish = false; } // @@ -926,9 +891,6 @@ bool DetectXCAEAConditions( conditions.Clean(); } - // - lastOSCPivot.Clean(); - // zBar.Clean(); cBar.Clean(); @@ -937,6 +899,125 @@ bool DetectXCAEAConditions( p3Bar.Clean(); p4Bar.Clean(); pConditions.Clean(); + rejectedPivot.Clean(); + + // + return result; +} + +// +bool SelectRejectedBox( + XBoxZone &box, + XBoxZone &boxes[], + XOHCL &zBar, + XOHCL &cBar, + XOHCL &pBar, + XOHCL &p2Bar, + bool forceBarType = false, + bool forcePressure = false // +) +{ + // + bool result = false; + + // + box.Clean(); + + // + // Validate ... + result = HasChild(boxes) && + zBar.IsValid() && + cBar.IsValid() && + pBar.IsValid() && + p2Bar.IsValid(); + if (!result) + { + return result; + } + + // + int count = ArraySize(boxes); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = boxes[i]; + + // + bool isBullish = iBox.IsBullish(); + bool isBearish = iBox.IsBearish(); + + // + double boundaryPrice = + isBullish + ? iBox.upper + : iBox.lower; + + // + double midPrice = + iBox.lower + + ((iBox.upper - iBox.lower) / 2); + + // + bool isMidBullishRejected = cBar.IsRejected( + midPrice, + X_DIRECTION_BULLISH, + forceBarType, + forcePressure // + ); + + // + bool isBoundaryBullishRejected = cBar.IsRejected( + boundaryPrice, + X_DIRECTION_BULLISH, + forceBarType, + forcePressure // + ); + + // + bool isMidBearishRejected = cBar.IsRejected( + midPrice, + X_DIRECTION_BEARISH, + forceBarType, + forcePressure // + ); + + // + bool isBoundaryBearishRejected = cBar.IsRejected( + boundaryPrice, + X_DIRECTION_BEARISH, + forceBarType, + forcePressure // + ); + + // + bool isBullishRejected = + isBullish && + (isMidBullishRejected || + isBoundaryBullishRejected); + + // + bool isBearishRejected = + isBearish && + (isMidBearishRejected || + isBoundaryBearishRejected); + + // + bool isRejected = + isBullishRejected || + isBearishRejected; + if (isRejected) + { + // + box = iBox; + break; + } + + // + iBox.Clean(); + } + + // + result = box.IsValid(); // return result; diff --git a/XCAEA/Signals/xcaea.signaller.class.mq5 b/XCAEA/Signals/xcaea.signaller.class.mq5 index 41e2004b..863e6e0e 100644 --- a/XCAEA/Signals/xcaea.signaller.class.mq5 +++ b/XCAEA/Signals/xcaea.signaller.class.mq5 @@ -40,9 +40,11 @@ class XCXCAEASignaller : XCBase // // Props ... bool useGuards; + int poiLoopback; XCAEAInputs inputs; XBarTracker barTraker; XCXCAEAHelper *helper; + bool rfOnInvalidPivots; XCXCAEAPOIDrawer *drawer; bool continuesRFTillTarget; XBoxZone unAvailableBoxes[]; @@ -192,6 +194,12 @@ class XCXCAEASignaller : XCBase zIndex // ); + // + if (detector.pivotDetectionLoopbac > 100) + { + detector.pivotDetectionLoopbac = 100; + } + // // Check Market Trend ... hasTrend = detector.MarketTrend(trend); @@ -421,7 +429,7 @@ class XCXCAEASignaller : XCBase else { // - double rfReward = 1; + double rfReward = 2; // double rewardRF = risk * rfReward; @@ -436,6 +444,95 @@ class XCXCAEASignaller : XCBase mConditions.targets // ); } + + // + // Detect Rf on Invalid Pivots ... + if (rfOnInvalidPivots) + { + // + has = detector.HasInvalidPivots(); + if (has) + { + // + XBoxZone targetBox; + double targetBoxPrice = 0; + count = detector.CountInvalidPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = detector.invalidPivots[i]; + + // + bool isValidPivot = + Contains( + "XCA_PEAKSWHRES", + iPivot.type // + ) || + Contains( + "XCA_VALESWLSUP", + iPivot.type // + ) || + Contains( + "XCA_FVG", + iPivot.type // + ); + if (!isValidPivot) + { + // + iPivot.Clean(); + continue; + } + + // + double selectedPrice = + isBullish + ? iPivot.lower - (5 * points) + : iPivot.upper + (5 * points); + + // + double targetBoxSelectedPrice = + isBullish + ? targetBox.lower - (5 * points) + : targetBox.upper + (5 * points); + + // + bool isDirPassed = iPivot.dir = signalBoxDir; + bool isPricePassed = + isBullish + ? entry < selectedPrice + : entry > selectedPrice; + bool canSetTarget = + !targetBox.IsValid() + ? true + : isBullish + ? targetBoxSelectedPrice > selectedPrice + : targetBoxSelectedPrice < selectedPrice; + if (canSetTarget) + { + // + targetBox = iPivot; + targetBoxPrice = targetBoxSelectedPrice; + } + + // + iPivot.Clean(); + } + + // + if (targetBox.IsValid() && + targetBoxPrice > 0) + { + // + Add( + targetBoxPrice, + mConditions.targets // + ); + } + + // + targetBox.Clean(); + } + } } // @@ -658,7 +755,8 @@ class XCXCAEASignaller : XCBase { // useGuards = false; - continuesRFTillTarget = true; + rfOnInvalidPivots = false; + continuesRFTillTarget = false; // barTraker.Init( @@ -688,10 +786,18 @@ class XCXCAEASignaller : XCBase inputs.caInputs.supResSmoothingMode = X_MA_MODE_NONE; // - inputs.caInputs.showKI = true; + inputs.x3maInputs.applyColor = true; + + // + inputs.x3maInputs.showFast = true; + inputs.x3maInputs.showMedium = true; + inputs.x3maInputs.showSlow = true; + + // + inputs.caInputs.showKI = false; inputs.caInputs.showTKI = false; inputs.caInputs.showSar = false; - inputs.caInputs.showVidya = true; + inputs.caInputs.showVidya = false; inputs.caInputs.showTrend = false; inputs.caInputs.showSwings = false; inputs.caInputs.showLongCycle = false; @@ -707,15 +813,19 @@ class XCXCAEASignaller : XCBase // // XOSCS ... - // inputs.oscsInputs.rsiLength = 5; - // inputs.oscsInputs.cciLength = 5; + inputs.oscsInputs.rsiLength = 4; + inputs.oscsInputs.rsiOBLevel = 90; + inputs.oscsInputs.rsiOSLevel = 10; + inputs.oscsInputs.cciLength = 7; + inputs.oscsInputs.cciOBLevel = 130; + inputs.oscsInputs.cciOSLevel = -130; // inputs.oscsInputs.mfiLength = 5; // inputs.oscsInputs.rviLength = 5; // // Oscillators Views ... - inputs.showCCI = false; inputs.showRSI = false; + inputs.showCCI = false; inputs.showMFI = false; inputs.showRVI = false; inputs.showADX = false; @@ -738,23 +848,27 @@ class XCXCAEASignaller : XCBase detector.maxAllowedPivots = 50; detector.pivotVerifications = 5; detector.ticksDividerInPoints = 15; - detector.pivotDetectionLoopbac = 100; + detector.pivotDetectionLoopbac = 200; detector.ticksDetectionPerid = PERIOD_D1; // // Configure Detector ... - detector.detectTickPivots = true; - detector.detectVolumePivots = true; - detector.detectRSIPeakPivots = true; - detector.detectRSIValePivots = true; - detector.detectCCIPeakPivots = true; - detector.detectCCIValePivots = true; - detector.detectFVGBullishPivots = true; - detector.detectFVGBearishPivots = true; + detector.detectTickPivots = false; + detector.detectVolumePivots = false; + detector.detectRSIPeakPivots = false; + detector.detectRSIValePivots = false; + detector.detectCCIPeakPivots = false; + detector.detectCCIValePivots = false; + detector.detectFVGBullishPivots = false; + detector.detectFVGBearishPivots = false; detector.detectValeSupSWLPivots = true; detector.detectPeakResSWHPivots = true; detector.detectPVFVGBullishPivots = true; detector.detectPVFVGBearishPivots = true; + detector.detectRSICrossedOverOSPivots = true; + detector.detectRSICrossedUnderOBPivots = true; + detector.detectCCICrossedOverOSPivots = false; + detector.detectCCICrossedUnderOBPivots = false; // // Initialize and Configure Drawer ... @@ -765,19 +879,23 @@ class XCXCAEASignaller : XCBase // // Configure Drawer ... - drawer.drawTrendLine = true; + drawer.drawTrendLine = false; drawer.drawTickPivots = false; drawer.drawVolumePivots = false; - drawer.drawRSIPeakPivots = true; - drawer.drawRSIValePivots = true; - drawer.drawCCIPeakPivots = true; - drawer.drawCCIValePivots = true; + drawer.drawRSIPeakPivots = false; + drawer.drawRSIValePivots = false; + drawer.drawCCIPeakPivots = false; + drawer.drawCCIValePivots = false; drawer.drawFVGBullishPivots = false; drawer.drawFVGBearishPivots = false; drawer.drawValeSupSWLPivots = true; drawer.drawPeakResSWHPivots = true; drawer.drawPVFVGBullishPivots = true; drawer.drawPVFVGBearishPivots = true; + drawer.drawRSICrossedOverOSPivots = true; + drawer.drawRSICrossedUnderOBPivots = true; + drawer.drawCCICrossedOverOSPivots = true; + drawer.drawCCICrossedUnderOBPivots = true; // // Configure Widths ... @@ -795,6 +913,10 @@ class XCXCAEASignaller : XCBase drawer.trendLineBullishWidth = 4; drawer.pvFVGBullishPivotsWidth = 1; drawer.pvFVGBearishPivotsWidth = 1; + drawer.rsiCrossedOverOSPivotsWidth = 4; + drawer.rsiCrossedUnderOBPivotsWidth = 4; + drawer.cciCrossedOverOSPivotsWidth = 4; + drawer.cciCrossedUnderOBPivotsWidth = 4; // // Configure Colors ... @@ -812,6 +934,10 @@ class XCXCAEASignaller : XCBase drawer.trendLineBullishColor = clrMagenta; drawer.pvFVGBullishPivotsColor = clrLime; drawer.pvFVGBearishPivotsColor = clrRed; + drawer.rsiCrossedOverOSPivotsColor = clrAqua; + drawer.rsiCrossedUnderOBPivotsColor = clrMagenta; + drawer.cciCrossedOverOSPivotsColor = clrAqua; + drawer.cciCrossedUnderOBPivotsColor = clrMagenta; // // Configures Styles ... @@ -829,6 +955,10 @@ class XCXCAEASignaller : XCBase drawer.trendLineBullishWidth = STYLE_SOLID; drawer.pvFVGBullishPivotsStyle = STYLE_DASHDOTDOT; drawer.pvFVGBearishPivotsStyle = STYLE_DASHDOTDOT; + drawer.rsiCrossedOverOSPivotsStyle = STYLE_DASHDOTDOT; + drawer.rsiCrossedUnderOBPivotsStyle = STYLE_DASHDOTDOT; + drawer.cciCrossedOverOSPivotsStyle = STYLE_DASHDOTDOT; + drawer.cciCrossedUnderOBPivotsStyle = STYLE_DASHDOTDOT; // }