From c6e3c78e06d761781a62e1a49c0431302f01a1ca Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 17 Apr 2025 01:46:46 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x-bar.analyser.class.mq5 | 109 ++ Documents/BKP/xaea.tmp.signaller.bkp.mq5 | 431 +++++++ Documents/BKP/xcaea.x-poi.detector.class.mq5 | 481 ++++++++ Helpers/x-saherelm.x121.xca.helper.mq5 | 280 +++++ Indicators/x-saherelm.x121.xca.mq5 | 193 ++- XCAEA/Classes/xcaea.x-poi.detector.class.mq5 | 1099 ++++++++++++++++++ XCAEA/Helpers/xcaea.helper.mq5 | 112 ++ XCAEA/Libraries/xcaea.signaller.lib.mq5 | 167 +++ XCAEA/Signals/xcaea.signaller.class.mq5 | 203 +++- 9 files changed, 3038 insertions(+), 37 deletions(-) create mode 100644 Documents/BKP/xaea.tmp.signaller.bkp.mq5 create mode 100644 Documents/BKP/xcaea.x-poi.detector.class.mq5 create mode 100644 XCAEA/Classes/xcaea.x-poi.detector.class.mq5 diff --git a/Classes/x-saherelm.x-bar.analyser.class.mq5 b/Classes/x-saherelm.x-bar.analyser.class.mq5 index 9369e1b1..b8e5f8ae 100644 --- a/Classes/x-saherelm.x-bar.analyser.class.mq5 +++ b/Classes/x-saherelm.x-bar.analyser.class.mq5 @@ -1753,6 +1753,115 @@ class XCBarAnalyser : public XCBase return result; } + // + // Custom Logics ... + + /** + * Check a Bar is End of an FVG Bar or Not ... + * + * @param bar: XOHCL ... + * @param box: XBoxZone ... + * @param forceType: bool, Force all Bars must be Same as Direction ... + * + * @return ( bool ) + */ + bool IsFVG( + XOHCL &bar, + XBoxZone &box, + bool forceType = false // + ) + { + // + bool result = false; + + // + box.Clean(); + + // + result = bar.IsValid(); + if (!result) + { + return result; + } + + // + XOHCL pBar; + XOHCL p2Bar; + result = bar.GetPreviousBar(pBar); + result = result && + pBar.GetPreviousBar(p2Bar); + if (!result) + { + // + pBar.Clean(); + p2Bar.Clean(); + + // + return result; + } + + // + bool isBullish = p2Bar.high < bar.low; + bool isBearish = p2Bar.low > bar.high; + + // + result = isBullish || + isBearish; + + // + // Apply Force Type ... + if (result) + { + // + if (isBullish) + { + // + result = + bar.IsBullish() && + pBar.IsBullish() && + p2Bar.IsBullish(); + } + else if (isBearish) + { + // + result = + bar.IsBearish() && + pBar.IsBearish() && + p2Bar.IsBearish(); + } + } + + // + if (result) + { + // + box.to = bar.time; + box.from = p2Bar.time; + box.symbol = bar.symbol; + box.period = bar.period; + box.dir = isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + box.upper = isBullish + ? bar.low + : p2Bar.low; + box.lower = isBullish + ? p2Bar.high + : bar.high; + box.type = "XFVG"; + } + + // + pBar.Clean(); + p2Bar.Clean(); + + // + result = box.IsValid(); + + // + return result; + } + // // Candlestick ... diff --git a/Documents/BKP/xaea.tmp.signaller.bkp.mq5 b/Documents/BKP/xaea.tmp.signaller.bkp.mq5 new file mode 100644 index 00000000..daf60bf0 --- /dev/null +++ b/Documents/BKP/xaea.tmp.signaller.bkp.mq5 @@ -0,0 +1,431 @@ + // + bool isPeakPivot = conditions.isPeakIsPivot; + bool isValePivot = conditions.isValeIsPivot; + + // + bool isPivotBullish = isValePivot && + isCBarValidForBullish; + + // + bool isPivotBearish = isPeakPivot && + isCBarValidForBearish; + + // + bool isPivotBullishReversal = + // + isPivotBullish && + conditions.isKIBearish && + conditions.isSarBearish && + conditions.isTrendBearish && + conditions.isLastSupportRejected + // + ; + + // + bool isPivotBearishReversal = + // + isPivotBearish && + conditions.isKIBullish && + conditions.isSarBullish && + conditions.isTrendBullish && + conditions.isLastResistanceRejected + // + ; + + // + bool isPivot = isPivotBullishReversal || + isPivotBearishReversal; + + if (isPivot) + { + Print("Pivot: "); + + // + if (isPivotBullish) + { + Print("Bullish: ", isPivotBullish); + } + + // + if (isPivotBearish) + { + Print("Bearish: ", isPivotBearish); + } + + // + Print("Bullish Score: ", bullishScore); + Print("Bearish Score: ", bearishScore); + } + + // + bool isOverFib2 = pBar.low > conditions.fiboLevel2Buffer[cIDX]; + bool isUnderFib2 = pBar.high < conditions.fiboLevel2Buffer[cIDX]; + + // + bool isTrendBasedBullish = + isUnderFib2 && + isCBarValidForBullish && + conditions.isTrendRejectUp; + + // + bool isTrendBasedBearish = + isOverFib2 && + isCBarValidForBearish && + conditions.isTrendRejectDown; + + // + bool isTrend = + isTrendBasedBullish || + isTrendBasedBearish; + + // + if (isTrend) + { + Print("Trend Based ..."); + } + + // + bool isBarBreakedKITrendBullish = + cBar.IsBullish() && + isCBarBullishMomentum && + cBar.open < conditions.kiBuffer[cIDX] && + cBar.close > conditions.kiBuffer[cIDX] && + cBar.open < conditions.trendBuffer[cIDX] && + cBar.close > conditions.trendBuffer[cIDX]; + + // + bool isBarBreakedKITrendBearish = + cBar.IsBearish() && + isCBarBearishMomentum && + cBar.open > conditions.kiBuffer[cIDX] && + cBar.close < conditions.kiBuffer[cIDX] && + cBar.open > conditions.trendBuffer[cIDX] && + cBar.close > conditions.trendBuffer[cIDX]; + + // + bool isKITrendBreaked = + isBarBreakedKITrendBullish || + isBarBreakedKITrendBearish; + + // + if (isKITrendBreaked) + { + Print("KI Trend Breaked ..."); + } + + + ///////////////////////////////////////////////////////////// + + + // while (index <= end) + // { + // // + // XCAEAConditions iConditions; + // bool has = helper.GetConditions( + // iConditions, + // index, + // 5 // + // ); + // if (!has) + // { + // // + // iConditions.Clean(); + // continue; + // } + + // // + // zIDX = 0; + // cIDX = zIDX + 1; + // pIDX = cIDX + 1; + // p2IDX = pIDX + 1; + + // // + // XOHCL cBar; + // has = cBar.Init( + // iConditions.symbol, + // iConditions.period, + // index + 1 // + // ); + // if (!has) + // { + // // + // cBar.Clean(); + // iConditions.Clean(); + // continue; + // } + + // // + // // Read Reuired Data ... + + // // + // // KI ... + + // // + // double cKI = iConditions.kiBuffer[cIDX]; + // double pKI = iConditions.kiBuffer[pIDX]; + // double p2KI = iConditions.kiBuffer[p2IDX]; + + // // + // double cKIState = iConditions.kiStateBuffer[cIDX]; + // double pKIState = iConditions.kiStateBuffer[pIDX]; + // double p2KIState = iConditions.kiStateBuffer[p2IDX]; + + // // + // // TKI ... + + // // + // double cTKI = iConditions.tkiBuffer[cIDX]; + // double pTKI = iConditions.tkiBuffer[pIDX]; + // double p2TKI = iConditions.tkiBuffer[p2IDX]; + + // // + // double cTKIState = iConditions.tkiStateBuffer[cIDX]; + // double pTKIState = iConditions.tkiStateBuffer[pIDX]; + // double p2TKIState = iConditions.tkiStateBuffer[p2IDX]; + + // // + // // TREND ... + + // // + // double cTrend = iConditions.trendBuffer[cIDX]; + // double pTrend = iConditions.trendBuffer[pIDX]; + // double p2Trend = iConditions.trendBuffer[p2IDX]; + + // // + // double ctrendState = iConditions.trendStateBuffer[cIDX]; + // double ptrendState = iConditions.trendStateBuffer[pIDX]; + // double p2trendState = iConditions.trendStateBuffer[p2IDX]; + + // // + // // SWING Low ... + + // // + // double cSWL = iConditions.swingLowBuffer[cIDX]; + // double pSWL = iConditions.swingLowBuffer[pIDX]; + // double p2SWL = iConditions.swingLowBuffer[p2IDX]; + + // // + // // SWING High ... + + // // + // double cSWH = iConditions.swingHighBuffer[cIDX]; + // double pSWH = iConditions.swingHighBuffer[pIDX]; + // double p2SWH = iConditions.swingHighBuffer[p2IDX]; + + // // + // // PEAK ... + + // // + // double cPeak = iConditions.peakBuffer[cIDX]; + // double pPeak = iConditions.peakBuffer[pIDX]; + // double p2Peak = iConditions.peakBuffer[p2IDX]; + + // // + // // VALE ... + + // // + // double cVale = iConditions.valeBuffer[cIDX]; + // double pVale = iConditions.valeBuffer[pIDX]; + // double p2Vale = iConditions.valeBuffer[p2IDX]; + + // // + // // Required Condirions ... + + // // + // bool isTKITRNDBullish = + // iConditions.isKIBullish && + // iConditions.isTKIBullish && + // iConditions.isTrendBullish; + + // // + // bool isTKITRNDBearish = + // iConditions.isKIBearish && + // iConditions.isTKIBearish && + // iConditions.isTrendBearish; + + // // + // XBoxZone iBox; + + // // + // // Check FVG ... + // bool isFVG = barAnalyser.IsFVG( + // cBar, + // iBox, + // false // Force Same Bars ... + // ); + // if (isFVG) + // { + // // + // // Validate FVG ... + // bool isFVGBullish = iBox.IsBullish(); + + // // // + // // isFVG = + // // isFVGBullish + // // ? isTKITRNDBullish + // // : isTKITRNDBearish; + + // // + // if (isFVG) + // { + // // + // XCBoxObject *iObj; + // has = drawer.DrawBox( + // iBox, + // iObj // + // ); + // if (has) + // { + // iObj.BoxWidth(2); + // } + // } + // } + + // // + // index++; + // cBar.Clean(); + // iConditions.Clean(); + // } + + //////////////////////////////////////////////////////////////////// + + // + XBoxZone tmpFVGBoxes[]; + + // + int index = barIndex; + int end = index + loopback; + while (index <= end) + { + // + XOHCL cBar; + bool has = cBar.Init( + helper.GetSymbol(), + helper.GetPeriod(), + index + 1 // + ); + if (!has) + { + // + cBar.Clean(); + continue; + } + + // + // Check FVG ... + XBoxZone iBox; + bool isFVG = barAnalyser.IsFVG( + cBar, + iBox, + false // Force Same Bars ... + ); + if (isFVG) + { + // + AddBox( + iBox, + tmpFVGBoxes // + ); + } + + // + index++; + cBar.Clean(); + } + + // + int idx = -1; + bool has = false; + if (HasChild(tmpFVGBoxes)) + { + // + while (HasChild(tmpFVGBoxes)) + { + // + idx = GetYoungest(tmpFVGBoxes); + has = IsValidIndex(idx); + if (!has) + { + break; + } + + // + XBoxZone iBox = tmpFVGBoxes[idx]; + ArrayRemove( + tmpFVGBoxes, + idx, + 1 // + ); + + // + // Here We Have to Validate FVG ... + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + iBox, + iObj // + ); + + // + } + } + + +////////////////////////////////////////////////////////////////////////////////// + +has = HasPeakPivots(); +if (has) +{ + // + count = CountPeakPivots(); + for (int i = 0; i < count; i++) + { + // + XCAPivot iPivot = peakPivots[i]; + + // + int toIDX = iPivot.ToIndex(); + int fromIDX = iPivot.FromIndex(); + has = IsValidIndex(toIDX) && + IsValidIndex(fromIDX); + if (!has) + { + // + iPivot.Clean(); + continue; + } + + // + for (int j = toIDX; j <= fromIDX; j++) { + // + XCAEAConditions jConditions; + has = helper.GetConditions( + jConditions, + j, + 5 // + ); + if (!has) { + // + jConditions.Clean(); + continue; + } + + // + datetime jTime = GetBarTime( + jConditions.symbol, + jConditions.period, + j // + ); + + // + + } + + // + iPivot.Clean(); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + diff --git a/Documents/BKP/xcaea.x-poi.detector.class.mq5 b/Documents/BKP/xcaea.x-poi.detector.class.mq5 new file mode 100644 index 00000000..73fab8fc --- /dev/null +++ b/Documents/BKP/xcaea.x-poi.detector.class.mq5 @@ -0,0 +1,481 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XCXCAEAPOIDetector ... +// Description: Class for XCAEA POI Detector ... +// +// +// 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 Class for XCAEA POI Detector" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" +#include "../Helpers/xcaea.helper.mq5" + +// +// Definitions ... + +// enum ENUM_X_PIVOT_KINDS +// { +// X_PIVOT_SWL, // SWL +// X_PIVOT_SWH, // SWH +// }; + +// string ToString(ENUM_X_PIVOT_KINDS value) +// { +// // +// string result = NULL; + +// // +// result = EnumToString(value); + +// // +// return result; +// } + +// struct XSamePivot +// { +// // +// // Props ... +// datetime to; +// string type; +// double value; +// datetime from; +// string symbol; +// ENUM_X_DIRECTION dir; +// ENUM_TIMEFRAMES period; + +// // +// // Constructor ... +// XSamePivot() +// { +// Clean(); +// } + +// // +// // Tools ... + +// /** +// * Cleanup Model ... +// */ +// void Clean() +// { +// // +// to = NULL; +// value = 0; +// from = NULL; +// type = NULL; +// symbol = NULL; +// period = NULL; +// dir = X_DIRECTION_NONE; +// } + +// /** +// * Validate Model ... +// * +// * @return ( bool ) +// */ +// bool IsValid() +// { +// // +// bool result = false; + +// // +// result = +// // +// from < to && +// value != 0 && +// IsValid(to) && +// IsValid(from) && +// IsValid(symbol) && +// IsValid(period) && +// HasDirection(dir) +// // +// ; + +// // +// return result; +// } + +// /** +// * Check a Model is Same As Other ... +// * +// * @return ( bool ) +// */ +// bool IsSameAs(XSamePivot &item) +// { +// // +// bool result = false; + +// // +// result = IsValid() && +// item.IsValid(); +// if (!result) +// { +// return result; +// } + +// // +// result = +// // +// to == item.to && +// dir == item.dir && +// from == item.from && +// type == item.type && +// value == item.value && +// symbol == item.symbol && +// period == item.period +// // +// ; + +// // +// return result; +// } + +// // +// }; + +// +// Implementations ... +class XCXCAEAPOIDetector : public XCBase +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCXCAEAPOIDetector( + XCXCAEAHelper *_helper // + ) + { + // + helper = _helper; + barAnalyser = new XCBarAnalyser(); + + // + Default(); + } + + // + // De Constructors ... + ~XCXCAEAPOIDetector() + { + // + Clean(tkitrndPivots); + + // + ZeroMemory(helper); + ZeroMemory(barAnalyser); + } + + // + // Properties ... + + int TITrndPivotVerification() + { + return tkitrndPivotVerification; + } + + void TKITrndPivotVerification(int value) + { + // + value = NormalizeInt(value, 0); + + // + tkitrndPivotVerification = value; + } + + // + // Tools ... + + virtual void Default() + { + // + TKITrndPivotVerification(10); + } + + // + void Update( + int barIndex = 0, + int loopback = 100 // + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + loopback = NormalizeInt(loopback, 100); + + // + int index = barIndex; + int end = index + loopback; + while (index <= end) + { + // + XCAEAConditions iConditions; + bool has = helper.GetConditions( + iConditions, + index, + loopback // + ); + + // + // Detecting Same Pivots ... + // HandleTKITRNDPivotDetection(iConditions, index); + + // + index++; + iConditions.Clean(); + } + + // + } + + // + // POI Handlers ... + + // bool HasTKITRNDPivots() + // { + // return HasChild(tkitrndPivots); + // } + + // int CountTKITRNDPivots() + // { + // return ArraySize(tkitrndPivots); + // } + + // int FillTKITRNDPivots(XSamePivot &pivots[]) + // { + // // + // int result = 0; + + // // + // if (!HasTKITRNDPivots()) + // { + // return result; + // } + + // // + // Copy( + // tkitrndPivots, + // pivots // + // ); + + // // + // result = ArraySize(pivots); + + // // + // return result; + // } + + // bool IsTKITRNDPivotExists( + // int &index, + // XSamePivot &pivot // + // ) + // { + // // + // bool result = false; + + // // + // index = -1; + + // // + // result = pivot.IsValid() && + // HasTKITRNDPivots(); + // if (!result) + // { + // return result; + // } + + // // + // int count = CountTKITRNDPivots(); + // for (int i = 0; i < count; i++) + // { + // // + // XSamePivot iPivot = tkitrndPivots[i]; + + // // + // bool isSame = + // pivot.IsSameAs(iPivot); + // if (isSame) + // { + // // + // index = i; + // iPivot.Clean(); + + // // + // break; + // } + + // // + // iPivot.Clean(); + // } + + // // + // result = IsValidIndex(index); + + // // + // return result; + // } + + // + // Protected ... + protected: + // + // Props ... + + // // + // void HandleTKITRNDPivotDetection( + // XCAEAConditions &conditions, + // int barIndex = 0 // + // ) + // { + // // + // if (barIndex < 0) + // { + // barIndex = 0; + // } + + // // + // if (tkitrndPivotVerification <= 0) + // { + // return; + // } + + // // + // datetime barTime = GetBarTime( + // conditions.symbol, + // conditions.period, + // barIndex + 1 // + // ); + + // // + // int index = 2; + // datetime cTime = barTime; + // int end = ArraySize(conditions.swingLowBuffer); + + // // + // int swingLowVerified = 0; + // datetime swingLowFinishAt = NULL; + // datetime swingLowStartAt = barTime; + // double swingLow = conditions.swingLowBuffer[1]; + // bool canLookupSwingLow = true; + + // // + // bool isVerified = false; + // bool canContinue = true; + // while (index < end && canContinue) + // { + // // + // cTime += PeriodSeconds(conditions.period); + + // // + // // Swing Low ... + // double iSWL = conditions.swingLowBuffer[index]; + // if (iSWL == swingLow) + // { + // swingLowVerified++; + // } + // else if (iSWL != swingLow) + // { + // // + // isVerified = swingLowVerified >= tkitrndPivotVerification; + // if (isVerified) + // { + // // + // swingLowFinishAt = cTime; + + // // + // XSamePivot iPivot; + + // // + // iPivot.value = swingLow; + // iPivot.to = swingLowFinishAt; + // iPivot.from = swingLowStartAt; + // iPivot.dir = X_DIRECTION_BULLISH; + // iPivot.symbol = conditions.symbol; + // iPivot.period = conditions.period; + // iPivot.type = ToString(X_PIVOT_SWL); + + // // + // if (iPivot.IsValid()) + // { + // AddOrUpdateTKITRNDPivot(iPivot); + // } + // } + + // // + // // Reset ... + // swingLow = iSWL; + // swingLowVerified = 0; + // swingLowFinishAt = NULL; + // swingLowStartAt = cTime; + // canLookupSwingLow = true; + // } + + // // + // index++; + + // // + // canContinue = canLookupSwingLow; + // } + // } + + // // + // void AddOrUpdateTKITRNDPivot(XSamePivot &pivot) + // { + // // + // int idx = -1; + // bool isExists = IsTKITRNDPivotExists( + // idx, + // pivot // + // ); + // if (isExists) + // { + // return; + // } + + // // + // AddRef( + // pivot, + // tkitrndPivots // + // ); + // } + + // + // Prrivate ... + private: + // + // Props ... + int tkitrndPivotVerification; // KI/TKI/Trend Verification ... + + // + XCXCAEAHelper *helper; + XCBarAnalyser *barAnalyser; + + // + // Same Pivots ... + // XSamePivot tkitrndPivots[]; // TKITrend is Bullish/Bearish and Swing Low/High Under / Over Min / Max ... + + // +}; + +// \ 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 7933fb1b..b33d5114 100644 --- a/Helpers/x-saherelm.x121.xca.helper.mq5 +++ b/Helpers/x-saherelm.x121.xca.helper.mq5 @@ -56,6 +56,8 @@ enum ENUM_X121_XCA_BUFFERS X121_XCA_KI_STATE_LINE = 25, X121_XCA_SWING_LOW_LINE = 22, X121_XCA_SWING_HIGH_LINE = 23, + X121_XCA_TKI_LINE = 24, + X121_XCA_TKI_STATE_LINE = 30, }; // @@ -127,6 +129,7 @@ struct X121XCAInputs // bool showSar; // Show Sar bool showKI; // Show KI + bool showTKI; // Show TKI bool showTrend; // Show Trend bool showSwings; // Show Swings bool showFiboLevel1; // Show Fibo Level 1 @@ -223,6 +226,7 @@ struct X121XCAInputs // showSar = true; // Show Sar showKI = true; // Show KI + showTKI = true; // Show TKI showTrend = true; // Show Trend showSwings = true; // Show Swings showFiboLevel1 = true; // Show Fibo Level 1 @@ -307,6 +311,7 @@ struct X121XCAInputs // showSar = true; // Show Sar showKI = true; // Show KI + showTKI = true; // Show TKI showTrend = true; // Show Trend showSwings = true; // Show Swings showFiboLevel1 = true; // Show Fibo Level 1 @@ -385,6 +390,7 @@ struct X121XCAConditions // // Buffers ... double kiBuffer[]; + double tkiBuffer[]; double sHHBuffer[]; double sLLBuffer[]; double mHHBuffer[]; @@ -399,6 +405,7 @@ struct X121XCAConditions double trendBuffer[]; double kiStateBuffer[]; double supportBuffer[]; + double tkiStateBuffer[]; double swingLowBuffer[]; double swingHighBuffer[]; double resistanceBuffer[]; @@ -427,6 +434,21 @@ struct X121XCAConditions bool isKISwitchedToBullish; bool isKISwitchedToBearish; + // + // TKI ... + + // + bool isTKIRejectUp; + bool isTKIRejectDown; + + // + bool isTKIBullish; + bool isTKIBearish; + + // + bool isTKISwitchedToBullish; + bool isTKISwitchedToBearish; + // // SAR ... @@ -562,6 +584,7 @@ struct X121XCAConditions // Clean(kiBuffer); + Clean(tkiBuffer); Clean(sHHBuffer); Clean(sLLBuffer); Clean(mHHBuffer); @@ -576,6 +599,7 @@ struct X121XCAConditions Clean(trendBuffer); Clean(kiStateBuffer); Clean(supportBuffer); + Clean(tkiStateBuffer); Clean(swingLowBuffer); Clean(swingHighBuffer); Clean(resistanceBuffer); @@ -588,6 +612,7 @@ struct X121XCAConditions // ArraySetAsSeries(kiBuffer, true); + ArraySetAsSeries(tkiBuffer, true); ArraySetAsSeries(sHHBuffer, true); ArraySetAsSeries(sLLBuffer, true); ArraySetAsSeries(mHHBuffer, true); @@ -602,6 +627,7 @@ struct X121XCAConditions ArraySetAsSeries(trendBuffer, true); ArraySetAsSeries(kiStateBuffer, true); ArraySetAsSeries(supportBuffer, true); + ArraySetAsSeries(tkiStateBuffer, true); ArraySetAsSeries(swingLowBuffer, true); ArraySetAsSeries(swingHighBuffer, true); ArraySetAsSeries(resistanceBuffer, true); @@ -630,6 +656,21 @@ struct X121XCAConditions isKISwitchedToBullish = false; isKISwitchedToBearish = false; + // + // TKI ... + + // + isTKIRejectUp = false; + isTKIRejectDown = false; + + // + isTKIBullish = false; + isTKIBearish = false; + + // + isTKISwitchedToBullish = false; + isTKISwitchedToBearish = false; + // // SAR ... @@ -794,6 +835,37 @@ struct X121XCAConditions bearishScore += minScore; } + // + // TKI ... + + // + if (isTKIBullish) + { + bullishScore += minScore; + } + if (isTKIRejectUp) + { + bullishScore += minScore; + } + if (isTKISwitchedToBullish) + { + bullishScore += minScore; + } + + // + if (isTKIBearish) + { + bearishScore += minScore; + } + if (isTKIRejectDown) + { + bearishScore += minScore; + } + if (isTKISwitchedToBearish) + { + bearishScore += minScore; + } + // // SAR ... @@ -1058,6 +1130,12 @@ struct X121XCAConditions ToString("isKIBearish", isKIBearish, ignoreFalseConditions, separator) + ToString("isKISwitchedToBullish", isKISwitchedToBullish, ignoreFalseConditions, separator) + ToString("isKISwitchedToBearish", isKISwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isTKIRejectUp", isTKIRejectUp, ignoreFalseConditions, separator) + + ToString("isTKIRejectDown", isTKIRejectDown, ignoreFalseConditions, separator) + + ToString("isTKIBullish", isTKIBullish, ignoreFalseConditions, separator) + + ToString("isTKIBearish", isTKIBearish, ignoreFalseConditions, separator) + + ToString("isTKISwitchedToBullish", isTKISwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isTKISwitchedToBearish", isTKISwitchedToBearish, ignoreFalseConditions, separator) + ToString("isSarBullish", isSarBullish, ignoreFalseConditions, separator) + ToString("isSarBearish", isSarBearish, ignoreFalseConditions, separator) + ToString("isSarSwitchedToBullish", isSarSwitchedToBullish, ignoreFalseConditions, separator) + @@ -1168,6 +1246,7 @@ class XCX121XCAHelper : public XCBaseHelper // Clean(kiBuffer); + Clean(tkiBuffer); Clean(sHHBuffer); Clean(sLLBuffer); Clean(mHHBuffer); @@ -1182,6 +1261,7 @@ class XCX121XCAHelper : public XCBaseHelper Clean(trendBuffer); Clean(kiStateBuffer); Clean(supportBuffer); + Clean(tkiStateBuffer); Clean(swingLowBuffer); Clean(swingHighBuffer); Clean(resistanceBuffer); @@ -1217,6 +1297,7 @@ class XCX121XCAHelper : public XCBaseHelper // ArraySetAsSeries(kiBuffer, true); + ArraySetAsSeries(tkiBuffer, true); ArraySetAsSeries(sHHBuffer, true); ArraySetAsSeries(sLLBuffer, true); ArraySetAsSeries(mHHBuffer, true); @@ -1231,6 +1312,7 @@ class XCX121XCAHelper : public XCBaseHelper ArraySetAsSeries(trendBuffer, true); ArraySetAsSeries(kiStateBuffer, true); ArraySetAsSeries(supportBuffer, true); + ArraySetAsSeries(tkiStateBuffer, true); ArraySetAsSeries(swingLowBuffer, true); ArraySetAsSeries(swingHighBuffer, true); ArraySetAsSeries(resistanceBuffer, true); @@ -1283,6 +1365,7 @@ class XCX121XCAHelper : public XCBaseHelper mInputs.startCalculationForLastBars, mInputs.showSar, mInputs.showKI, + mInputs.showTKI, mInputs.showTrend, mInputs.showSwings, mInputs.showFiboLevel1, @@ -1443,6 +1526,110 @@ class XCX121XCAHelper : public XCBaseHelper ); } + // + // TKI ... + + // + double GetTKI( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(tkiBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return tkiBuffer[barIndex]; + } + + // + int CopyTKI( + 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, + tkiBuffer, + buffer, + forceClean + // + ); + } + + // + // TKI STATE ... + + // + double GetTKIState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(tkiStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return tkiStateBuffer[barIndex]; + } + + // + int CopyTKIState( + 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, + tkiStateBuffer, + buffer, + forceClean + // + ); + } + // // SHORT ... @@ -2688,6 +2875,20 @@ class XCX121XCAHelper : public XCBaseHelper conditions.kiStateBuffer // ); + // + CopyTKI( + zIndex, + loopback, + conditions.tkiBuffer // + ); + + // + CopyTKIState( + zIndex, + loopback, + conditions.tkiStateBuffer // + ); + // CopySHH( zIndex, @@ -2897,6 +3098,47 @@ class XCX121XCAHelper : public XCBaseHelper bool isKISwitchedToBearish = isKIBearish && !isKIBearishPrev; + // + // TKI ... + + // + double cTKI = conditions.tkiBuffer[cIDX]; + double pTKI = conditions.tkiBuffer[pIDX]; + double p2TKI = conditions.tkiBuffer[p2IDX]; + + // + double cTKIState = conditions.tkiStateBuffer[cIDX]; + double pTKIState = conditions.tkiStateBuffer[pIDX]; + double p2TKIState = conditions.tkiStateBuffer[p2IDX]; + + // + bool isTKIRejectUp = cBar.IsRejected( + cTKI, + X_DIRECTION_BULLISH, + false, + false // + ); + bool isTKIRejectDown = cBar.IsRejected( + cTKI, + X_DIRECTION_BEARISH, + false, + false // + ); + + // + bool isTKIBullish = cTKIState > 0; + bool isTKIBullishPrev = pTKIState > 0; + + // + bool isTKIBearish = cTKIState < 0; + bool isTKIBearishPrev = pTKIState < 0; + + // + bool isTKISwitchedToBullish = isTKIBullish && + !isTKIBullishPrev; + bool isTKISwitchedToBearish = isTKIBearish && + !isTKIBearishPrev; + // // SAR ... @@ -3107,8 +3349,11 @@ class XCX121XCAHelper : public XCBaseHelper conditions.isKIBullish = isKIBullish; conditions.isKIBearish = isKIBearish; conditions.isKIRejectUp = isKIRejectUp; + conditions.isTKIBullish = isTKIBullish; + conditions.isTKIBearish = isTKIBearish; conditions.isSarBullish = isSarBullish; conditions.isSarBearish = isSarBearish; + conditions.isTKIRejectUp = isTKIRejectUp; conditions.isPeakIsPivot = isPeakIsPivot; conditions.isValeIsPivot = isValeIsPivot; conditions.isKIRejectDown = isKIRejectDown; @@ -3118,6 +3363,7 @@ class XCX121XCAHelper : public XCBaseHelper conditions.isValeOverLast = isValeOverLast; conditions.isTrendBullish = isTrendBullish; conditions.isTrendBearish = isTrendBearish; + conditions.isTKIRejectDown = isTKIRejectDown; conditions.isPeakUnderLast = isPeakUnderLast; conditions.isValeUnderLast = isValeUnderLast; conditions.isTrendRejectUp = isTrendRejectUp; @@ -3142,6 +3388,8 @@ class XCX121XCAHelper : public XCBaseHelper conditions.isKISwitchedToBearish = isKISwitchedToBearish; conditions.isLastSwingLowBreaked = isLastSwingLowBreaked; conditions.isSwingHighSameAsPeak = isSwingHighSameAsPeak; + conditions.isTKISwitchedToBullish = isTKISwitchedToBullish; + conditions.isTKISwitchedToBearish = isTKISwitchedToBearish; conditions.isLastSwingLowRejected = isLastSwingLowRejected; conditions.isSarSwitchedToBullish = isSarSwitchedToBullish; conditions.isSarSwitchedToBearish = isSarSwitchedToBearish; @@ -3180,6 +3428,7 @@ class XCX121XCAHelper : public XCBaseHelper // // Buffers ... double kiBuffer[]; + double tkiBuffer[]; double sHHBuffer[]; double sLLBuffer[]; double mHHBuffer[]; @@ -3194,6 +3443,7 @@ class XCX121XCAHelper : public XCBaseHelper double trendBuffer[]; double kiStateBuffer[]; double supportBuffer[]; + double tkiStateBuffer[]; double swingLowBuffer[]; double swingHighBuffer[]; double resistanceBuffer[]; @@ -3226,6 +3476,15 @@ class XCX121XCAHelper : public XCBaseHelper kiBuffer // ); + // + CopyBuffer( + mHandler, + X121_XCA_TKI_LINE, + barIndex, + maxRequiredBars, + tkiBuffer // + ); + // CopyBuffer( mHandler, @@ -3343,6 +3602,15 @@ class XCX121XCAHelper : public XCBaseHelper kiStateBuffer // ); + // + CopyBuffer( + mHandler, + X121_XCA_TKI_STATE_LINE, + barIndex, + maxRequiredBars, + tkiStateBuffer // + ); + // CopyBuffer( mHandler, @@ -3445,6 +3713,12 @@ class XCX121XCAHelper : public XCBaseHelper maxAllowed // ); + // + CleanupArray( + tkiBuffer, + maxAllowed // + ); + // CleanupArray( sHHBuffer, @@ -3523,6 +3797,12 @@ class XCX121XCAHelper : public XCBaseHelper maxAllowed // ); + // + CleanupArray( + tkiStateBuffer, + maxAllowed // + ); + // CleanupArray( supportBuffer, diff --git a/Indicators/x-saherelm.x121.xca.mq5 b/Indicators/x-saherelm.x121.xca.mq5 index 21bea53b..e068635f 100644 --- a/Indicators/x-saherelm.x121.xca.mq5 +++ b/Indicators/x-saherelm.x121.xca.mq5 @@ -82,7 +82,7 @@ input int swingLength = 5; // Length // input group "Support and Resistance"; -input int supResSmoothingLength = 7; // Smoothing Length +input int supResSmoothingLength = 7; // Smoothing Length input ENUM_X_MA_METHOD supResSmoothingMode = X_MA_MODE_SMA; // Smoothing Method // @@ -95,6 +95,7 @@ input int startCalculationForLastBars = 1000; // Calculate Last n Bars // input bool showSar = true; // Show Sar input bool showKI = true; // Show KI +input bool showTKI = true; // Show KI Trend input bool showTrend = true; // Show Trend input bool showSwings = true; // Show Swings input bool showFiboLevel1 = true; // Show Fibo Level 1 @@ -124,6 +125,11 @@ input int swingHighArrowCode = 226; // Swing High Arrow Code #define bearishColorIDX 2 #define neuturalColorIDX 3 +// +#define bullishState 1 +#define neuturalState 0 +#define bearishState -1 + // #define emptyValue 0.0 @@ -131,8 +137,8 @@ input int swingHighArrowCode = 226; // Swing High Arrow Code #property indicator_chart_window // -#property indicator_buffers 28 -#property indicator_plots 22 +#property indicator_buffers 31 +#property indicator_plots 23 // // Plot Buffers ... @@ -440,10 +446,29 @@ double swingHighBuffer[]; #property indicator_color22 clrRed #property indicator_width22 1 +// +// TKI ... + +// +#define tkiBufferIndex 24 +#define tkiBufferPlotIndex 22 +double tkiBuffer[]; + +// +#define tkiColorBufferIndex 25 +double tkiColorBuffer[]; + +// +#property indicator_label23 "TKI" +#property indicator_type23 DRAW_COLOR_LINE +#property indicator_color23 CLR_NONE, clrGreen, clrRed, clrGray +#property indicator_style23 STYLE_DASHDOTDOT +#property indicator_width23 2 + // // Data Buffers ... -#define mLastBufferIndex 23 +#define mLastBufferIndex 25 // #define trendStateBufferIndex mLastBufferIndex + 1 @@ -461,6 +486,10 @@ double supBuffer[]; #define resBufferIndex mLastBufferIndex + 4 double resBuffer[]; +// +#define tkiStateBufferIndex mLastBufferIndex + 5 +double tkiStateBuffer[]; + // // Variables, Properties and etc ... @@ -477,6 +506,7 @@ int sarHandler = INVALID_HANDLE; // // TREND Handler ... +int tkiHandler = INVALID_HANDLE; int trendHandler = INVALID_HANDLE; // @@ -539,6 +569,22 @@ int OnInit() return INIT_FAILED; } + // + // TKI ... + tkiHandler = iMA( + _Symbol, + _Period, + kiLength, + 0, + MODE_SMA, + PRICE_MEDIAN // + ); + isInited = tkiHandler != INVALID_HANDLE; + if (!isInited) + { + return INIT_FAILED; + } + // // TREND ... trendHandler = iMA( @@ -646,6 +692,10 @@ int OnCalculate( // SAR ... int sarCalculatedBars = BarsCalculated(sarHandler); + // + // TKI ... + int tkiCalculatedBars = BarsCalculated(tkiHandler); + // // TREND ... int trendCalculatedBars = BarsCalculated(trendHandler); @@ -656,6 +706,9 @@ int OnCalculate( // SAR ... sarCalculatedBars >= maxLength && // + // TKI ... + tkiCalculatedBars >= maxLength && + // // TREND ... trendCalculatedBars >= maxLength // @@ -677,6 +730,10 @@ int OnCalculate( // SAR ... int copiedSars = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); + // + // TKI ... + int copiedTKIs = CopyBuffer(tkiHandler, 0, 0, limit, tkiBuffer); + // // TREND ... int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit + 1, trendBuffer); @@ -688,6 +745,9 @@ int OnCalculate( // SAR ... copiedSars >= limit && // + // TKI ... + copiedTKIs >= limit && + // // TREND ... copiedTrends >= limit // @@ -1130,6 +1190,27 @@ void DefineBuffers() ArraySetAsSeries(kiColorBuffer, true); SetIndexBuffer(kiColorBufferIndex, kiColorBuffer, INDICATOR_COLOR_INDEX); + // + // TKI ... + + // + ENUM_DRAW_TYPE tkiDrawType = showTKI ? DRAW_COLOR_LINE : DRAW_NONE; + + // + ArraySetAsSeries(tkiBuffer, true); + SetIndexBuffer(tkiBufferIndex, tkiBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(tkiBufferPlotIndex, PLOT_SHOW_DATA, showKI); + // PlotIndexSetInteger(tkiBufferPlotIndex, PLOT_DRAW_TYPE, kiDrawType); + + // + PlotIndexSetDouble(tkiBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(tkiColorBuffer, true); + SetIndexBuffer(tkiColorBufferIndex, tkiColorBuffer, INDICATOR_COLOR_INDEX); + // // SWINGS ... @@ -1185,6 +1266,10 @@ void DefineBuffers() ArraySetAsSeries(resBuffer, true); SetIndexBuffer(resBufferIndex, resBuffer, INDICATOR_CALCULATIONS); + // + ArraySetAsSeries(tkiStateBuffer, true); + SetIndexBuffer(tkiStateBufferIndex, tkiStateBuffer, INDICATOR_CALCULATIONS); + // } @@ -1456,11 +1541,19 @@ void FillBuffersZero(int barIndex) // TREND ... trendBuffer[barIndex] = emptyValue; trendColorBuffer[barIndex] = hideColorIDX; + trendStateBuffer[barIndex] = hideColorIDX; // // KI ... kiBuffer[barIndex] = emptyValue; kiColorBuffer[barIndex] = hideColorIDX; + kiStateBuffer[barIndex] = hideColorIDX; + + // + // TKI ... + tkiBuffer[barIndex] = emptyValue; + tkiColorBuffer[barIndex] = hideColorIDX; + tkiStateBuffer[barIndex] = hideColorIDX; // // SWINGS ... @@ -1786,19 +1879,25 @@ void CalculateValues( double iTrend = trendBuffer[bar_index]; // - double iTrendState = - iClose > iTrend - ? bullishColorIDX - : iClose < iTrend - ? bearishColorIDX - : neuturalColorIDX; + double iTrendState = neuturalState; + double iTrendColor = neuturalColorIDX; + if (iClose > iTrend) + { + // + iTrendState = bullishState; + iTrendColor = !showTrend + ? hideColorIDX + : bullishColorIDX; + } + else if (iClose < iTrend) + { + // + iTrendState = bearishState; + iTrendColor = !showTrend + ? hideColorIDX + : bearishColorIDX; + } trendStateBuffer[bar_index] = iTrendState; - - // - double iTrendColor = - showTrend - ? iTrendState - : hideColorIDX; trendColorBuffer[bar_index] = iTrendColor; // @@ -1814,19 +1913,27 @@ void CalculateValues( kiBuffer[bar_index] = iKI; // - double iKIState = - iClose > iKI - ? bullishColorIDX - : iClose < iKI - ? bearishColorIDX - : neuturalColorIDX; + double iKIState = neuturalState; + double iKIColor = neuturalColorIDX; + if (iClose > iKI) + { + // + iKIState = bullishState; + iKIColor = + !showKI + ? hideColorIDX + : bullishColorIDX; + } + else if (iClose < iKI) + { + // + iKIState = bearishState; + iKIColor = + !showKI + ? hideColorIDX + : bearishColorIDX; + } kiStateBuffer[bar_index] = iKIState; - - // - double iKIColor = - showKI - ? iKIState - : hideColorIDX; kiColorBuffer[bar_index] = iKIColor; } @@ -1880,6 +1987,36 @@ void CalculateValues( : lastSwingHigh; swingHighBuffer[bar_index] = iSwingHigh; + // + // TKI State and Color ... + + // + double iTKI = tkiBuffer[bar_index]; + + // + double iTKIState = neuturalState; + double iTKIColor = neuturalColorIDX; + if (iClose > iTKI) + { + // + iTKIState = bullishState; + iTKIColor = + !showTKI + ? hideColorIDX + : bullishColorIDX; + } + else if (iClose < iTKI) + { + // + iTKIState = bearishState; + iTKIColor = + !showTKI + ? hideColorIDX + : bearishColorIDX; + } + tkiStateBuffer[bar_index] = iTKIState; + tkiColorBuffer[bar_index] = iTKIColor; + // // Cleanup Resources ... diff --git a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 new file mode 100644 index 00000000..8582d08a --- /dev/null +++ b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 @@ -0,0 +1,1099 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XCXCAEAPOIDetector ... +// Description: Class for XCAEA POI Detector ... +// +// +// 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 Class for XCAEA POI Detector" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" +#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" +#include "../Helpers/xcaea.helper.mq5" + +// +// Definitions ... + +// +enum ENUM_XCA_PIVOTS +{ + XCA_NONE, // None + XCA_SWL, // SWL + XCA_SWH, // SWH + XCA_VALE, // VALE + XCA_PEAK, // PEAK + XCA_PEAKSWHRES, // PeakSWHRes + XCA_VALESWLSUP, // ValeSWLSup +}; + +// +bool IsValid(ENUM_XCA_PIVOTS value) +{ + // + bool result = false; + + // + result = value != XCA_NONE; + + // + return result; +} + +// +string ToString(ENUM_XCA_PIVOTS value) +{ + // + string result = NULL; + + // + result = EnumToString(value); + + // + return result; +} + +// +struct XCAPivot +{ + // + // Props ... + datetime to; + double value; + string symbol; + datetime from; + double reserve; + ENUM_XCA_PIVOTS type; + ENUM_TIMEFRAMES period; + + // + // Constructor ... + XCAPivot() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup ... + */ + void Clean() + { + // + value = 0; + to = NULL; + reserve = 0; + from = NULL; + symbol = NULL; + period = NULL; + type = XCA_NONE; + } + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + from < to && + value != 0 && + IsValid(to) && + IsValid(from) && + IsValid(type) && + IsValid(symbol) && + IsValid(period); + + // + return result; + } + + /** + * Check a Model is Same as this or not ... + * + * @param pivot: XCAPivot ... + * + * @return ( bool ) + */ + bool IsSameAs(XCAPivot &pivot) + { + // + bool result = false; + + // + result = + IsValid() && + pivot.IsValid(); + if (!result) + { + return result; + } + + // + result = + to == pivot.to && + from == pivot.from && + type == pivot.type && + value == pivot.value && + symbol == pivot.symbol && + period == pivot.period; + + // + return result; + } + + /** + * Retrieve To Index ... + * + * @param forPeriod: ENUM_TIMEFRAMES, Specified Period ... + * + * @return ( int ) + */ + int ToIndex( + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = GetBarIndex( + symbol, + forPeriod, + to // + ); + + // + return result; + } + + /** + * Retrieve From Index ... + * + * @param forPeriod: ENUM_TIMEFRAMES, Specified Period ... + * + * @return ( int ) + */ + int FromIndex( + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = -1; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + result = GetBarIndex( + symbol, + forPeriod, + from // + ); + + // + return result; + } + + /** + * Retrieve Age of Pivot ... + * + * @param forPeriod: ENUM_TIMEFRAMES, Specified Period ... + * + * @return ( int ) + */ + int GetAge( + ENUM_TIMEFRAMES forPeriod = NULL // + ) + { + // + int result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsValid(forPeriod)) + { + forPeriod = period; + } + + // + int toIDX = ToIndex(forPeriod); + int fromIDX = FromIndex(forPeriod); + + // + result = fromIDX - toIDX; + + // + return result; + } + + /** + * Converts Pivot to Box ... + * + * @param box: XBoxZone instance reference ... + * + * @return ( bool ) + */ + bool AsBox( + XBoxZone &box // + ) + { + // + bool result = false; + + // + box.Clean(); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + switch (type) + { + // + case XCA_SWL: + case XCA_VALE: + case XCA_VALESWLSUP: + iDir = X_DIRECTION_BULLISH; + break; + + // + case XCA_SWH: + case XCA_PEAK: + case XCA_PEAKSWHRES: + iDir = X_DIRECTION_BEARISH; + break; + } + + // + result = HasDirection(iDir); + if (!result) + { + return result; + } + + // + bool isBullish = + IsBullish(iDir) && + value < reserve; + + // + bool isBearish = + IsBearish(iDir) && + value > reserve; + + // + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + box.to = to; + box.dir = iDir; + box.from = from; + box.symbol = symbol; + box.period = period; + box.type = ToString(type); + + // + box.upper = + isBullish + ? reserve + : value; + box.lower = + isBullish + ? value + : reserve; + + // + result = box.IsValid(); + if (!result) + { + box.Clean(); + } + + // + return result; + } + + // +}; + +/** + * Find Specified Pivot Index inside a Collection of Pivots ... + * + * @param pivot: XCAPivot instance Reference ... + * @param pivots: XCAPivot instance Reference Collection ... + * + * @return ( int ) + */ +bool FindPivotIndex( + int &index, + XCAPivot &pivot, + XCAPivot &pivots[] // +) +{ + // + bool result = false; + + // + index = -1; + + // + int count = ArraySize(pivots); + result = pivot.IsValid() && + IsValidSize(count); + if (!result) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XCAPivot iPivot = pivots[i]; + + // + bool isSame = pivot.IsSameAs(iPivot); + if (isSame) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; +} + +// +// Implementations ... +class XCXCAEAPOIDetector : public XCBase +{ + // + // Public ... + public: + // + // Props ... + XCAPivot swhPivots[]; + XCAPivot swlPivots[]; + XCAPivot peakPivots[]; + XCAPivot valePivots[]; + XCAPivot peakSWHResPivots[]; + XCAPivot valeSWLSupPivots[]; + + // + // Constructors ... + XCXCAEAPOIDetector( + XCXCAEAHelper *_helper // + ) + { + // + helper = _helper; + drawer = new XCPOIDrawer(); + barAnalyser = new XCBarAnalyser(); + + // + Default(); + } + + // + // De Constructors ... + ~XCXCAEAPOIDetector() + { + // + peakPivot.Clean(); + Clean(peakPivots); + + // + valePivot.Clean(); + Clean(valePivots); + + // + peakSWHResPivot.Clean(); + Clean(peakSWHResPivots); + + // + valeSWLSupPivot.Clean(); + Clean(valeSWLSupPivots); + + // + ZeroMemory(helper); + ZeroMemory(drawer); + ZeroMemory(barAnalyser); + } + + // + // Properties ... + + // + // Tools ... + + virtual void Default() + { + // + pivotVerifications = 5; + } + + // + void Update( + int barIndex = 0, + int loopback = 400 // + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + loopback = NormalizeInt(loopback, 400); + + // + int count = 0; + bool has = false; + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + + // + int index = barIndex; + int start = index; + int end = index + loopback; + while (start < end) + { + // + // Retrieve Conditions ... + XCAEAConditions iConditions; + has = helper.GetConditions( + iConditions, + start, + 5 // + ); + + // + // Retrieve Bars ... + XOHCL zBar; + XOHCL cBar; + XOHCL pBar; + XOHCL p2Bar; + has = zBar.Init( + iConditions.symbol, + iConditions.period, + start // + ); + has = + has && + zBar.GetPreviousBar(cBar); + has = + has && + cBar.GetPreviousBar(pBar); + has = + has && + pBar.GetPreviousBar(p2Bar); + if (!has) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + iConditions.Clean(); + + // + continue; + } + + // + // Checking Pivots ... + + // + // Peak Pivot ... + + // + if (!peakPivot.IsValid()) + { + // + peakPivot.type = XCA_PEAK; + peakPivot.symbol = iConditions.symbol; + peakPivot.period = iConditions.period; + + // + if (iConditions.isPeakSameLast) + { + // + peakPivot.to = cBar.time; + peakPivot.from = pBar.time; + peakPivot.value = iConditions.peakBuffer[cIDX]; + } + } + + // + if (iConditions.isPeakSameLast) + { + // + peakPivot.from = pBar.time; + peakPivot.reserve = + peakPivot.reserve == 0 + ? iConditions.peakGoldenBuffer[cIDX] + : MathMax(peakPivot.reserve, iConditions.peakGoldenBuffer[cIDX]); + } + + // + if (!iConditions.isPeakSameLast) + { + // + has = + peakPivot.IsValid() && + peakPivot.GetAge() >= pivotVerifications; + if (has) + { + // + AddPivot( + peakPivot, + peakPivots // + ); + } + + // + peakPivot.Clean(); + } + + // + // Peak SWH Res Pivot ... + + // + if (!peakSWHResPivot.IsValid()) + { + // + peakSWHResPivot.type = XCA_PEAKSWHRES; + peakSWHResPivot.symbol = iConditions.symbol; + peakSWHResPivot.period = iConditions.period; + + // + if (iConditions.isPeakIsPivot && iConditions.isPeakSameLast) + { + // + peakSWHResPivot.to = cBar.time; + peakSWHResPivot.from = pBar.time; + peakSWHResPivot.value = iConditions.peakBuffer[cIDX]; + } + } + + // + if (iConditions.isPeakIsPivot && iConditions.isPeakSameLast) + { + // + peakSWHResPivot.from = pBar.time; + peakSWHResPivot.reserve = + peakSWHResPivot.reserve == 0 + ? iConditions.peakGoldenBuffer[cIDX] + : MathMax(peakSWHResPivot.reserve, iConditions.peakGoldenBuffer[cIDX]); + } + + // + if (!(iConditions.isPeakIsPivot && iConditions.isPeakSameLast)) + { + // + has = peakSWHResPivot.IsValid() && + peakSWHResPivot.GetAge() >= pivotVerifications; + if (has) + { + // + AddPivot( + peakSWHResPivot, + peakSWHResPivots // + ); + } + + // + peakSWHResPivot.Clean(); + } + + // + // Vale Pivot ... + + // + if (!valePivot.IsValid()) + { + // + valePivot.type = XCA_VALE; + valePivot.symbol = iConditions.symbol; + valePivot.period = iConditions.period; + + // + if (iConditions.isValeSameLast) + { + // + valePivot.to = cBar.time; + valePivot.from = pBar.time; + valePivot.value = iConditions.valeBuffer[cIDX]; + } + } + + // + if (iConditions.isValeSameLast) + { + // + valePivot.from = pBar.time; + valePivot.reserve = + valePivot.reserve == 0 + ? iConditions.valeGoldenBuffer[cIDX] + : MathMin(valePivot.reserve, iConditions.valeGoldenBuffer[cIDX]); + } + + // + if (!iConditions.isValeSameLast) + { + // + has = valePivot.IsValid() && + valePivot.GetAge() >= pivotVerifications; + if (has) + { + // + AddPivot( + valePivot, + valePivots // + ); + } + + // + valePivot.Clean(); + } + + // + // Vale SWL Sup Pivot ... + + // + if (!valeSWLSupPivot.IsValid()) + { + // + valeSWLSupPivot.type = XCA_VALESWLSUP; + valeSWLSupPivot.symbol = iConditions.symbol; + valeSWLSupPivot.period = iConditions.period; + + // + if (iConditions.isValeIsPivot && iConditions.isValeSameLast) + { + // + valeSWLSupPivot.to = cBar.time; + valeSWLSupPivot.from = pBar.time; + valeSWLSupPivot.value = iConditions.valeBuffer[cIDX]; + } + } + + // + if (iConditions.isValeIsPivot && iConditions.isValeSameLast) + { + // + valeSWLSupPivot.from = pBar.time; + valeSWLSupPivot.reserve = + valeSWLSupPivot.reserve == 0 + ? iConditions.valeGoldenBuffer[cIDX] + : MathMin(valeSWLSupPivot.reserve, iConditions.valeGoldenBuffer[cIDX]); + } + + // + if (!(iConditions.isValeIsPivot && iConditions.isValeSameLast)) + { + // + has = valeSWLSupPivot.IsValid() && + valeSWLSupPivot.GetAge() >= pivotVerifications; + if (has) + { + // + AddPivot( + valeSWLSupPivot, + valeSWLSupPivots // + ); + } + + // + valeSWLSupPivot.Clean(); + } + + // + // SWH Pivot ... + + // + if (!swhPivot.IsValid()) + { + // + swhPivot.type = XCA_SWH; + swhPivot.symbol = iConditions.symbol; + swhPivot.period = iConditions.period; + + // + if (iConditions.isSwingHighSameLast) + { + // + swhPivot.to = cBar.time; + swhPivot.from = pBar.time; + swhPivot.value = iConditions.swingHighBuffer[cIDX]; + } + } + + // + if (iConditions.isSwingHighSameLast) + { + // + swhPivot.from = pBar.time; + } + + // + if (!iConditions.isSwingHighSameLast) + { + // + has = + swhPivot.IsValid() && + cBar.high > cBar.GetUp() && + cBar.high == swhPivot.value && + swhPivot.GetAge() >= pivotVerifications; + if (has) + { + // + swhPivot.reserve = cBar.GetUp(); + + // + AddPivot( + swhPivot, + swhPivots // + ); + } + + // + swhPivot.Clean(); + } + + // + // SWL Pivot ... + + // + if (!swlPivot.IsValid()) + { + // + swlPivot.type = XCA_SWL; + swlPivot.symbol = iConditions.symbol; + swlPivot.period = iConditions.period; + + // + if (iConditions.isSwingLowSameLast) + { + // + swlPivot.to = cBar.time; + swlPivot.from = pBar.time; + swlPivot.value = iConditions.swingLowBuffer[cIDX]; + } + } + + // + if (iConditions.isSwingLowSameLast) + { + // + swlPivot.from = pBar.time; + } + + // + if (!iConditions.isSwingLowSameLast) + { + // + has = + swlPivot.IsValid() && + cBar.low < cBar.GetDown() && + cBar.low == swlPivot.value && + swlPivot.GetAge() >= pivotVerifications; + if (has) + { + // + swlPivot.reserve = cBar.GetDown(); + + // + AddPivot( + swlPivot, + swlPivots // + ); + } + + // + swlPivot.Clean(); + } + + // + start++; + + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + iConditions.Clean(); + } + + // + } + + // + // POI Handlers ... + + // + bool HasPeakPivots() + { + return HasChild(peakPivots); + } + + // + int CountPeakPivots() + { + return ArraySize(peakPivots); + } + + // + bool HasPeakSWHResPivots() + { + return HasChild(peakSWHResPivots); + } + + // + int CountPeakSWHResPivots() + { + return ArraySize(peakSWHResPivots); + } + + // + bool HasValePivots() + { + return HasChild(valePivots); + } + + // + int CountValePivots() + { + return ArraySize(valePivots); + } + + // + bool HasValeSWLSupPivots() + { + return HasChild(valeSWLSupPivots); + } + + // + int CountValeSWLSupPivots() + { + return ArraySize(valeSWLSupPivots); + } + + // + bool HasSWHPivots() + { + return HasChild(swhPivots); + } + + // + int CountSWHPivots() + { + return ArraySize(swhPivots); + } + + // + bool HasSWLPivots() + { + return HasChild(swlPivots); + } + + // + int CountSWLPivots() + { + return ArraySize(swlPivots); + } + + // + // Protected ... + protected: + // + // Props ... + + // + // Prrivate ... + private: + // + // Props ... + int pivotVerifications; // Pivots Verifications ... + + // + XCAPivot swhPivot; + XCAPivot swlPivot; + XCAPivot peakPivot; + XCAPivot valePivot; + XCAPivot peakSWHResPivot; + XCAPivot valeSWLSupPivot; + + // + XCPOIDrawer *drawer; + XCXCAEAHelper *helper; + XCBarAnalyser *barAnalyser; + + // + void AddBox( + XBoxZone &box, + XBoxZone &boxes[] // + ) + { + // + bool has = box.IsValid(); + if (!has) + { + return; + } + + // + int idx = -1; + has = FindBoxIndex( + idx, + box, + boxes // + ); + if (has) + { + return; + } + + // + AddRef( + box, + boxes // + ); + } + + // + void AddPivot( + XCAPivot &pivot, + XCAPivot &pivots[] // + ) + { + // + bool has = pivot.IsValid(); + if (!has) + { + return; + } + + // + int idx = -1; + has = FindPivotIndex( + idx, + pivot, + pivots // + ); + if (has) + { + return; + } + + // + int updateIDX = -1; + int count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + XCAPivot iPivot = pivots[i]; + + // + has = + iPivot.to < pivot.to && + iPivot.from == pivot.from && + iPivot.value == pivot.value && + iPivot.symbol == pivot.symbol && + iPivot.period == pivot.period; + if (has) + { + // + updateIDX = i; + break; + } + } + + // + has = IsValidIndex(updateIDX); + if (!has) + { + // + AddRef( + pivot, + pivots // + ); + } + else + { + // + pivots[updateIDX].to = pivot.to; + } + } + + // +}; + +// \ No newline at end of file diff --git a/XCAEA/Helpers/xcaea.helper.mq5 b/XCAEA/Helpers/xcaea.helper.mq5 index 8c0750b7..c9cafd3d 100644 --- a/XCAEA/Helpers/xcaea.helper.mq5 +++ b/XCAEA/Helpers/xcaea.helper.mq5 @@ -163,6 +163,10 @@ struct XCAEAConditions ENUM_TIMEFRAMES period; datetime time; + // + datetime to; + datetime from; + // // XCA ... @@ -171,6 +175,7 @@ struct XCAEAConditions // double kiBuffer[]; + double tkiBuffer[]; double sHHBuffer[]; double sLLBuffer[]; double mHHBuffer[]; @@ -185,6 +190,7 @@ struct XCAEAConditions double trendBuffer[]; double kiStateBuffer[]; double supportBuffer[]; + double tkiStateBuffer[]; double swingLowBuffer[]; double swingHighBuffer[]; double resistanceBuffer[]; @@ -213,6 +219,21 @@ struct XCAEAConditions bool isKISwitchedToBullish; bool isKISwitchedToBearish; + // + // TKI ... + + // + bool isTKIRejectUp; + bool isTKIRejectDown; + + // + bool isTKIBullish; + bool isTKIBearish; + + // + bool isTKISwitchedToBullish; + bool isTKISwitchedToBearish; + // // SAR ... @@ -577,6 +598,10 @@ struct XCAEAConditions // Commons ... symbol = NULL; period = NULL; + + // + to = NULL; + from = NULL; time = NULL; // @@ -587,6 +612,7 @@ struct XCAEAConditions // Clean(kiBuffer); + Clean(tkiBuffer); Clean(sHHBuffer); Clean(sLLBuffer); Clean(mHHBuffer); @@ -601,6 +627,7 @@ struct XCAEAConditions Clean(trendBuffer); Clean(kiStateBuffer); Clean(supportBuffer); + Clean(tkiStateBuffer); Clean(swingLowBuffer); Clean(swingHighBuffer); Clean(resistanceBuffer); @@ -613,6 +640,7 @@ struct XCAEAConditions // ArraySetAsSeries(kiBuffer, true); + ArraySetAsSeries(tkiBuffer, true); ArraySetAsSeries(sHHBuffer, true); ArraySetAsSeries(sLLBuffer, true); ArraySetAsSeries(mHHBuffer, true); @@ -627,6 +655,7 @@ struct XCAEAConditions ArraySetAsSeries(trendBuffer, true); ArraySetAsSeries(kiStateBuffer, true); ArraySetAsSeries(supportBuffer, true); + ArraySetAsSeries(tkiStateBuffer, true); ArraySetAsSeries(swingLowBuffer, true); ArraySetAsSeries(swingHighBuffer, true); ArraySetAsSeries(resistanceBuffer, true); @@ -655,6 +684,21 @@ struct XCAEAConditions isKISwitchedToBullish = false; isKISwitchedToBearish = false; + // + // TKI ... + + // + isTKIRejectUp = false; + isTKIRejectDown = false; + + // + isTKIBullish = false; + isTKIBearish = false; + + // + isTKISwitchedToBullish = false; + isTKISwitchedToBearish = false; + // // SAR ... @@ -1008,6 +1052,37 @@ struct XCAEAConditions bearishScore += minScore; } + // + // TKI ... + + // + if (isTKIBullish) + { + bullishScore += minScore; + } + if (isTKIRejectUp) + { + bullishScore += minScore; + } + if (isTKISwitchedToBullish) + { + bullishScore += minScore; + } + + // + if (isTKIBearish) + { + bearishScore += minScore; + } + if (isTKIRejectDown) + { + bearishScore += minScore; + } + if (isTKISwitchedToBearish) + { + bearishScore += minScore; + } + // // SAR ... @@ -1695,6 +1770,12 @@ struct XCAEAConditions ToString("isKIBearish", isKIBearish, ignoreFalseConditions, separator) + ToString("isKISwitchedToBullish", isKISwitchedToBullish, ignoreFalseConditions, separator) + ToString("isKISwitchedToBearish", isKISwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isTKIRejectUp", isTKIRejectUp, ignoreFalseConditions, separator) + + ToString("isTKIRejectDown", isTKIRejectDown, ignoreFalseConditions, separator) + + ToString("isTKIBullish", isTKIBullish, ignoreFalseConditions, separator) + + ToString("isTKIBearish", isTKIBearish, ignoreFalseConditions, separator) + + ToString("isTKISwitchedToBullish", isTKISwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isTKISwitchedToBearish", isTKISwitchedToBearish, ignoreFalseConditions, separator) + ToString("isSarBullish", isSarBullish, ignoreFalseConditions, separator) + ToString("isSarBearish", isSarBearish, ignoreFalseConditions, separator) + ToString("isSarSwitchedToBullish", isSarSwitchedToBullish, ignoreFalseConditions, separator) + @@ -2396,6 +2477,7 @@ class XCXCAEAHelper : XCBase XOHCL zBar; XOHCL cBar; XOHCL pBar; + XOHCL fromBar; // X121XCAConditions xcaConditions; @@ -2413,6 +2495,12 @@ class XCXCAEAHelper : XCBase result = result && cBar.GetPreviousBar(pBar); + result = + result && + fromBar.Init( + zBar.symbol, + zBar.period, + zIndex + loopback); // // Conditions Retriever ... @@ -2445,6 +2533,7 @@ class XCXCAEAHelper : XCBase zBar.Clean(); cBar.Clean(); pBar.Clean(); + fromBar.Clean(); // xcaConditions.Clean(); @@ -2454,6 +2543,10 @@ class XCXCAEAHelper : XCBase return result; } + // + conditions.to = zBar.time; + conditions.from = fromBar.time; + // // Fill X121 Conditions Reference by Using // Retrieved Conditions ... @@ -2474,6 +2567,12 @@ class XCXCAEAHelper : XCBase conditions.kiBuffer // ); + // + Copy( + xcaConditions.tkiBuffer, + conditions.tkiBuffer // + ); + // Copy( xcaConditions.sHHBuffer, @@ -2552,6 +2651,12 @@ class XCXCAEAHelper : XCBase conditions.kiStateBuffer // ); + // + Copy( + xcaConditions.tkiStateBuffer, + conditions.tkiStateBuffer // + ); + // Copy( xcaConditions.supportBuffer, @@ -2619,8 +2724,11 @@ class XCXCAEAHelper : XCBase conditions.isKIBullish = xcaConditions.isKIBullish; conditions.isKIBearish = xcaConditions.isKIBearish; conditions.isKIRejectUp = xcaConditions.isKIRejectUp; + conditions.isTKIBullish = xcaConditions.isTKIBullish; + conditions.isTKIBearish = xcaConditions.isTKIBearish; conditions.isSarBullish = xcaConditions.isSarBullish; conditions.isSarBearish = xcaConditions.isSarBearish; + conditions.isTKIRejectUp = xcaConditions.isTKIRejectUp; conditions.isPeakIsPivot = xcaConditions.isPeakIsPivot; conditions.isValeIsPivot = xcaConditions.isValeIsPivot; conditions.isKIRejectDown = xcaConditions.isKIRejectDown; @@ -2630,6 +2738,7 @@ class XCXCAEAHelper : XCBase conditions.isValeOverLast = xcaConditions.isValeOverLast; conditions.isTrendBullish = xcaConditions.isTrendBullish; conditions.isTrendBearish = xcaConditions.isTrendBearish; + conditions.isTKIRejectDown = xcaConditions.isTKIRejectDown; conditions.isPeakUnderLast = xcaConditions.isPeakUnderLast; conditions.isValeUnderLast = xcaConditions.isValeUnderLast; conditions.isTrendRejectUp = xcaConditions.isTrendRejectUp; @@ -2654,6 +2763,8 @@ class XCXCAEAHelper : XCBase conditions.isKISwitchedToBearish = xcaConditions.isKISwitchedToBearish; conditions.isLastSwingLowBreaked = xcaConditions.isLastSwingLowBreaked; conditions.isSwingHighSameAsPeak = xcaConditions.isSwingHighSameAsPeak; + conditions.isTKISwitchedToBullish = xcaConditions.isTKISwitchedToBullish; + conditions.isTKISwitchedToBearish = xcaConditions.isTKISwitchedToBearish; conditions.isLastSwingLowRejected = xcaConditions.isLastSwingLowRejected; conditions.isSarSwitchedToBullish = xcaConditions.isSarSwitchedToBullish; conditions.isSarSwitchedToBearish = xcaConditions.isSarSwitchedToBearish; @@ -2866,6 +2977,7 @@ class XCXCAEAHelper : XCBase zBar.Clean(); cBar.Clean(); pBar.Clean(); + fromBar.Clean(); // xcaConditions.Clean(); diff --git a/XCAEA/Libraries/xcaea.signaller.lib.mq5 b/XCAEA/Libraries/xcaea.signaller.lib.mq5 index 9f7ee2b1..2f377415 100644 --- a/XCAEA/Libraries/xcaea.signaller.lib.mq5 +++ b/XCAEA/Libraries/xcaea.signaller.lib.mq5 @@ -598,9 +598,176 @@ bool DetectXCAEAConditions( isCBarBearishMomentum || isCBarBearishEngulfed); + // + // Score ... + + // + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + bool isScoreBullish = + bullishScore > bearishScore; + + // + bool isScoreBearish = + bearishScore > bullishScore; + + // + string summary = + conditions + .GenerateSummary(); + // // Conditions ... + // + // Reading Values ... + + // + // KI ... + + // + double cKI = conditions.kiBuffer[cIDX]; + double pKI = conditions.kiBuffer[pIDX]; + double p2KI = conditions.kiBuffer[ppIDX]; + + // + double cKIState = conditions.kiStateBuffer[cIDX]; + double pKIState = conditions.kiStateBuffer[pIDX]; + double p2KIState = conditions.kiStateBuffer[ppIDX]; + + // + // TKI ... + + // + double cTKI = conditions.tkiBuffer[cIDX]; + double pTKI = conditions.tkiBuffer[pIDX]; + double p2TKI = conditions.tkiBuffer[ppIDX]; + + // + double cTKIState = conditions.tkiStateBuffer[cIDX]; + double pTKIState = conditions.tkiStateBuffer[pIDX]; + double p2TKIState = conditions.tkiStateBuffer[ppIDX]; + + // + // TREND ... + + // + double cTrend = conditions.trendBuffer[cIDX]; + double pTrend = conditions.trendBuffer[pIDX]; + double p2Trend = conditions.trendBuffer[ppIDX]; + + // + double ctrendState = conditions.trendStateBuffer[cIDX]; + double ptrendState = conditions.trendStateBuffer[pIDX]; + double p2trendState = conditions.trendStateBuffer[ppIDX]; + + // + // SWING Low ... + + // + double cSWL = conditions.swingLowBuffer[cIDX]; + double pSWL = conditions.swingLowBuffer[pIDX]; + double p2SWL = conditions.swingLowBuffer[ppIDX]; + + // + // SWING High ... + + // + double cSWH = conditions.swingHighBuffer[cIDX]; + double pSWH = conditions.swingHighBuffer[pIDX]; + double p2SWH = conditions.swingHighBuffer[ppIDX]; + + // + // PEAK ... + + // + double cPeak = conditions.peakBuffer[cIDX]; + double pPeak = conditions.peakBuffer[pIDX]; + double p2Peak = conditions.peakBuffer[ppIDX]; + + // + // VALE ... + + // + double cVale = conditions.valeBuffer[cIDX]; + double pVale = conditions.valeBuffer[pIDX]; + double p2Vale = conditions.valeBuffer[ppIDX]; + + // + // COMPLEX ... + + // + double iKTIRNDs[] = { + cKI, + cTKI, + cTrend // + }; + + // + double iKTIRNDMax = GetMax(iKTIRNDs); + double iKTIRNDMin = GetMin(iKTIRNDs); + + // + // Conditions Preparing ... + + // + bool isTKITRNDBullish = + cKIState > 0 && + cTKIState > 0 && + ctrendState > 0; + + // + bool isTKITRNDBullishPrev = + pKIState > 0 && + pTKIState > 0 && + ptrendState > 0; + + // + bool isTKITRNDBearish = + cKIState < 0 && + cTKIState < 0 && + ctrendState < 0; + + // + bool isTKITRNDBearishPrev = + pKIState < 0 && + pTKIState < 0 && + ptrendState < 0; + + // + bool isTKITRNDSwitchedToBullish = + isTKITRNDBullish && + !isTKITRNDBullishPrev; + + // + bool isTKITRNDSwitchedToBearish = + isTKITRNDBearish && + !isTKITRNDBearishPrev; + + // + bool isCond1Bullish = + conditions.isValeIsPivot && + isTKITRNDSwitchedToBullish; + + // + bool isCond1Bearish = + conditions.isPeakIsPivot && + isTKITRNDSwitchedToBearish; + + // + if (isCond1Bullish || + isCond1Bearish) + { + // + Print("Cond1"); + } + // // Summarise Conditions ... diff --git a/XCAEA/Signals/xcaea.signaller.class.mq5 b/XCAEA/Signals/xcaea.signaller.class.mq5 index 3cfdcea1..fe3ad57b 100644 --- a/XCAEA/Signals/xcaea.signaller.class.mq5 +++ b/XCAEA/Signals/xcaea.signaller.class.mq5 @@ -23,6 +23,7 @@ // Imports ... #include "../../Classes/x-saherelm.base.class.mq5" #include "../../Classes/x-saherelm.x-cobject.class.mq5" +#include "../Classes/xcaea.x-poi.detector.class.mq5" #include "../Helpers/xcaea.helper.mq5" #include "../Libraries/xcaea.signaller.lib.mq5" @@ -41,6 +42,7 @@ class XCXCAEASignaller : XCBase XBarTracker barTraker; XCXCAEAHelper *helper; bool continuesRFTillTarget; + XCXCAEAPOIDetector *detector; XCAEAStrategyConditions mConditions; XCAEAStrategyConditions mConditionsCollection[]; @@ -115,6 +117,11 @@ class XCXCAEASignaller : XCBase // int loopback = 10; + // + int idx = -1; + int count = 0; + bool has = false; + // double ask = GetAsk(symbol); double bid = GetBid(symbol); @@ -159,7 +166,180 @@ class XCXCAEASignaller : XCBase ENUM_X_DIRECTION signalBoxDir = X_DIRECTION_NONE; // - // Checking Conditions ... + // Detecting Pivots ... + detector.Update( + zIndex // + ); + + // + bool drawSWHPivots = true; + bool drawSWLPivots = true; + bool drawPeakPivots = false; + bool drawValePivots = false; + + // + // Draw Peak SWH Res Pivots ... + if (drawPeakPivots) + { + // + has = detector.HasPeakSWHResPivots(); + if (has) + { + // + count = detector.CountPeakSWHResPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox; + has = detector + .peakSWHResPivots[i] + .AsBox(iBox); + if (has) + { + // + iBox.to = cTime; + + // + XCBoxObject *iObj; + has = helper.poiDrawer.DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + } + + // + iBox.Clean(); + } + + // + Print("Draw Peak SWH Res Pivots ..."); + } + } + + // + // Draw Vale SWL Sup Pivots ... + if (drawValePivots) + { + // + has = detector.HasValeSWLSupPivots(); + if (has) + { + // + count = detector.CountValeSWLSupPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox; + has = detector + .valeSWLSupPivots[i] + .AsBox(iBox); + if (has) + { + // + iBox.to = cTime; + + // + XCBoxObject *iObj; + has = helper.poiDrawer.DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + } + + // + iBox.Clean(); + } + + // + Print("Draw Vale SWL Sup Pivots ..."); + } + } + + // + // Draw SWH Pvots ... + if (drawSWHPivots) + { + // + has = detector.HasSWHPivots(); + if (has) + { + // + count = detector.CountSWHPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox; + has = detector + .swhPivots[i] + .AsBox(iBox); + if (has) + { + // + iBox.to = cTime; + + // + XCBoxObject *iObj; + has = helper + .poiDrawer + .DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + } + } + } + } + + // + // Draw SWL Pvots ... + if (drawSWLPivots) + { + // + has = detector.HasSWLPivots(); + if (has) + { + // + count = detector.CountSWLPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox; + has = detector + .swlPivots[i] + .AsBox(iBox); + if (has) + { + // + iBox.to = cTime; + + // + XCBoxObject *iObj; + has = helper + .poiDrawer + .DrawBox( + iBox, + iObj // + ); + if (has) + { + mObjects.Add(iObj); + } + } + } + } + } // XCAEAConditions conditions; @@ -232,7 +412,8 @@ class XCXCAEASignaller : XCBase ? entry - sl : sl - entry; risk += spread; - if (risk >= maxAllowedSLDistanceInPoint * points) { + if (risk >= maxAllowedSLDistanceInPoint * points) + { // // Fix Risk in Big Distances ... double hh5 = zBar.FindHighest(5, MODE_HIGH); @@ -541,23 +722,23 @@ class XCXCAEASignaller : XCBase // inputs.caInputs.supResSmoothingLength = 7; - inputs.caInputs.supResSmoothingMode = X_MA_MODE_NONE; + inputs.caInputs.supResSmoothingMode = X_MA_MODE_NONE; // inputs.caInputs.showKI = true; - inputs.caInputs.showSar = true; + inputs.caInputs.showSar = false; inputs.caInputs.showTrend = true; - inputs.caInputs.showSwings = false; + inputs.caInputs.showSwings = true; inputs.caInputs.showLongCycle = false; inputs.caInputs.showHindCycle = false; - inputs.caInputs.showFiboLevel1 = false; + inputs.caInputs.showFiboLevel1 = true; inputs.caInputs.showFiboLevel2 = false; - inputs.caInputs.showFiboLevel3 = false; + inputs.caInputs.showFiboLevel3 = true; inputs.caInputs.showShortCycle = false; inputs.caInputs.showMediumCycle = false; inputs.caInputs.showPeaksAndVales = true; - inputs.caInputs.showPeakAndValeGolden = true; - inputs.caInputs.showSupportAndResistance = true; + inputs.caInputs.showPeakAndValeGolden = false; + inputs.caInputs.showSupportAndResistance = false; // // XOSCS ... @@ -582,6 +763,9 @@ class XCXCAEASignaller : XCBase period, inputs // ); + + // + detector = new XCXCAEAPOIDetector(helper); } /** @@ -592,6 +776,7 @@ class XCXCAEASignaller : XCBase // inputs.Clean(); ZeroMemory(helper); + ZeroMemory(detector); // mConditions.Clean();