diff --git a/XCAEA/Classes/xcaea.x-data.collector.class.mq5 b/Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-data.collector.class.mq5 similarity index 100% rename from XCAEA/Classes/xcaea.x-data.collector.class.mq5 rename to Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-data.collector.class.mq5 diff --git a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 b/Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 similarity index 100% rename from XCAEA/Classes/xcaea.x-poi.detector.class.mq5 rename to Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 diff --git a/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 b/Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 similarity index 100% rename from XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 rename to Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 diff --git a/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 b/Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 similarity index 100% rename from XCAEA/Classes/xcaea.x-trade.manager.class.mq5 rename to Documents/BKP/XCAEA_BKP/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 diff --git a/XCAEA/Helpers/xcaea.helper.mq5 b/Documents/BKP/XCAEA_BKP/XCAEA/Helpers/xcaea.helper.mq5 similarity index 100% rename from XCAEA/Helpers/xcaea.helper.mq5 rename to Documents/BKP/XCAEA_BKP/XCAEA/Helpers/xcaea.helper.mq5 diff --git a/XCAEA/Libraries/xcaea.signaller.lib.mq5 b/Documents/BKP/XCAEA_BKP/XCAEA/Libraries/xcaea.signaller.lib.mq5 similarity index 100% rename from XCAEA/Libraries/xcaea.signaller.lib.mq5 rename to Documents/BKP/XCAEA_BKP/XCAEA/Libraries/xcaea.signaller.lib.mq5 diff --git a/XCAEA/Signals/xcaea.signaller.class.mq5 b/Documents/BKP/XCAEA_BKP/XCAEA/Signals/xcaea.signaller.class.mq5 similarity index 100% rename from XCAEA/Signals/xcaea.signaller.class.mq5 rename to Documents/BKP/XCAEA_BKP/XCAEA/Signals/xcaea.signaller.class.mq5 diff --git a/Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 b/Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 new file mode 100644 index 00000000..9f1645d6 --- /dev/null +++ b/Documents/BKP/XCAEA_BKP/tmp.detect.tb.mq5 @@ -0,0 +1,955 @@ + +// +// Detect Trigger Block ... +bool DetectTriggerBlock( + // + string symbol, + ENUM_TIMEFRAMES period, + // + XTriggerBlock &tb, + // + XCBarAnalyser *barAnalyser, + // + // Required Buffers ... + const double &_atrBuffer[], + const double &_rsiBuffer[], + const double &_adxBuffer[], + const double &_adxpBuffer[], + const double &_adxnBuffer[], + const double &_peakBuffer[], + const double &_valeBuffer[], + const double &_deltaBuffer[], + const double &_sarBuffer[], + const double &_sarStateBuffer[], + const double &_trendBuffer[], + const double &_trendStateBuffer[], + const double &_atrUpperBuffer[], + const double &_atrLowerBuffer[], + const double &_sBarOpenSBuffer[], + const double &_sBarCloseBuffer[], + const double &_hkSBarOpenBuffer[], + const double &_hkSBarCloseBuffer[], + const double &_peakGoldenBuffer[], + const double &_valeGoldenBuffer[], + const double &_deltaSignalBuffer[], + const double &_bullishVolumeSignalBuffer[], + const double &_bearishVolumeSignalBuffer[], + // + int barIndex, + // + int _r2r, + double _slAtrMultiplier, + // + // Configs ... + double _rsiOBLevel, + double _rsiOSLevel, + double _adxThreshold, + // + // Validators ... + // + bool _forceOBBarType = false, + bool _forceFVGBarType = false, + bool _forceHasSwing = false, + bool _forceHasFLiquidity = false, + bool _forceHasRLiquidity = false, + bool _validateGapSequence = false, + bool _validateBlockEdgeBreakout = false, + // + // Filters ... + bool _filterBasedOnPV = false, + bool _filterBasedOnSar = false, + bool _filterBasedOnRSI = false, + bool _filterBasedOnADX = false, + bool _filterBasedOnATR = false, + bool _filterBasedOnTrend = false, + bool _filterBasedOnDelta = false, + bool _filterBasedOnVolume = false, + bool _filterBasedOnSignalBar = false, + bool _filterBasedOnHKSignalBar = false // +) +{ + // + bool result = false; + + // + // Custom Configs ... + + // // + // _r2r = 2; + // _slAtrMultiplier = 1; + + // // + // // Validators ... + // _forceHasSwing = true; + // _forceOBBarType = true; + // _forceFVGBarType = true; + // _validateGapSequence = true; + + // // + // _forceHasFLiquidity = false; + // _forceHasRLiquidity = false; + // _validateBlockEdgeBreakout = true; + + // // + // // Filters ... + // _filterBasedOnPV = true; + // _filterBasedOnATR = true; + // _filterBasedOnDelta = true; + // _filterBasedOnVolume = true; + + // // + // _filterBasedOnSar = true; + // _filterBasedOnRSI = false; + // _filterBasedOnADX = false; + // _filterBasedOnTrend = false; + // _filterBasedOnSignalBar = true; + // _filterBasedOnHKSignalBar = true; + + // + tb.Clean(); + + // + result = barAnalyser != NULL; + if (!result) + { + return result; + } + + // + int zIDX = 0; + bool has = false; + bool isDone = false; + ENUM_X_DIRECTION iDir = X_DIRECTION_NONE; + + // + // Retrieve Required Bars ... + + // + XOHCL iBar; + XOHCL zBar; // Current Start Checking Bar (Usually Used for Triggering) ... + has = zBar.Init( + symbol, + period, + barIndex // + ); + + // + // Detect Based Order Block ... + has = + has && + barAnalyser.IsOB( + zBar, + tb.ob, + _forceFVGBarType, // Force FVG Bar Type ... + _forceOBBarType // Force Block Two Bar Checking ... + ); + + // + // Detect Based Fair Value Gap ... + has = + has && + barAnalyser.IsFVG( + zBar, + tb.fvg, + _forceFVGBarType // Force FVG Bar Type ... + ); + + // + // Clone Trigger Block ... + if (has) + { + // + tb.trigger = tb.ob; + tb.trigger.type = "XTRGB"; + } + + // + bool isBullish = + has && + tb.IsBullish(); + + // + bool isBearish = + has && + tb.IsBearish(); + + // + int toIDX = tb.ToIndex(); + int fromIDX = tb.FromIndex(); + + // + // Verifications and Filters ... + + // + int loopback = 144; + + // + // Forces ... + + // + // Force Has Proper Swing ... + if (has && + _forceHasSwing) + { + // + XOHCL iPBar; + XOHCL iP2Bar; + toIDX = tb.ToIndex(); + fromIDX = tb.FromIndex(); + for (int i = toIDX; i <= fromIDX; i++) + { + // + // Initialize iBar ... + isDone = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + isDone = + isDone && + iBar.GetPreviousBar(iPBar); + isDone = + isDone && + iPBar.GetPreviousBar(iP2Bar); + isDone = + isDone && + barAnalyser.IsSimpleSwing( + iBar, + iDir // + ) && + iDir == tb.GetDirection(); + if (isDone) + { + // + bool canSet = + !tb.swingBar.IsValid() + ? true + : (isBullish + ? tb.swingBar.low > iP2Bar.low + : tb.swingBar.high < iP2Bar.high); + if (canSet) + { + tb.swingBar = iP2Bar; + } + } + + // + iBar.Clean(); + iPBar.Clean(); + iP2Bar.Clean(); + } + + // + has = tb.swingBar.IsValid(); + } + + // + // Force Has Liquidity ... + // TODO: Add Validation based on Liquidities + // if necessary ... + if (has && + (_forceHasFLiquidity || + _forceHasRLiquidity)) + { + // + toIDX = tb.ToIndex(); + fromIDX = tb.FromIndex(); + for (int i = toIDX; i < fromIDX + loopback; i++) + { + // + // Initialize iBar ... + isDone = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + + // + bool isRejected = + isDone && + barAnalyser.IsRejected( + iBar, + iDir, + false, // Force Bar Type ... + true // Force Fibo Pressure ... + ); + + // + // Following Liquidity ... + bool isFLiq = + isDone && + isRejected && + iDir == tb.GetDirection() && + (isBullish + ? iBar.low < tb.trigger.lower + : iBar.high > tb.trigger.upper); + if (isFLiq && + _forceHasFLiquidity && + !tb.fLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iDir, + tb.fLiquidity, + tb.trigger.to // + ); + } + + // + // Reversal Liquidity ... + bool isRLiq = + isDone && + isRejected && + Opposit(iDir) == tb.GetDirection() && + (isBullish + ? iBar.low > tb.trigger.upper + : iBar.high < tb.trigger.lower); + if (isRLiq && + _forceHasRLiquidity && + !tb.rLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iDir, + tb.rLiquidity, + tb.trigger.to // + ); + } + + // + // Checking Conditions ... + isDone = + (!_forceHasFLiquidity + ? true + : tb.fLiquidity.IsValid()) && + (!_forceHasRLiquidity + ? true + : tb.rLiquidity.IsValid()); + if (isDone) + { + // + iBar.Clean(); + break; + } + + // + iBar.Clean(); + } + + // + // Checking Conditions ... + has = + (!_forceHasFLiquidity + ? true + : tb.fLiquidity.IsValid()) && + (!_forceHasRLiquidity + ? true + : tb.rLiquidity.IsValid()); + } + + // + // Validations ... + + // + // Validating Gap Sequence means + // Gap Bars must Follow each Other ... + if (has && + _validateGapSequence) + { + // + XOHCL iPBar; + toIDX = tb.fvg.ToIndex(); + fromIDX = tb.fvg.FromIndex(); + + // + for (int i = toIDX; i < fromIDX - 1; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + zBar.symbol, + zBar.period, + i // + ); + has = + has && + iBar.GetPreviousBar(iPBar); + has = + has && + (isBullish + ? iBar.low > iPBar.low + : iBar.high < iPBar.high); + if (!has) + { + break; + } + } + + // + iBar.Clean(); + iPBar.Clean(); + } + + // + // Validate Block Edge Breakout ... + if (has && + _validateBlockEdgeBreakout) + { + // + has = tb.fvg.ToBar(iBar); + has = + has && + (isBullish + ? (iBar.GetDown() < tb.ob.upper && + iBar.GetUp() > tb.ob.upper) + : (iBar.GetDown() < tb.ob.lower && + iBar.GetUp() > tb.ob.lower)); + + // + iBar.Clean(); + } + + // + // Filters ... + + // + // PV ... + if (has && + _filterBasedOnPV) + { + // + double iPeak = _peakBuffer[barIndex]; + double iPPeak = _peakBuffer[barIndex + 1]; + double iP2Peak = _peakBuffer[barIndex + 2]; + + // + double iPeakGolden = _peakGoldenBuffer[barIndex]; + double iPPeakGolden = _peakGoldenBuffer[barIndex + 1]; + double iP2PeakGolden = _peakGoldenBuffer[barIndex + 2]; + + // + double iVale = _valeBuffer[barIndex]; + double iPVale = _valeBuffer[barIndex + 1]; + double iP2Vale = _valeBuffer[barIndex + 2]; + + // + double iValeGolden = _valeGoldenBuffer[barIndex]; + double iPValeGolden = _valeGoldenBuffer[barIndex + 1]; + double iP2ValeGolden = _valeGoldenBuffer[barIndex + 2]; + + // + // TODO: Fix this ... + has = + has && + (isBullish + ? (tb.trigger.lower <= iVale && + tb.trigger.upper < iPeak + // || tb.trigger.lower <= iValeGolden + ) + : (tb.trigger.upper >= iPeak && + tb.trigger.lower > iVale + // || tb.trigger.upper >= iPeakGolden + )); + } + + // + // SAR ... + if (has && + _filterBasedOnSar) + { + // + double iSarState = _sarStateBuffer[barIndex]; + double iPSarState = _sarStateBuffer[barIndex + 1]; + double iP2SarState = _sarStateBuffer[barIndex + 2]; + + // + bool isSarBullish = iSarState > 0; + bool isPSarBullish = iPSarState > 0; + bool isP2SarBullish = iP2SarState > 0; + + // + bool isSarBearish = iSarState < 0; + bool isPSarBearish = iPSarState < 0; + bool isP2SarBearish = iP2SarState < 0; + + // + bool isSarSwitchedToBullish = + isSarBullish && + !isPSarBullish; + + // + bool isSarSwitchedToBearish = + isSarBearish && + !isPSarBearish; + + // + bool isSarPSwitchedToBullish = + isPSarBullish && + !isP2SarBullish; + + // + bool isSarPSwitchedToBearish = + isPSarBearish && + !isP2SarBearish; + + // + has = + has && + (isBullish + ? (isSarSwitchedToBullish || + isSarPSwitchedToBullish) + : (isSarSwitchedToBearish || + isSarPSwitchedToBearish)); + } + + // + // RSI ... + if (has && + _filterBasedOnRSI) + { + // + double rsiTrend = (_rsiOBLevel + _rsiOSLevel) / 2; + + // + double iRSI = _rsiBuffer[barIndex]; + double iPRSI = _rsiBuffer[barIndex + 1]; + double iP2RSI = _rsiBuffer[barIndex + 2]; + + // + bool isRSICrossedOverOS = + iRSI > _rsiOSLevel && + iPRSI <= _rsiOSLevel; + + // + bool isRSICrossedUnderOB = + iRSI < _rsiOBLevel && + iPRSI >= _rsiOBLevel; + + // + bool isPRSICrossedOverOS = + iPRSI > _rsiOSLevel && + iP2RSI <= _rsiOSLevel; + + // + bool isPRSICrossedUnderOB = + iPRSI < _rsiOBLevel && + iP2RSI >= _rsiOBLevel; + + // + has = + has && + (isBullish + ? (isRSICrossedOverOS || + isPRSICrossedOverOS) + : (isRSICrossedUnderOB || + isPRSICrossedUnderOB)); + } + + // + // ADX ... + if (has && + _filterBasedOnADX) + { + // + // ADX ... + double iADX = _adxBuffer[barIndex]; + double iPADX = _adxBuffer[barIndex + 1]; + double iP2ADX = _adxBuffer[barIndex + 2]; + + // + // ADX +DI ... + double iADXP = _adxpBuffer[barIndex]; + double iPADXP = _adxpBuffer[barIndex + 1]; + double iP2ADXP = _adxpBuffer[barIndex + 2]; + + // + // ADX -DI ... + double iADXN = _adxnBuffer[barIndex]; + double iPADXN = _adxnBuffer[barIndex + 1]; + double iP2ADXN = _adxnBuffer[barIndex + 2]; + + // + // Preparing Conditions ... + + // + bool isADXBullish = iADX > _adxThreshold; + bool isADXBearish = iADX < _adxThreshold; + + // + bool isPADXBullish = iPADX > _adxThreshold; + bool isPADXBearish = iPADX < _adxThreshold; + + // + bool isP2ADXBullish = iP2ADX > _adxThreshold; + bool isP2ADXBearish = iP2ADX < _adxThreshold; + + // + bool isADXSwitchedToBullish = + isADXBullish && + !isPADXBullish; + + // + bool isADXSwitchedToBearish = + isADXBearish && + !isPADXBearish; + + // + bool isPADXSwitchedToBullish = + isPADXBullish && + !isP2ADXBullish; + + // + bool isPADXSwitchedToBearish = + isPADXBearish && + !isP2ADXBearish; + + // + has = + has && + (isBullish + ? (isADXSwitchedToBullish || + isPADXSwitchedToBullish) + : (isADXSwitchedToBearish || + isPADXSwitchedToBearish)); + } + + // + // ATR ... + if (has && + _filterBasedOnATR) + { + // + fromIDX = tb.FromIndex(); + double iATRUpper = _atrUpperBuffer[fromIDX]; + double iATRLower = _atrLowerBuffer[fromIDX]; + + // + has = + has && + (isBullish + ? tb.trigger.lower < iATRLower + : tb.trigger.upper > iATRUpper); + } + + // + // TREND ... + if (has && + _filterBasedOnTrend) + { + // + double iTrendState = _trendStateBuffer[barIndex]; + double iPTrendState = _trendStateBuffer[barIndex + 1]; + + // + bool isTrendBullish = iTrendState > 0; + bool isPTrendBullish = iPTrendState > 0; + + // + bool isTrendBearish = iTrendState < 0; + bool isPTrendBearish = iPTrendState < 0; + + // + double trends[]; + int toIDX = tb.ToIndex(); + int fromIDX = tb.FromIndex(); + double iTrend = _trendBuffer[toIDX]; + for (int i = toIDX; i <= fromIDX; i++) + { + // + Add( + _trendBuffer[i], + trends // + ); + } + double trendsMin = GetMin(trends); + double trendsMax = GetMax(trends); + double trendsAVG = GetAverage(trends); + + // + bool isTrendUp = + iTrend > trendsMin && + iTrend >= trendsAVG; + + // + bool isTrendDown = + iTrend < trendsMax && + iTrend <= trendsAVG; + + // + bool isTrendSwitchedToBullish = + isTrendUp && + isTrendBullish && + !isPTrendBullish; + + // + bool isTrendSwitchedToBearish = + isTrendDown && + isTrendBearish && + !isPTrendBearish; + + // + has = + has && + (isBullish + ? isTrendSwitchedToBullish + : isTrendSwitchedToBearish); + } + + // + // DELTA ... + if (has && + _filterBasedOnDelta) + { + // + double iDelta = _deltaBuffer[barIndex]; + double iPDelta = _deltaBuffer[barIndex + 1]; + + // + bool isDeltaUp = iDelta > iPDelta; + bool isDeltaDown = iDelta < iPDelta; + + // + double iDeltaSignal = _deltaSignalBuffer[barIndex]; + double iPDeltaSignal = _deltaSignalBuffer[barIndex + 1]; + + // + bool isDeltaSignalUp = iDeltaSignal > iPDeltaSignal; + bool isDeltaSignalDown = iDeltaSignal < iPDeltaSignal; + + // + bool isDeltaSwitchedToBullish = + isDeltaUp && + isDeltaSignalUp && + iDelta > iDeltaSignal && + iPDelta < iPDeltaSignal; + + // + bool isDeltaSwitchedToBearish = + isDeltaDown && + isDeltaSignalDown && + iDelta < iDeltaSignal && + iPDelta > iPDeltaSignal; + + // + has = + has && + (isBullish + ? isDeltaSwitchedToBullish + : isDeltaSwitchedToBearish); + } + + // + // VOLUME ... + if (has && + _filterBasedOnVolume) + { + // + double iBullishVolumeSignal = _bullishVolumeSignalBuffer[barIndex]; + double iPBullishVolumeSignal = _bullishVolumeSignalBuffer[barIndex + 1]; + + // + bool isBullishVolumeSignalUp = iBullishVolumeSignal > iPBullishVolumeSignal; + bool isBullishVolumeSignalDown = iBullishVolumeSignal < iPBullishVolumeSignal; + + // + double iBearishVolumeSignal = _bearishVolumeSignalBuffer[barIndex]; + double iPBearishVolumeSignal = _bearishVolumeSignalBuffer[barIndex + 1]; + + // + bool isBearishVolumeSignalUp = iBearishVolumeSignal > iPBearishVolumeSignal; + bool isBearishVolumeSignalDown = iBearishVolumeSignal < iPBearishVolumeSignal; + + // + bool isVolumeSwitchdToBullish = + isBullishVolumeSignalUp && + !isBearishVolumeSignalUp && + iBullishVolumeSignal > iBearishVolumeSignal && + iPBullishVolumeSignal < iPBearishVolumeSignal; + + // + bool isVolumeSwitchdToBearish = + isBearishVolumeSignalUp && + !isBullishVolumeSignalUp && + iBearishVolumeSignal > iBullishVolumeSignal && + iPBearishVolumeSignal < iPBullishVolumeSignal; + + // + has = + has && + (isBullish + ? isVolumeSwitchdToBullish + : isVolumeSwitchdToBearish); + } + + // + // SIGNAL Bar ... + if (has && + _filterBasedOnSignalBar) + { + // + double iSignalOpen = _sBarOpenSBuffer[barIndex]; + double iPSignalOpen = _sBarOpenSBuffer[barIndex + 1]; + + // + double iSignalClose = _sBarCloseBuffer[barIndex]; + double iPSignalClose = _sBarCloseBuffer[barIndex + 1]; + + // + bool isSignalBarBullish = iSignalOpen < iSignalClose; + bool isPSignalBarBullish = iPSignalOpen < iPSignalClose; + + // + bool isSignalBarBearish = iSignalOpen > iSignalClose; + bool isPSignalBarBearish = iPSignalOpen > iPSignalClose; + + // + bool isSignalBarSwitchedToBullish = + isSignalBarBullish && + !isPSignalBarBullish; + + // + bool isSignalBarSwitchedToBearish = + isSignalBarBearish && + !isPSignalBarBearish; + + // + has = + has && + (isBullish + ? isSignalBarSwitchedToBullish + : isSignalBarSwitchedToBearish); + } + + // + // HK SIGNAL Bar ... + if (has && + _filterBasedOnHKSignalBar) + { + // + double iHKSignalOpen = _hkSBarOpenBuffer[barIndex]; + double iPHKSignalOpen = _hkSBarOpenBuffer[barIndex + 1]; + + // + double iHKSignalClose = _hkSBarCloseBuffer[barIndex]; + double iPHKSignalClose = _hkSBarCloseBuffer[barIndex + 1]; + + // + bool isHKSignalBarBullish = iHKSignalOpen < iHKSignalClose; + bool isPHKSignalBarBullish = iPHKSignalOpen < iPHKSignalClose; + + // + bool isHKSignalBarBearish = iHKSignalOpen > iHKSignalClose; + bool isPHKSignalBarBearish = iPHKSignalOpen > iPHKSignalClose; + + // + bool isHKSignalBarSwitchedToBullish = + isHKSignalBarBullish && + !isPHKSignalBarBullish; + + // + bool isHKSignalBarSwitchedToBearish = + isHKSignalBarBearish && + !isPHKSignalBarBearish; + + // + has = + has && + (isBullish + ? isHKSignalBarSwitchedToBullish + : isHKSignalBarSwitchedToBearish); + } + + // + // Valdating Directional Trending ... + bool _filterBasedOnDirection = false; + if (has && + _filterBasedOnDirection) + { + // + iBar.Clean(); + fromIDX = tb.FromIndex(); + int loopbackForValidating = 30; + for (int i = fromIDX; i < fromIDX + loopbackForValidating; i++) + { + // + // Initialize iBar ... + iBar.Clean(); + has = iBar.Init( + symbol, + period, + i // + ); + + // + has = + has && + (isBullish + ? iBar.high < tb.trigger.upper + : iBar.low > tb.trigger.lower); + if (!has) + { + break; + } + } + + // + // Update Trigger Block ... + if (has) + { + tb.trigger.from = iBar.time; + } + + // + iBar.Clean(); + } + + // + // Preparing Signal ... + if (has) + { + // + // CArrayObj *tbObjects = new CArrayObj(); + // DrawTriggerBlock( + // tb, + // drawer, + // tbObjects, + // NULL // + // ); + + // + double targets[]; + for (int i = 1; i <= _r2r; i++) + { + // + Add( + (double)i, + targets // + ); + } + + // + double iATR = 0; + if (barIndex > 0 && + barIndex < ArraySize(_atrBuffer)) + { + iATR = _atrBuffer[barIndex]; + } + double slAdditional = _slAtrMultiplier * iATR; + + // + has = ToSignal( + tb.trigger, + tb.signal, + targets, + slAdditional // + ); + } + + // + result = has; + + // + return result; +} diff --git a/Libraries/x-saherelm.x121.xcatb.lib.mq5 b/Documents/BKP/XCAEA_BKP/x-saherelm.x121.xcatb.lib.mq5 similarity index 78% rename from Libraries/x-saherelm.x121.xcatb.lib.mq5 rename to Documents/BKP/XCAEA_BKP/x-saherelm.x121.xcatb.lib.mq5 index 21b49c43..6c79b664 100644 --- a/Libraries/x-saherelm.x121.xcatb.lib.mq5 +++ b/Documents/BKP/XCAEA_BKP/x-saherelm.x121.xcatb.lib.mq5 @@ -145,10 +145,13 @@ struct XTriggerBlockValidationRules // Props ... bool forceHasSwing; // Force Block to Has Propper Swing ... bool forceOBBarType; // Force Order Block to Has InDirectional Bars ... + int minRequiredOBBar; // Min Required OB Bar ... bool forceFVGBarType; // Force Fair Value Gaps Bars Type ... double maxAllowedRange; // Max Allowed Order Block Range ... + double minAllowedRange; // Min Allowed Order Block Range ... bool forceHasFLiquidity; // Force Order Block To Has Reversal Liquidity ... bool forceHasRLiquidity; // Force Order Block to Has Following Liquidity ... + int liquidityLoopback; // Liquidity Detection Loopback ... bool validateGapSequence; // Validate Fair Value Gaps Bar Sequences ... bool validateBlockEdgeBreakout; // Validate Order Block Edge Breakeout ... @@ -168,6 +171,9 @@ struct XTriggerBlockValidationRules { // maxAllowedRange = 0; + minAllowedRange = 0; + minRequiredOBBar = 0; + liquidityLoopback = 0; forceHasSwing = false; forceOBBarType = false; forceFVGBarType = false; @@ -198,6 +204,9 @@ struct XTriggerBlockFilters bool filterBasedOnSignalBar; // Filter Based on Signal Bar ... bool filterBasedOnHKSignalBar; // Filter Based On HK Signal Bar ... + // + int bosLoopback; // PV Based Filtering BOS Lookup ... + // // Constructor(s) ... XTriggerBlockFilters() @@ -224,6 +233,9 @@ struct XTriggerBlockFilters filterBasedOnSignalBar = false; filterBasedOnHKSignalBar = false; + // + bosLoopback = 0; + // ZeroMemory(this); } @@ -232,7 +244,20 @@ struct XTriggerBlockFilters // // Extensions ... -// +/** + * Detect Trigger Block ... + * + * @param helper: XCX121XCatbHelper instance pointer ... + * @param barAnalyser: XCBarAnalyser instance pointer ... + * @param triggerBlock: XTriggerBlock Refrence, holds Detected Trigger Block ... + * @param conditions: X121XCatbConditions Refrence, holds Trigger Block Conditions ... + * @param validations: XTriggerBlockValidationRules Refrence, Provides Trigger Block Validation Rules ... + * @param filters: XTriggerBlockFilters Refrence, Provides Trigger Block Filters ... + * @param barIndex: int, Bar Index ... + * @param loopback: int, Loopback for Conditions reading ... + * + * @return ( bool ) + */ bool DetectTriggerBlock1( XCX121XCatbHelper *helper, XCBarAnalyser *barAnalyser, @@ -346,8 +371,47 @@ bool DetectTriggerBlock1( // triggerBlock.trigger = triggerBlock.ob; triggerBlock.trigger.type = XTriggerBlockToken; + + // + // Update Upper and Lower ... + int toIDX = triggerBlock.ob.ToIndex(); + int fromIDX = triggerBlock.ob.FromIndex(); + + // + iBar.Clean(); + result = iBar.Init( + symbol, + period, + toIDX // + ); + if (result) + { + // + double iLL = iBar.FindLowest(fromIDX - toIDX, MODE_LOW); + double iHH = iBar.FindHighest(fromIDX - toIDX, MODE_HIGH); + + // + triggerBlock.trigger.upper = MathMax(iHH, triggerBlock.trigger.upper); + triggerBlock.trigger.lower = MathMin(iLL, triggerBlock.trigger.lower); + } + + // + iBar.Clean(); } + // + // TODO: Remove this ... + // Temparory Testing Configs ... + // validations.maxAllowedRange = 200; + // validations.forceHasSwing = true; + // validations.forceFVGBarType = true; + // validations.forceOBBarType = true; + // validations.validateGapSequence = true; + // validations.validateBlockEdgeBreakout = true; + // validations.liquidityLoopback = 144; + // validations.forceHasFLiquidity = true; + // validations.forceHasRLiquidity = true; + // // Apply Validations ... if (result) @@ -370,6 +434,11 @@ bool DetectTriggerBlock1( } } + // + // TODO: Remove this ... + filters.bosLoopback = 30; + filters.filterBasedOnPV = true; + // // Apply Filtering ... if (result) @@ -398,17 +467,18 @@ bool DetectTriggerBlock1( result && triggerBlock.IsValid(); + // + // Preparing Signal ... + if (result) + { // - // Preparing Signal ... - if (result) { - // - - } + } // // Cleanup Resources ... // + iBar.Clean(); zBar.Clean(); cBar.Clean(); @@ -422,7 +492,19 @@ bool DetectTriggerBlock1( return result; } -// +/** + * Validate a Trigger Block ... + * + * @param helper: XCX121XCatbHelper instance pointer ... + * @param barAnalyser: XCBarAnalyser instance pointer ... + * @param triggerBlock: XTriggerBlock Refrence, Trigger Block ... + * @param conditions: X121XCatbConditions Refrence, Trigger Block Conditions ... + * @param validations: XTriggerBlockValidationRules Refrence, Provides Trigger Block Validation Rules ... + * @param barIndex: int, Bar Index ... + * @param loopback: int, Loopback for Conditions reading ... + * + * @return ( bool ) + */ bool ValidateTriggerBlock( XCX121XCatbHelper *helper, XCBarAnalyser *barAnalyser, @@ -480,9 +562,389 @@ bool ValidateTriggerBlock( int p3IDX = p2IDX + 1; int p4IDX = p3IDX + 1; + // + XOHCL iBar; + int count = 0; + int toIDX = -1; + int fromIDX = -1; + bool has = false; + bool isBullish = triggerBlock.IsBullish(); + bool isBearish = triggerBlock.IsBearish(); + double points = GetPoints(triggerBlock.ob.symbol); + ENUM_X_DIRECTION iDir = triggerBlock.GetDirection(); + // // Checking Conditions ... + // + // Range Validation ... + + // + // Max Allowed OB Range ... + if (result && + validations.maxAllowedRange > 0) + { + // + double iRange = triggerBlock.ob.GetRange(); + result = iRange <= (validations.maxAllowedRange * points); + } + + // + // Min Allowed OB Range ... + if (result && + validations.minAllowedRange > 0) + { + // + double iRange = triggerBlock.ob.GetRange(); + result = iRange >= (validations.maxAllowedRange * points); + } + + // + // Has Swing ... + if (result && + validations.forceHasSwing) + { + // + bool isSwing = false; + toIDX = triggerBlock.ToIndex(); + fromIDX = triggerBlock.FromIndex(); + ENUM_X_DIRECTION swingDir = X_DIRECTION_NONE; + for (int i = toIDX; i <= fromIDX; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + isSwing = + has && + barAnalyser + .IsSimpleSwing( + iBar, + swingDir // + ); + if (isSwing && + swingDir == iDir) + { + break; + } + + // + iBar.Clean(); + } + + // + result = + isSwing && + iBar.IsValid() && + swingDir == iDir; + if (result) + { + // + // Initialize Swing Bar ... + result = triggerBlock + .swingBar + .Init( + iBar.symbol, + iBar.period, + iBar.Index() + 2 // + ); + } + + // + iBar.Clean(); + } + + // + // Force FVG Bar Types ... + if (result && + validations.forceFVGBarType) + { + // + toIDX = triggerBlock.fvg.ToIndex(); + fromIDX = triggerBlock.fvg.FromIndex(); + for (int i = toIDX; i < fromIDX; i++) + { + // + // Initialize iBar ... + result = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + result = + result && + iDir == iBar.GetDirection(); + + // + iBar.Clean(); + + // + if (!result) + { + break; + } + } + + // + iBar.Clean(); + } + + // + // Force OB Start By InDirectional Bars ... + if (result && + validations.forceOBBarType) + { + // + count = 0; + fromIDX = triggerBlock.fvg.FromIndex() + 1; + int sIDX = fromIDX; + has = true; + while (has) + { + // + // Initialize iBar .. + has = iBar.Init( + conditions.symbol, + conditions.period, + fromIDX // + ); + has = has && + iDir == Opposit(iBar.GetDirection()); + if (has) + { + count++; + } + + // + fromIDX++; + } + + // + int required = + validations.minRequiredOBBar > 0 + ? validations.minRequiredOBBar + : 1; + + // + result = count >= required; + + // + // Update Trigger Block Box based on OB Bar Types ... + if (result) + { + // + result = iBar.Init( + conditions.symbol, + conditions.period, + sIDX // + ); + if (result) + { + // + datetime iFrom = GetBarTime( + conditions.symbol, + conditions.period, + sIDX + count // + ); + double iLL = iBar.FindLowest(count, MODE_LOW); + double iHH = iBar.FindHighest(count, MODE_HIGH); + + // + triggerBlock.trigger.from = iFrom; + triggerBlock.trigger.upper = MathMax(iHH, triggerBlock.trigger.upper); + triggerBlock.trigger.lower = MathMin(iLL, triggerBlock.trigger.lower); + } + } + + // + iBar.Clean(); + } + + // + // Force Fair Value Gap to Following Sequence ... + if (result && + validations.validateGapSequence) + { + // + XOHCL iPBar; + toIDX = triggerBlock.fvg.ToIndex(); + fromIDX = triggerBlock.fvg.FromIndex() - 1; + for (int i = toIDX; i < fromIDX; i++) + { + // + result = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + result = + result && + iBar.GetPreviousBar(iPBar); + result = + result && + (isBullish + ? iBar.low > iPBar.low + : iBar.high < iPBar.high); + if (!result) + { + break; + } + + // + iBar.Clean(); + iPBar.Clean(); + } + + // + iBar.Clean(); + iPBar.Clean(); + } + + // + // Validate OB Edge Breakeout Using Gaps End Bar ... + if (result && + validations.validateBlockEdgeBreakout) + { + // + // Initialize Gap End Bar ... + toIDX = triggerBlock.fvg.ToIndex(); + result = iBar.Init( + conditions.symbol, + conditions.period, + toIDX // + ); + + // + result = + result && + (isBullish + ? iBar.open < triggerBlock.ob.upper && + iBar.close > triggerBlock.ob.upper + : iBar.open > triggerBlock.ob.lower && + iBar.close < triggerBlock.ob.lower); + + // + // Here we Can Apply Edge Breakout Using Fibo ... + + // + iBar.Clean(); + } + + // + // Force Block to Has Liquidity ... + if (result && + validations.liquidityLoopback > 0 && + (validations.forceHasFLiquidity || + validations.forceHasRLiquidity)) + { + // + toIDX = triggerBlock.ToIndex(); + fromIDX = triggerBlock.FromIndex(); + ENUM_X_DIRECTION iLiqDir = X_DIRECTION_NONE; + for (int i = toIDX; i < fromIDX + validations.liquidityLoopback; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + has = + has && + barAnalyser + .IsRejected( + iBar, + iLiqDir, + false, // Force Bar Type ... + true // Force Fibo Pressure ... + ); + + // + bool isFLiq = + has && + iLiqDir == iDir; + if (isFLiq && + validations.forceHasFLiquidity && + !triggerBlock.fLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iLiqDir, + triggerBlock.fLiquidity, + triggerBlock.trigger.to // + ); + } + + // + bool isRLiq = + has && + iLiqDir == Opposit(iDir); + if (isRLiq && + validations.forceHasRLiquidity && + !triggerBlock.rLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iLiqDir, + triggerBlock.rLiquidity, + triggerBlock.trigger.to // + ); + } + + // + // Here We Can Apply Liquidity Validations ... + ValidateTriggerBlockLiquidities( + helper, + barAnalyser, + triggerBlock, + conditions, + validations // + ); + + // + // Check Liquidities ... + has = (!validations.forceHasFLiquidity + ? true + : triggerBlock.fLiquidity.IsValid()) && + (!validations.forceHasRLiquidity + ? true + : triggerBlock.rLiquidity.IsValid()); + + // + iBar.Clean(); + + // + if (has) + { + break; + } + } + + // + // Check Result ... + result = (!validations.forceHasFLiquidity + ? true + : triggerBlock.fLiquidity.IsValid()) && + (!validations.forceHasRLiquidity + ? true + : triggerBlock.rLiquidity.IsValid()); + + // + iBar.Clean(); + } + + // + if (!result) + { + triggerBlock.Clean(); + } + // // Summarize result ... result = triggerBlock.IsValid(); @@ -490,17 +952,34 @@ bool ValidateTriggerBlock( // // Cleanup Resources ... + // + iBar.Clean(); + // if (!result) { + // conditions.Clean(); + triggerBlock.Clean(); } // return result; } -// +/** + * Filter a Trigger Block ... + * + * @param helper: XCX121XCatbHelper instance pointer ... + * @param barAnalyser: XCBarAnalyser instance pointer ... + * @param triggerBlock: XTriggerBlock Refrence, Trigger Block ... + * @param conditions: X121XCatbConditions Refrence, Trigger Block Conditions ... + * @param filters: XTriggerBlockFilters Refrence, Provides Trigger Block Filters ... + * @param barIndex: int, Bar Index ... + * @param loopback: int, Loopback for Conditions reading ... + * + * @return ( bool ) + */ bool FilterTriggerBlock( XCX121XCatbHelper *helper, XCBarAnalyser *barAnalyser, @@ -558,9 +1037,87 @@ bool FilterTriggerBlock( int p3IDX = p2IDX + 1; int p4IDX = p3IDX + 1; + // + XOHCL iBar; + int toIDX = -1; + int fromIDX = -1; + bool has = false; + bool isBullish = triggerBlock.IsBullish(); + bool isBearish = triggerBlock.IsBearish(); + double points = GetPoints(triggerBlock.ob.symbol); + ENUM_X_DIRECTION iDir = triggerBlock.GetDirection(); + // // Checking Conditions ... + // + // Filter Based On PV ... + if (result && + filters.filterBasedOnPV) + { + // + // For PV Filtering ... + + // + // Detect Bos ... + if (filters.bosLoopback > 0) + { + // + has = true; + bool isBOS = false; + bool isPeakOverLast = false; + bool isValeUnderLast = false; + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + int sIDX = fromIDX; + while (has) + { + // + double iPeak = helper.GetPeak(sIDX); + double iPPeak = helper.GetPeak(sIDX + 1); + + // + double iVale = helper.GetVale(sIDX); + double iPVale = helper.GetVale(sIDX + 1); + + // + isPeakOverLast = + iPeak > 0 && + iPeak > iPPeak; + + // + isValeUnderLast = + iVale > 0 && + iVale < iPVale; + + // + isBOS = + (isBullish && + isPeakOverLast) || + (isBearish && + isValeUnderLast); + if (isBOS) + { + break; + } + + // + sIDX++; + has = !isBOS && + sIDX < fromIDX + filters.bosLoopback; + } + + // + result = isBOS; + } + } + + // + if (!result) + { + triggerBlock.Clean(); + } + // // Summarize result ... result = triggerBlock.IsValid(); @@ -568,16 +1125,53 @@ bool FilterTriggerBlock( // // Cleanup Resources ... + // + iBar.Clean(); + // if (!result) { + // conditions.Clean(); + triggerBlock.Clean(); } // return result; } +// +void ValidateTriggerBlockLiquidities( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockValidationRules &validations // +) +{ + // + bool has = false; + + // + has = + helper != NULL && + barAnalyser != NULL && + triggerBlock.IsValid() && + (triggerBlock.fLiquidity.IsValid() || + triggerBlock.rLiquidity.IsValid()); + if (!has) + { + return; + } + + // + bool hasFLiq = triggerBlock.fLiquidity.IsValid(); + bool hasRLiq = triggerBlock.rLiquidity.IsValid(); + + // + // TODO: Implement Liquidity Validation ... +} + // bool DetectSignalZone( XCPOIDrawer *&drawer, diff --git a/Documents/BKP/XCAEA_BKP/x-saherelm.x121.xcatb.mq5 b/Documents/BKP/XCAEA_BKP/x-saherelm.x121.xcatb.mq5 new file mode 100644 index 00000000..8fb1e13d --- /dev/null +++ b/Documents/BKP/XCAEA_BKP/x-saherelm.x121.xcatb.mq5 @@ -0,0 +1,2777 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XCATB +// Description: Integrates All Requirements inside +// this indicator for analyse Markets to +// Detect Trigger Blocks ... +// +// - HK Bars; +// - ATR Band; +// - Signal Bars; +// - Parabolic Sar; +// - HK Signal Bars; +// - Peaks and Vales; +// - Peaks and Vales Goldens; +// - Trending Average Prices; +// +// - ATR; +// - RSI; +// - ADX; +// - DELTA; +// - VOLUME; +// +// 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 XCATB Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 XCATB" + +// +// Imports ... +#include "../Classes/x-saherelm.x-alert.class.mq5" +#include "../Classes/x-saherelm.x-bar.analyser.class.mq5" +#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.x121.xcatb.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; + +// +// Short ... +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Short Period + +// +// Medium ... +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period + +// +// Long ... +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period + +// +// Hind ... +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period + +// +// Select Trending Cycle ... +// this Cycle Used for All Calculations ... +input ENUM_X_MARKET_CYCLES appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + +// +// Signal ... +input group "Signal"; +input int signalR2R = 4; // Risk Reward Ratio +input bool drawSignals = true; // Draw Signal +input bool drawTriggerBlock = true; // Draw Trigger Block +input double slAtrMultiplier = 1.0; // ATR Multiplier for SL + +// +// Validating ... +input group "Validating"; +input bool forceHasSwing = false; // Force Blocks to Have Swing +input bool forceObBarType = false; // Force Block Has Reversal Bar +input bool forceOBFVGBarType = false; // Force FVG Has Same Bars +input bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +input bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +input bool validateGapSequence = false; // Validate Block's Gap Sequence +input bool validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + +// +// Filtering ... +input group "Filtering"; +input bool filterBasedOnPV = false; // Filter Based on Peak and Vale +input bool filterBasedOnSar = false; // Filter Based on Sar +input bool filterBasedOnRSI = false; // Filter Based on RSI +input bool filterBasedOnADX = false; // Filter Based on ADX +input bool filterBasedOnATR = false; // Filter Based on ATR +input bool filterBasedOnTrend = false; // Filter Based on Trend +input bool filterBasedOnDelta = false; // Filter Based on Delta +input bool filterBasedOnVolume = false; // Filter Based on Volume +input bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar +input bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +input group "Alerts"; +input string mAlertPrefix = ""; // Alert Prefix +input bool _logAlerts = false; // Log Alerts +input bool _pushAlerts = false; // Push Alerts +input bool _mailAlerts = false; // Mail Alerts +input bool _terminalAlerts = false; // Terminal Alerts + +// +// Presentation ... +input group "Presentation"; +input bool showBars = true; // Show Bars +input bool showPV = false; // Show PV +input bool showPVGolden = false; // Show PV Golden +input bool showSar = false; // Show Sar +input bool showTrend = false; // Show Trend +input bool showATRBand = false; // Show ATR Band +input bool showSignalBars = false; // Show Signal Bars +input bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars + +// +input int startCalculationForLastBars = 1500; // Calculate Last n Bars + +// +// Non Inputs ... +double sarStep = 0.02; // Step +double sarMax = 0.2; // Maximum +double rsiOBLevel = 70.0; // RSI OB Level +double rsiOSLevel = 30.0; // RSI OS Level +double adxThreshold = 25.0; // ADX Threshold +int sarArrowCode = 159; // Parabolic Sar Arrow Code +int peakArrowCode = 159; // Peaks Arrow Code +int valeArrowCode = 159; // Vales Arrow Code +double atrMultiplier = 1.5; // ATR Band Multiplier +bool showShortCycle = false; // Show Short Cycle Range +bool showMediumCycle = false; // Show Medium Cycle Range +bool showLongCycle = false; // Show Long Cycle Range +bool showHindCycle = false; // Show Hind Cycle Range +ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode +ENUM_SERIESMODE upperMode = MODE_HIGH; // Peak Method +ENUM_SERIESMODE lowerMode = MODE_LOW; // Vale Method +ENUM_X_PRICE atrUpperPriceType = X_PRICE_HIGH; // ATR Upper Zone Applied To +ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // ATR Lower Zone Applied To +ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To +ENUM_APPLIED_PRICE trendAppliedTo = PRICE_MEDIAN; // Trend Applied To +ENUM_X_MA_METHOD atrSignalMethod = X_MA_MODE_EMA; // ATR Signalling Method +ENUM_X_MA_METHOD barsSignalMethod = X_MA_MODE_EMA; // Bars Signalling Method +ENUM_X_MA_METHOD deltaSignalMethod = X_MA_MODE_EMA; // Delta Signalling Method +ENUM_X_MA_METHOD hkSignalBarMethod = X_MA_MODE_EMA; // Hiken Ashi Signal Method +ENUM_X_MA_METHOD volumeSignalMethod = X_MA_MODE_EMA; // Volume Signalling Method + +// +#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 + +// +// Buffers ... + +// +#property indicator_chart_window + +// +// Plot: 18 +// Color: 4 +// Bar: 8 +// Data Buffer: 19 +#property indicator_buffers 49 +#property indicator_plots 18 + +// +// Plot Buffers ... + +// +// SAR ... + +// +#define sarBufferIndex 0 +#define sarBufferPlotIndex 0 +double sarBuffer[]; + +// +#define sarColorBufferIndex 1 +double sarColorBuffer[]; + +// +#property indicator_label1 "SAR" +#property indicator_type1 DRAW_COLOR_ARROW +#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_width1 2 + +// +// PEAKS ... + +// +#define peakBufferIndex 2 +#define peakBufferPlotIndex 1 +double peakBuffer[]; + +// +#property indicator_label2 "PEAK" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +// VALES ... + +// +#define valeBufferIndex 3 +#define valeBufferPlotIndex 2 +double valeBuffer[]; + +// +#property indicator_label3 "VALE" +#property indicator_type3 DRAW_ARROW +#property indicator_color3 clrAqua +#property indicator_width3 1 + +// +// PEAKS Golden ... + +// +#define peakGoldenBufferIndex 4 +#define peakGoldenBufferPlotIndex 3 +double peakGoldenBuffer[]; + +// +#property indicator_label4 "PEAK Golden" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// VALE Golden ... + +// +#define valeGoldenBufferIndex 5 +#define valeGoldenBufferPlotIndex 4 +double valeGoldenBuffer[]; + +// +#property indicator_label5 "VALES Golden" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAqua +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// ATR ... + +// +// Upper ... + +// +#define atrUpperBufferIndex 6 +#define atrUpperBufferPlotIndex 5 +double atrUpperBuffer[]; + +// +#property indicator_label6 "XATRU" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrYellow +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// Lower ... + +// +#define atrLowerBufferIndex 7 +#define atrLowerBufferPlotIndex 6 +double atrLowerBuffer[]; + +// +#property indicator_label7 "XATRL" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrYellow +#property indicator_style7 STYLE_SOLID +#property indicator_width7 1 + +// +// TREND ... + +// +#define trendBufferIndex 8 +#define trendBufferPlotIndex 7 +double trendBuffer[]; + +// +#define trendColorBufferIndex 9 +double trendColorBuffer[]; + +// +#property indicator_label8 "Trend" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrAqua, clrMagenta, clrGray +#property indicator_style8 STYLE_SOLID +#property indicator_width8 2 + +// +// Signal Bar ... + +// +#define sBarOpenBufferIndex 10 +double sBarOpenBuffer[]; + +// +#define sBarHighBufferIndex 11 +double sBarHighBuffer[]; + +// +#define sBarLowBufferIndex 12 +double sBarLowBuffer[]; + +// +#define sBarCloseBufferIndex 13 +double sBarCloseBuffer[]; + +// +#define sBarColorBufferIndex 14 +double sBarColorBuffer[]; + +// +#define sBarBufferPlotIndex 8 +#property indicator_label9 "XSGB Open;XSGB High;XSGB Low;XSGB Close" +#property indicator_type9 DRAW_COLOR_CANDLES +#property indicator_color9 CLR_NONE, clrLime, clrRed + +// +// XHK SIGNAL ... + +// +#define hkSBarOpenBufferIndex 15 +double hkSBarOpenBuffer[]; + +// +#define hkSBarHighBufferIndex 16 +double hkSBarHighBuffer[]; + +// +#define hkSBarLowBufferIndex 17 +double hkSBarLowBuffer[]; + +// +#define hkSBarCloseBufferIndex 18 +double hkSBarCloseBuffer[]; + +// +#define hkSBarColorBufferIndex 19 +double hkSBarColorBuffer[]; + +// +#define hkSBarBufferPlotIndex 9 +#property indicator_label10 "XHKSGB Open;XHKSGB High;XHKSGB Low;XHKSGB Close" +#property indicator_type10 DRAW_COLOR_CANDLES +#property indicator_color10 CLR_NONE, clrAqua, clrMagenta + +// +// CYCLES Range ... + +// +// SHORT ... + +// +#define sHHBufferIndex 20 +#define sHHBufferPlotIndex 10 +double sHHBuffer[]; + +// +#property indicator_label11 "SH" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define sLLBufferIndex 21 +#define sLLBufferPlotIndex 11 +double sLLBuffer[]; + +// +#property indicator_label12 "SL" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// MEDIUM ... + +// +#define mHHBufferIndex 22 +#define mHHBufferPlotIndex 12 +double mHHBuffer[]; + +// +#property indicator_label13 "MH" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrIndigo +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define mLLBufferIndex 23 +#define mLLBufferPlotIndex 13 +double mLLBuffer[]; + +// +#property indicator_label14 "ML" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrIndigo +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +// LONG ... + +// +#define lHHBufferIndex 24 +#define lHHBufferPlotIndex 14 +double lHHBuffer[]; + +// +#property indicator_label15 "LH" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrGoldenrod +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define lLLBufferIndex 25 +#define lLLBufferPlotIndex 15 +double lLLBuffer[]; + +// +#property indicator_label16 "LL" +#property indicator_type16 DRAW_LINE +#property indicator_color16 clrGoldenrod +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +// HIND ... + +// +#define hHHBufferIndex 26 +#define hHHBufferPlotIndex 16 +double hHHBuffer[]; + +// +#property indicator_label17 "HH" +#property indicator_type17 DRAW_LINE +#property indicator_color17 clrBrown +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +#define hLLBufferIndex 27 +#define hLLBufferPlotIndex 17 +double hLLBuffer[]; + +// +#property indicator_label18 "HL" +#property indicator_type18 DRAW_LINE +#property indicator_color18 clrBrown +#property indicator_style18 STYLE_DOT +#property indicator_width18 1 + +// +// Data Buffers ... + +// +#define mLastBufferIndex 27 + +// +// SAR ... + +// +#define sarStateBufferIndex mLastBufferIndex + 1 +double sarStateBuffer[]; + +// +// TREND State ... + +// +#define trendStateBufferIndex mLastBufferIndex + 2 +double trendStateBuffer[]; + +// +// RSI ... + +// +#define rsiBufferIndex mLastBufferIndex + 3 +double rsiBuffer[]; + +// +// ADX ... + +// +#define adxBufferIndex mLastBufferIndex + 4 +double adxBuffer[]; + +// +#define adxpBufferIndex mLastBufferIndex + 5 +double adxpBuffer[]; + +// +#define adxnBufferIndex mLastBufferIndex + 6 +double adxnBuffer[]; + +// +// DELTA ... + +// +#define deltaBufferIndex mLastBufferIndex + 7 +double deltaBuffer[]; + +// +#define deltaSignalBufferIndex mLastBufferIndex + 8 +double deltaSignalBuffer[]; + +// +// VOLUMES ... + +// +#define bullishVolumeBufferIndex mLastBufferIndex + 9 +double bullishVolumeBuffer[]; + +// +#define bearishVolumeBufferIndex mLastBufferIndex + 10 +double bearishVolumeBuffer[]; + +// +#define bullishVolumeSignalBufferIndex mLastBufferIndex + 11 +double bullishVolumeSignalBuffer[]; + +// +#define bearishVolumeSignalBufferIndex mLastBufferIndex + 12 +double bearishVolumeSignalBuffer[]; + +// +// ATR ... + +// +#define atrBufferIndex mLastBufferIndex + 13 +double atrBuffer[]; + +// +#define atrUpperRawBufferIndex mLastBufferIndex + 14 +double atrUpperRawBuffer[]; + +// +#define atrLowerRawBufferIndex mLastBufferIndex + 15 +double atrLowerRawBuffer[]; + +// +// HK ... + +// +#define openHKBufferIndex mLastBufferIndex + 16 +double openHKBuffer[]; + +// +#define highHKBufferIndex mLastBufferIndex + 17 +double highHKBuffer[]; + +// +#define lowHKBufferIndex mLastBufferIndex + 18 +double lowHKBuffer[]; + +// +#define closeHKBufferIndex mLastBufferIndex + 19 +double closeHKBuffer[]; + +// +// Variables, Properties and etc ... + +// +int limit; + +// +int maxLength; + +// +int firstBarIndex; + +// +// Bars Color Variables ... +color _upColor = clrLime; +color _downColor = clrRed; +color _lineColor = clrLime; +color _bullishColor = clrLime; +color _bearishColor = clrRed; + +// +// XMarketCycle sc; +int mSCLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// XMarketCycle mc; +int mMCLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// XMarketCycle lc; +int mLCLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// XMarketCycle hc; +int mHCLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +// Applied Cycle ... +int mAppliedLength; +ENUM_TIMEFRAMES mAppliedPeriod = NULL; + +// +// Handlers ... +int atrHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int adxHandler = INVALID_HANDLE; +int trendHandler = INVALID_HANDLE; + +// +XCAlert *mAlert; +CArrayObj mObjects; +XCPOIDrawer *mDrawer; +bool mEnableAlerts = false; +XCBarAnalyser *mBarAnalyser; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + bool has = false; + + // + ReadBarStyle(); + + // + // Validate Inputs ... + has = ValidateInputs(); + if (!has) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + has = InitCycles(); + if (!has) + { + 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(); + + // + // Initial Requirements ... + has = InitRequirements(); + if (!has) + { + return INIT_FAILED; + } + + // + if (showBars) + { + ShowBars(); + } + else + { + HideBars(); + } + + // + // 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 + + // + ShowBars(); + + // + mObjects.Clear(); + + // + delete mAlert; + ZeroMemory(mAlert); + + // + delete mDrawer; + ZeroMemory(mDrawer); + + // + delete mBarAnalyser; + ZeroMemory(mBarAnalyser); + + // + // De Initialize all Handlers and etc ... + IndicatorRelease(atrHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(adxHandler); + IndicatorRelease(trendHandler); +} + +/** + * 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 ... + + // + // ATR ... + int atrCalculatedBars = BarsCalculated(atrHandler); + + // + // SAR ... + int sarCalculatedBars = BarsCalculated(sarHandler); + + // + // RSI ... + int rsiCalculatedBars = BarsCalculated(rsiHandler); + + // + // ADX ... + int adxCalculatedBars = BarsCalculated(adxHandler); + + // + // TREND ... + int trendCalculatedBars = BarsCalculated(trendHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // ATR ... + atrCalculatedBars >= maxLength && + // + // SAR ... + sarCalculatedBars >= maxLength && + // + // RSI ... + rsiCalculatedBars >= maxLength && + // + // ADX ... + adxCalculatedBars >= maxLength && + // + // TREND ... + trendCalculatedBars >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // ATR ... + int copiedAtrs = CopyBuffer(atrHandler, MAIN_LINE, 0, limit, atrBuffer); + + // + // SAR ... + int copiedSars = CopyBuffer(sarHandler, MAIN_LINE, 0, limit, sarBuffer); + + // + // RSI ... + int copiedRSIs = CopyBuffer(rsiHandler, MAIN_LINE, 0, limit, rsiBuffer); + + // + // ADX ... + int copiedADXs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer); + + // + // ADX Plus ... + int copiedADXPs = CopyBuffer(adxHandler, PLUSDI_LINE, 0, limit, adxpBuffer); + + // + // ADX Negative ... + int copiedADXNs = CopyBuffer(adxHandler, MINUSDI_LINE, 0, limit, adxnBuffer); + + // + // TREND ... + int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit, trendBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // ATR ... + copiedAtrs >= limit && + // + // SAR ... + copiedSars >= limit && + // + // RSI ... + copiedRSIs >= limit && + // + // TREND ... + copiedTrends >= 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 // + ); + } + + // + if (prev_calculated == 0) + { + // + string message = "History Finished ..."; + Print(message); + } + + // + return rates_total; +} + +// +// Custom Functions ... + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + sarMax > 0 && + sarStep > 0 && + rsiOBLevel > 0 && + rsiOSLevel > 0 && + adxThreshold > 0 && + sarMax > sarStep && + atrMultiplier > 0 && + // + IsValid(appliedCycle) && + // + IsValid(atrUpperPriceType) && + IsValid(atrLowerPriceType) && + // + // CYCLES ... + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mSCLength, mMCLength); + result = MathMax(result, mLCLength); + result = MathMax(result, mHCLength); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // Plot Buffers ... + + // + // SAR ... + + // + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_SHOW_DATA, showSar); + PlotIndexSetDouble(sarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_ARROW, sarArrowCode); + + // + ArraySetAsSeries(sarColorBuffer, true); + SetIndexBuffer(sarColorBufferIndex, sarColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(sarStateBuffer, true); + SetIndexBuffer(sarStateBufferIndex, sarStateBuffer, INDICATOR_CALCULATIONS); + + // + // PEAK / VALE ... + + // + ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE; + + // + // PEAK ... + + // + ArraySetAsSeries(peakBuffer, true); + SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode); + + // + // VALE ... + + // + ArraySetAsSeries(valeBuffer, true); + SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode); + + // + // PV GOLDEN ... + + // + ENUM_DRAW_TYPE pvGoldenDrawType = showPVGolden ? DRAW_LINE : DRAW_NONE; + + // + // PEAK Golden ... + + // + ArraySetAsSeries(peakGoldenBuffer, true); + SetIndexBuffer(peakGoldenBufferIndex, peakGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(peakGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // VALE Golden ... + + // + ArraySetAsSeries(valeGoldenBuffer, true); + SetIndexBuffer(valeGoldenBufferIndex, valeGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(valeGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // ATR Band ... + + // + // UPPER ... + ENUM_DRAW_TYPE atrUpperDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrUpperBuffer, true); + SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrUpperBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_DRAW_TYPE, atrUpperDrawType); + + // + // LOWER ... + ENUM_DRAW_TYPE atrLowerDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrLowerBuffer, true); + SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrLowerBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_DRAW_TYPE, atrLowerDrawType); + + // + // TREND ... + + // + ArraySetAsSeries(trendBuffer, true); + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetDouble(trendBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(trendColorBuffer, true); + SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(trendStateBuffer, true); + SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); + + // + // SIGNAL Bar ... + + // + // Signal Bars Color ... + ArraySetAsSeries(sBarColorBuffer, true); + SetIndexBuffer(sBarColorBufferIndex, sBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(sBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(sBarOpenBuffer, true); + SetIndexBuffer(sBarOpenBufferIndex, sBarOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(sBarHighBuffer, true); + SetIndexBuffer(sBarHighBufferIndex, sBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(sBarLowBuffer, true); + SetIndexBuffer(sBarLowBufferIndex, sBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(sBarCloseBuffer, true); + SetIndexBuffer(sBarCloseBufferIndex, sBarCloseBuffer, INDICATOR_DATA); + + // + // XHK SIGNAL Bar ... + + // + // HK Bars Color ... + ArraySetAsSeries(hkSBarColorBuffer, true); + SetIndexBuffer(hkSBarColorBufferIndex, hkSBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(hkSBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(hkSBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hkSBarOpenBuffer, true); + SetIndexBuffer(hkSBarOpenBufferIndex, hkSBarOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hkSBarHighBuffer, true); + SetIndexBuffer(hkSBarHighBufferIndex, hkSBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(hkSBarLowBuffer, true); + SetIndexBuffer(hkSBarLowBufferIndex, hkSBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(hkSBarCloseBuffer, true); + SetIndexBuffer(hkSBarCloseBufferIndex, hkSBarCloseBuffer, INDICATOR_DATA); + + // + // CYCLES ... + + // + // SHORT ... + + // + ENUM_DRAW_TYPE sDrawType = showShortCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // MEDIUM ... + + // + ENUM_DRAW_TYPE mDrawType = showMediumCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LONG ... + + // + ENUM_DRAW_TYPE lDrawType = showLongCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // HIND ... + + // + ENUM_DRAW_TYPE hDrawType = showHindCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // Data Buffers ... + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // ADX ... + + // + ArraySetAsSeries(adxBuffer, true); + SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxpBuffer, true); + SetIndexBuffer(adxpBufferIndex, adxpBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxnBuffer, true); + SetIndexBuffer(adxnBufferIndex, adxnBuffer, INDICATOR_CALCULATIONS); + + // + // DELTA ... + + // + ArraySetAsSeries(deltaBuffer, true); + SetIndexBuffer(deltaBufferIndex, deltaBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(deltaSignalBuffer, true); + SetIndexBuffer(deltaSignalBufferIndex, deltaSignalBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + + // + ArraySetAsSeries(bullishVolumeBuffer, true); + SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeBuffer, true); + SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + SetIndexBuffer(bullishVolumeSignalBufferIndex, bullishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + SetIndexBuffer(bearishVolumeSignalBufferIndex, bearishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + // ATR ... + + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrUpperRawBuffer, true); + SetIndexBuffer(atrUpperRawBufferIndex, atrUpperRawBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrLowerRawBuffer, true); + SetIndexBuffer(atrLowerRawBufferIndex, atrLowerRawBuffer, INDICATOR_CALCULATIONS); + + // + // XHK ... + + // + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_CALCULATIONS); + + // +} + +/** + * Initial Market Cycles ... + * + * @return ( bool ) + */ +bool InitCycles() +{ + // + bool result = false; + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + if (IsValid(mSCPeriod)) + { + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + if (IsValid(mMCPeriod)) + { + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + if (IsValid(mLCPeriod)) + { + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + if (IsValid(mHCPeriod)) + { + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + } + + // + result = mSCLength > 0 && + mMCLength > mSCLength && + mLCLength > mMCLength && + mHCLength > mLCLength; + + // + // Selecte Applied Cycle ... + if (result) + { + // + switch (appliedCycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + mAppliedLength = mSCLength; + mAppliedPeriod = mSCPeriod; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + mAppliedLength = mMCLength; + mAppliedPeriod = mMCPeriod; + break; + + // + case X_MARKET_CYCLE_LONG: + // + mAppliedLength = mLCLength; + mAppliedPeriod = mLCPeriod; + break; + + // + case X_MARKET_CYCLE_HIND: + // + mAppliedLength = mHCLength; + mAppliedPeriod = mHCPeriod; + break; + } + } + + // + return result; +} + +/** + * Initial all Indicator Requirements ... + * + * @return ( false ) + * + */ +bool InitRequirements() +{ + // + bool result = false; + + // + // Handlers ... + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMax // + ); + result = sarHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + mAppliedLength // + ); + result = atrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + mAppliedLength, + rsiAppliedTo // + ); + result = rsiHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ADX ... + adxHandler = iADX( + _Symbol, + _Period, + mAppliedLength // + ); + result = adxHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // TREND ... + trendHandler = iMA( + _Symbol, + _Period, + mAppliedLength, + 0, + trendMode, + trendAppliedTo // + ); + result = trendHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Initial Class Instances ... + + // + mDrawer = new XCPOIDrawer(); + mBarAnalyser = new XCBarAnalyser(); + + // + // Initialize and Configure Alert ... + mAlert = new XCAlert(); + mEnableAlerts = + _logAlerts || + _pushAlerts || + _mailAlerts || + _terminalAlerts; + string mPrefix = ShortName + + (!IsValid(mAlertPrefix) + ? "" + : "[" + mAlertPrefix + "]"); + mAlert.SetPrefix(mPrefix); + mAlert.SetLogAlerts(_logAlerts); + mAlert.SetMailAlerts(_mailAlerts); + mAlert.SetPushAlerts(_pushAlerts); + mAlert.SetEnableAlerts(mEnableAlerts); + mAlert.SetTerminalAlerts(_terminalAlerts); + + // + return result; +} + +/** + * Calculate Custom Buffers ... + * + * @param barIndex: 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 barIndex, + 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; + if (barsLimit == 0) + { + // + barsLimit = ratesTotal; + firstBarIndex = barsLimit - 1; + } + else + { + firstBarIndex = startCalculationForLastBars; + } + + // + // bool canCalculate = true; + bool canCalculate = + barIndex <= barsLimit; + if (canCalculate) + { + // + // Calculate Values ... + CalculateValues( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + } + else + { + FillBuffersZero(barIndex); + } +} + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + sarColorBuffer[barIndex] = hideColorIDX; + trendColorBuffer[barIndex] = hideColorIDX; + + // + atrUpperRawBuffer[barIndex] = emptyValue; + atrLowerRawBuffer[barIndex] = emptyValue; +} + +// +// Custom Handlers ... + +/** + * Calculate Values ... + * + * @param barIndex: 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 barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + int maxBarIndex = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : ratesTotal; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + // Cycle Ranges ... + CalculateCycleRanges( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // PV ... + CalculatePV( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SAR ... + CalculateSAR( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SBAR ... + CalculateSBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // HKBAR ... + CalculateHKBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // DELTA ... + CalculateDelta( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // TREND ... + CalculateTrend( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // VOLUME ... + CalculateVolume( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // ATR Band ... + CalculateATRBand( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Try To Detect Trigger Block ... + + // + // Prevent Calculation ... + if (maxBarIndex - barIndex < maxLength) + { + return; + } + + // + XTriggerBlock tb; + bool has = DetectTriggerBlock( + // + _Symbol, + _Period, + // + tb, + // + mBarAnalyser, + // + // Required Buffers ... + atrBuffer, + rsiBuffer, + adxBuffer, + adxpBuffer, + adxnBuffer, + peakBuffer, + valeBuffer, + deltaBuffer, + sarBuffer, + sarStateBuffer, + trendBuffer, + trendStateBuffer, + atrUpperBuffer, + atrLowerBuffer, + sBarOpenBuffer, + sBarCloseBuffer, + hkSBarOpenBuffer, + hkSBarCloseBuffer, + peakGoldenBuffer, + valeGoldenBuffer, + deltaSignalBuffer, + bullishVolumeSignalBuffer, + bearishVolumeSignalBuffer, + // + barIndex, + // + // Signalling ... + signalR2R, + slAtrMultiplier, + // + // Configs ... + rsiOBLevel, + rsiOSLevel, + adxThreshold, + // + // Validators ... + forceObBarType, + forceOBFVGBarType, + forceHasSwing, + forceHasFLiquidity, + forceHasRLiquidity, + validateGapSequence, + validateBlockEdgeBreakout, + // + // Filters ... + filterBasedOnPV, + filterBasedOnSar, + filterBasedOnRSI, + filterBasedOnADX, + filterBasedOnATR, + filterBasedOnTrend, + filterBasedOnDelta, + filterBasedOnVolume, + filterBasedOnSignalBar, + filterBasedOnHKSignalBar // + ); + if (has) + { + // + // Draw ... + if (drawTriggerBlock) + { + // + has = DrawTriggerBlock( + tb, + mDrawer, + mObjects, + NULL, + drawSignals // + ); + } + + // + // Alert ... + bool canAlert = + mEnableAlerts && + prevCalculated > 0; + bool canLogOnly = + mEnableAlerts && + prevCalculated == 0; + if (has && + (canAlert || + canLogOnly)) + { + // + string message = + tb.trigger.symbol + "," + + ToString(tb.trigger.period) + "> " + + ToString(tb.trigger.dir) + + " Zone Detected at: " + ToString(tb.trigger.to); + + // + if (canLogOnly) + { + mAlert.LogAlert(message); + } + else if (canAlert) + { + mAlert.SendAlert(message); + } + } + } +} + +// +void CalculateCycleRanges( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // SHORT ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_SHORT, + sHHBuffer, + sLLBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_MEDIUM, + mHHBuffer, + mLLBuffer // + ); + + // + // LONG ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_LONG, + lHHBuffer, + lLLBuffer // + ); + + // + // HIND ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_HIND, + hHHBuffer, + hLLBuffer // + ); +} + +// +void CalculatePV( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iSHH = sHHBuffer[barIndex]; + double iSLL = sLLBuffer[barIndex]; + + // + double iMHH = mHHBuffer[barIndex]; + double iMLL = mLLBuffer[barIndex]; + + // + double iLHH = lHHBuffer[barIndex]; + double iLLL = lLLBuffer[barIndex]; + + // + double iHHH = hHHBuffer[barIndex]; + double iHLL = hLLBuffer[barIndex]; + + // + // Calculate VALE ... + bool isVale = iSLL == iMLL && + iMLL == iLLL && + iLLL == iHLL; + double iPVale = + isFirstBar + ? emptyValue + : valeBuffer[lastBarIndex]; + double iVale = + isVale + ? iSLL + : iPVale; + valeBuffer[barIndex] = iVale; + + // + // Calculate PEAK ... + bool isPeak = iSHH == iMHH && + iMHH == iLHH && + iLHH == iHHH; + double iPPeak = + isFirstBar + ? emptyValue + : peakBuffer[lastBarIndex]; + double iPeak = + isPeak + ? iSHH + : iPPeak; + peakBuffer[barIndex] = iPeak; + + // + // GOLDEN ... + + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + barIndex // + ); + + // + // Calculate PV Gold ... + double lastPeakGold = + isFirstBar + ? emptyValue + : peakGoldenBuffer[lastBarIndex]; + double lastValeGold = + isFirstBar + ? emptyValue + : valeGoldenBuffer[lastBarIndex]; + double iPeakGold = lastPeakGold; + double iValeGold = lastValeGold; + if (isInited) + { + // + iPeakGold = iBar.FindHighest(mHCLength, MODE_CLOSE); + if (iPeakGold == 0) + { + iPeakGold = lastPeakGold; + } + + // + iValeGold = iBar.FindLowest(mHCLength, MODE_CLOSE); + if (iValeGold == 0) + { + iValeGold = lastValeGold; + } + } + else + { + // + iPeakGold = lastPeakGold; + iValeGold = lastValeGold; + } + + // + peakGoldenBuffer[barIndex] = iPeakGold; + valeGoldenBuffer[barIndex] = iValeGold; + + // + iBar.Clean(); +} + +// +void CalculateSAR( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = low[barIndex]; + double iSar = sarBuffer[barIndex]; + + // + bool isBullish = iSar < iLow; + bool isBearish = iSar > iHigh; + + // + double iSarState = isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iSarColor = iSarState > 0 + ? bullishColorIDX + : iSarState < 0 + ? bearishColorIDX + : neuturalColorIDX; + sarStateBuffer[barIndex] = iSarState; + sarColorBuffer[barIndex] = showSar + ? iSarColor + : hideColorIDX; +} + +// +void CalculateSBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + open, + sBarOpenBuffer, + barsSignalMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + close, + sBarCloseBuffer, + barsSignalMethod // + ); + + // + double min = MathMin(sBarCloseBuffer[barIndex], sBarOpenBuffer[barIndex]); + double max = MathMin(sBarCloseBuffer[barIndex], sBarOpenBuffer[barIndex]); + + // + sBarLowBuffer[barIndex] = min; + sBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iSignalColorValue = + sBarOpenBuffer[barIndex] < sBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + sBarColorBuffer[barIndex] = + showSignalBars + ? iSignalColorValue + : hideColorIDX; +} + +// +void CalculateHKBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double lastHKOpen = + isFirstBar + ? emptyValue + : openHKBuffer[lastBarIndex]; + double lastHKClose = + isFirstBar + ? emptyValue + : closeHKBuffer[lastBarIndex]; + + // + double iHKOpenValue = (lastHKOpen + lastHKClose) / 2; + double iHKCloseValue = (open[barIndex] + high[barIndex] + close[barIndex] + low[barIndex]) / 4; + double iHKHighValue = MathMax(high[barIndex], MathMax(iHKOpenValue, iHKCloseValue)); + double iHKLowValue = MathMin(low[barIndex], MathMin(iHKOpenValue, iHKCloseValue)); + + // + // Raw HK Buffers ... + openHKBuffer[barIndex] = iHKOpenValue; + highHKBuffer[barIndex] = iHKHighValue; + lowHKBuffer[barIndex] = iHKLowValue; + closeHKBuffer[barIndex] = iHKCloseValue; + + // + // XHK Signal ... + + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + openHKBuffer, + hkSBarOpenBuffer, + hkSignalBarMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + closeHKBuffer, + hkSBarCloseBuffer, + hkSignalBarMethod // + ); + + // + double min = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + double max = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + + // + hkSBarLowBuffer[barIndex] = min; + hkSBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iHKSignalColorValue = + hkSBarOpenBuffer[barIndex] < hkSBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + hkSBarColorBuffer[barIndex] = + showHKSignalBars + ? iHKSignalColorValue + : hideColorIDX; +} + +// +void CalculateDelta( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + // DELTA ... + double lastDelta = + isFirstBar + ? emptyValue + : deltaBuffer[lastBarIndex]; + double iAppliedVolume = + isBullish + ? iVolume + : -1 * iVolume; + double iDelta = + lastDelta + iAppliedVolume; + deltaBuffer[barIndex] = iDelta; + + // + // Calculate Delta Signal ... + int deltaSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + deltaBuffer, + deltaSignalBuffer, + deltaSignalMethod // + ); +} + +// +void CalculateTrend( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = high[barIndex]; + double iClose = close[barIndex]; + double iTrend = trendBuffer[barIndex]; + + // + bool isBullish = iTrend < iLow; + bool isBearish = iTrend > iHigh; + + // + double iTrendState = + isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iTrendColor = + iTrendState > 0 + ? bullishColorIDX + : iTrendState < 0 + ? bearishColorIDX + : neuturalColorIDX; + trendStateBuffer[barIndex] = iTrendState; + trendColorBuffer[barIndex] = showTrend + ? iTrendColor + : hideColorIDX; +} + +// +void CalculateVolume( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + double iBullishVolume = emptyValue; + double iBearishVolume = emptyValue; + if (isBullish) + { + iBullishVolume = iVolume; + } + else if (isBearish) + { + iBearishVolume = iVolume; + } + else + { + // + double iHalfVolume = iVolume / 2; + + // + iBullishVolume = iHalfVolume; + iBearishVolume = iHalfVolume; + } + bullishVolumeBuffer[barIndex] = iBullishVolume; + bearishVolumeBuffer[barIndex] = iBearishVolume; + + // + // Calculate Volume Signals ... + + // + int bullishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bullishVolumeBuffer, + bullishVolumeSignalBuffer, + volumeSignalMethod // + ); + + // + int bearishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bearishVolumeBuffer, + bearishVolumeSignalBuffer, + volumeSignalMethod // + ); +} + +// +void CalculateATRBand( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iATR = atrBuffer[barIndex]; + double iAppliedATR = atrMultiplier * iATR; + double iATRUpperPrice = GetAppliedPrice( + atrUpperPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRLowerPrice = GetAppliedPrice( + atrLowerPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRUpper = iATRUpperPrice + iAppliedATR; + double iATRLower = iATRLowerPrice - iAppliedATR; + atrUpperRawBuffer[barIndex] = iATRUpper; + atrLowerRawBuffer[barIndex] = iATRLower; + + // + bool canSignalATR = IsValid(atrSignalMethod); + if (canSignalATR) + { + // + // Upper ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrUpperRawBuffer, + atrUpperBuffer, + atrSignalMethod // + ); + + // + // Lower ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrLowerRawBuffer, + atrLowerBuffer, + atrSignalMethod // + ); + } + else + { + // + atrUpperBuffer[barIndex] = iATRUpper; + atrLowerBuffer[barIndex] = iATRLower; + } +} + +/** + * Calculate Specified Market Cycle Info ... + * + * @param barIndex: Integer, Bar Index ... + * @param cycle: ENUM_X_MARKET_CYCLES member, Specified Cycle ... + * @param hhBuffer: Highest High Buffer Reference ... + * @param llBuffer: Lowest Low Buffer Reference ... + */ +void CalculateCycle( + int barIndex, + ENUM_X_MARKET_CYCLES cycle, + double &hhBuffer[], + double &llBuffer[] // +) +{ + // + XOHCL bar; + bool isBarInited = bar.Init( + _Symbol, + _Period, + barIndex + // + ); + if (!isBarInited) + { + return; + } + + // + int mLength = 0; + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + mLength = mSCLength; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + mLength = mMCLength; + break; + + // + case X_MARKET_CYCLE_LONG: + mLength = mLCLength; + break; + + // + case X_MARKET_CYCLE_HIND: + mLength = mHCLength; + break; + } + + // + if (mLength == 0) + { + return; + } + + // + // Find Highest High ... + double hhValue = bar.FindHighest( + mLength, + upperMode // + ); + hhBuffer[barIndex] = hhValue; + + // + // Find Lowest Low ... + double llValue = bar.FindLowest( + mLength, + lowerMode // + ); + llBuffer[barIndex] = llValue; + + // + bar.Clean(); +} + +// +void ReadBarStyle() +{ + // + long chartId = ChartID(); + + // + _upColor = GetChartUpColor(chartId); + _downColor = GetChartDownColor(chartId); + _lineColor = GetChartLineColor(chartId); + _bullishColor = GetChartBullishColor(chartId); + _bearishColor = GetChartBearishColor(chartId); +} + +// +void ShowBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(_upColor, chartId); + SetChartDownColor(_downColor, chartId); + SetChartLineColor(_lineColor, chartId); + SetChartBullishColor(_bullishColor, chartId); + SetChartBearishColor(_bearishColor, chartId); +} + +// +void HideBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(CLR_NONE, chartId); + SetChartDownColor(CLR_NONE, chartId); + SetChartLineColor(CLR_NONE, chartId); + SetChartBullishColor(CLR_NONE, chartId); + SetChartBearishColor(CLR_NONE, chartId); +} + +// \ No newline at end of file diff --git a/Experts/x-saherelm.xcaea.ea.mq5 b/Documents/BKP/XCAEA_BKP/x-saherelm.xcaea.ea.mq5 similarity index 100% rename from Experts/x-saherelm.xcaea.ea.mq5 rename to Documents/BKP/XCAEA_BKP/x-saherelm.xcaea.ea.mq5 diff --git a/Helpers/x-saherelm.x121.x3ma.helper.mq5 b/Documents/Helpers/x-saherelm.x121.x3ma.helper.mq5 similarity index 100% rename from Helpers/x-saherelm.x121.x3ma.helper.mq5 rename to Documents/Helpers/x-saherelm.x121.x3ma.helper.mq5 diff --git a/Helpers/x-saherelm.x121.xca.helper.mq5 b/Documents/Helpers/x-saherelm.x121.xca.helper.mq5 similarity index 100% rename from Helpers/x-saherelm.x121.xca.helper.mq5 rename to Documents/Helpers/x-saherelm.x121.xca.helper.mq5 diff --git a/Documents/Helpers/x-saherelm.x121.xcatb.helper.mq5 b/Documents/Helpers/x-saherelm.x121.xcatb.helper.mq5 new file mode 100644 index 00000000..6bfab823 --- /dev/null +++ b/Documents/Helpers/x-saherelm.x121.xcatb.helper.mq5 @@ -0,0 +1,5548 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCX121XCatbHelper +// 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" +#include "../Libraries/x-saherelm.x-poi.lib.mq5" + +// +// Definitions ... + +// +// Buffers ... +enum ENUM_X121_XCATB_BUFFERS +{ + X121_XCATB_SAR_LINE = 0, + X121_XCATB_SAR_STATE_LINE = 28, + X121_XCATB_PEAK_LINE = 2, + X121_XCATB_VALE_LINE = 3, + X121_XCATB_PEAK_GOLDEN_LINE = 4, + X121_XCATB_VALE_GOLDEN_LINE = 5, + X121_XCATB_ATR_BAND_UPPER_LINE = 6, + X121_XCATB_ATR_BAND_LOWER_LINE = 7, + X121_XCATB_TREND_LINE = 8, + X121_XCATB_TREND_STATE_LINE = 29, + X121_XCATB_SBAR_O_LINE = 10, + X121_XCATB_SBAR_H_LINE = 11, + X121_XCATB_SBAR_L_LINE = 12, + X121_XCATB_SBAR_C_LINE = 13, + X121_XCATB_HK_SBAR_O_LINE = 15, + X121_XCATB_HK_SBAR_H_LINE = 16, + X121_XCATB_HK_SBAR_L_LINE = 17, + X121_XCATB_HK_SBAR_C_LINE = 18, + X121_XCATB_S_HH_LINE = 20, + X121_XCATB_S_LL_LINE = 21, + X121_XCATB_M_HH_LINE = 22, + X121_XCATB_M_LL_LINE = 23, + X121_XCATB_L_HH_LINE = 24, + X121_XCATB_L_LL_LINE = 25, + X121_XCATB_H_HH_LINE = 26, + X121_XCATB_H_LL_LINE = 27, + X121_XCATB_RSI_LINE = 30, + X121_XCATB_ADX_LINE = 31, + X121_XCATB_ADXP_LINE = 32, + X121_XCATB_ADXN_LINE = 33, + X121_XCATB_DELTA_LINE = 34, + X121_XCATB_DELTA_SIGNAL_LINE = 35, + X121_XCATB_VOLUME_BULLISH_LINE = 36, + X121_XCATB_VOLUME_BEARISH_LINE = 37, + X121_XCATB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE = 38, + X121_XCATB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE = 39, + X121_XCATB_ATR_LINE = 40, + X121_XCATB_ATR_BAND_RAW_UPPER_LINE = 41, + X121_XCATB_ATR_BAND_RAW_LOWER_LINE = 42, + X121_XCATB_HK_BAR_O_LINE = 43, + X121_XCATB_HK_BAR_H_LINE = 44, + X121_XCATB_HK_BAR_L_LINE = 45, + X121_XCATB_HK_BAR_C_LINE = 46, +}; + +// +// Input Models ... +struct X121XCatbInputs +{ + // + // Props ... + + // + // Market ... + ENUM_X_PERIOD_METHOD scMethod; // How to Find Short Period + ENUM_TIMEFRAMES scPeriod; // Short Period + ENUM_X_PERIOD_METHOD mcMethod; // How to Find Medium Period + ENUM_TIMEFRAMES mcPeriod; // Medium Period + ENUM_X_PERIOD_METHOD lcMethod; // How to Find Long Period + ENUM_TIMEFRAMES lcPeriod; // Long Period + ENUM_X_PERIOD_METHOD hcMethod; // How to Find Hind Period + ENUM_TIMEFRAMES hcPeriod; // Hind Period + ENUM_X_MARKET_CYCLES appliedCycle; // Applied Cycle + + // + // Signal ... + int signalR2R; // Risk Reward Ratio + bool drawSignals; // Draw Signal + bool drawTriggerBlock; // Draw Trigger Block + double slAtrMultiplier; // ATR Multiplier for SL + + // + // Validating ... + bool forceHasSwing; // Force Blocks to Have Swing + bool forceOBBarType; // Force Block Has Reversal Bar + bool forceOBFVGBarType; // Force FVG Has Same Bars + bool forceHasFLiquidity; // Force Blocks to Have Following Liquidity + bool forceHasRLiquidity; // Force Blocks to Have Reversal Liquidity + bool validateGapSequence; // Validate Block's Gap Sequence + bool validateBlockEdgeBreakout; // Validate Block's Edge Breakout + + // + // Filtering ... + bool filterBasedOnPV; // Filter Based on Peak and Vale + bool filterBasedOnSar; // Filter Based on Sar + bool filterBasedOnRSI; // Filter Based on RSI + bool filterBasedOnADX; // Filter Based on ADX + bool filterBasedOnATR; // Filter Based on ATR + bool filterBasedOnTrend; // Filter Based on Trend + bool filterBasedOnDelta; // Filter Based on Delta + bool filterBasedOnVolume; // Filter Based on Volume + bool filterBasedOnSignalBar; // Filter Based on Signal Bar + bool filterBasedOnHKSignalBar; // Filter Based on Hiken Ashi Signal Bar + + // + // Alert ... + string alertPrefix; // Alert Prefix + bool logAlerts; // Log Alerts + bool pushAlerts; // Push Alerts + bool mailAlerts; // Mail Alerts + bool terminalAlerts; // Terminal Alerts + + // + // Presentation ... + bool showBars; // Show Bars + bool showPV; // Show PV + bool showPVGolden; // Show PV Golden + bool showSar; // Show Sar + bool showTrend; // Show Trend + bool showATRBand; // Show ATR Band + bool showSignalBars; // Show Signal Bars + bool showHKSignalBars; // Show Hiken Ashi Signal Bars + + // + double rsiOBLevel; // RSI OB Level + double rsiOSLevel; // RSI OS Level + double adxThreshold; // ADX Threshold + + // + int startCalculationForLastBars; // Calculate Last n Bars + + // + // Constructor(s) ... + X121XCatbInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + // Market ... + scMethod = X_PERIOD_AUTO; // How to Find Short Period + scPeriod = NULL; // Short Period + mcMethod = X_PERIOD_AUTO; // How to Find Medium Period + mcPeriod = NULL; // Medium Period + lcMethod = X_PERIOD_AUTO; // How to Find Long Period + lcPeriod = NULL; // Long Period + hcMethod = X_PERIOD_AUTO; // How to Find Hind Period + hcPeriod = NULL; // Hind Period + appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + + // + // Signal ... + signalR2R = 0; // Risk Reward Ratio + drawSignals = false; // Draw Signal + drawTriggerBlock = false; // Draw Trigger Block + slAtrMultiplier = 0; // ATR Multiplier for SL + + // + // Validating ... + forceHasSwing = false; // Force Blocks to Have Swing + forceOBBarType = false; // Force Block Has Reversal Bar + forceOBFVGBarType = false; // Force FVG Has Same Bars + forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity + forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity + validateGapSequence = false; // Validate Block's Gap Sequence + validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + + // + // Filtering ... + filterBasedOnPV = false; // Filter Based on Peak and Vale + filterBasedOnSar = false; // Filter Based on Sar + filterBasedOnRSI = false; // Filter Based on RSI + filterBasedOnADX = false; // Filter Based on ADX + filterBasedOnATR = false; // Filter Based on ATR + filterBasedOnTrend = false; // Filter Based on Trend + filterBasedOnDelta = false; // Filter Based on Delta + filterBasedOnVolume = false; // Filter Based on Volume + filterBasedOnSignalBar = false; // Filter Based on Signal Bar + filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + + // + // Alert ... + alertPrefix = ""; // Alert Prefix + logAlerts = false; // Log Alerts + pushAlerts = false; // Push Alerts + mailAlerts = false; // Mail Alerts + terminalAlerts = false; // Terminal Alerts + + // + // Presentation ... + showBars = false; // Show Bars + showPV = false; // Show PV + showPVGolden = false; // Show PV Golden + showSar = false; // Show Sar + showTrend = false; // Show Trend + showATRBand = false; // Show ATR Band + showSignalBars = false; // Show Signal Bars + showHKSignalBars = false; // Show Hiken Ashi Signal Bars + + // + startCalculationForLastBars = 0; // Calculate Last n Bars + + // + rsiOBLevel = 70.0; // RSI OB Level + rsiOSLevel = 30.0; // RSI OS Level + adxThreshold = 25.0; // ADX Threshold + + // + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + // Market ... + scMethod = X_PERIOD_AUTO; // How to Find Short Period + scPeriod = NULL; // Short Period + mcMethod = X_PERIOD_AUTO; // How to Find Medium Period + mcPeriod = NULL; // Medium Period + lcMethod = X_PERIOD_AUTO; // How to Find Long Period + lcPeriod = NULL; // Long Period + hcMethod = X_PERIOD_AUTO; // How to Find Hind Period + hcPeriod = NULL; // Hind Period + appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + + // + // Signal ... + signalR2R = 4; // Risk Reward Ratio + drawSignals = false; // Draw Signal + drawTriggerBlock = false; // Draw Trigger Block + slAtrMultiplier = 1.0; // ATR Multiplier for SL + + // + // Validating ... + forceHasSwing = false; // Force Blocks to Have Swing + forceOBBarType = false; // Force Block Has Reversal Bar + forceOBFVGBarType = false; // Force FVG Has Same Bars + forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity + forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity + validateGapSequence = false; // Validate Block's Gap Sequence + validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + + // + // Filtering ... + filterBasedOnPV = false; // Filter Based on Peak and Vale + filterBasedOnSar = false; // Filter Based on Sar + filterBasedOnRSI = false; // Filter Based on RSI + filterBasedOnADX = false; // Filter Based on ADX + filterBasedOnATR = false; // Filter Based on ATR + filterBasedOnTrend = false; // Filter Based on Trend + filterBasedOnDelta = false; // Filter Based on Delta + filterBasedOnVolume = false; // Filter Based on Volume + filterBasedOnSignalBar = false; // Filter Based on Signal Bar + filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + + // + // Alert ... + alertPrefix = ""; // Alert Prefix + logAlerts = false; // Log Alerts + pushAlerts = false; // Push Alerts + mailAlerts = false; // Mail Alerts + terminalAlerts = false; // Terminal Alerts + + // + // Presentation ... + showBars = true; // Show Bars + showPV = false; // Show PV + showPVGolden = false; // Show PV Golden + showSar = false; // Show Sar + showTrend = false; // Show Trend + showATRBand = false; // Show ATR Band + showSignalBars = false; // Show Signal Bars + showHKSignalBars = false; // Show Hiken Ashi Signal Bars + + // + startCalculationForLastBars = 1500; // Calculate Last n Bars + + // + rsiOBLevel = 70.0; // RSI OB Level + rsiOSLevel = 30.0; // RSI OS Level + adxThreshold = 25.0; // ADX Threshold + } + + // + // Hide all Visible Buffers ... + void Hide() + { + // + showPV = false; + showPVGolden = false; + showSar = false; + showTrend = false; + showATRBand = false; + showSignalBars = false; + showHKSignalBars = false; + + // + drawSignals = false; + drawTriggerBlock = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(appliedCycle) && + // + // CYCLES ... + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + return result; + } + + // +}; + +// +// Conditions ... +struct X121XCatbConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + datetime to; + datetime from; + XOHCL bars[]; + + // + // Buffers ... + double sarBuffer[]; + double atrBuffer[]; + double rsiBuffer[]; + double adxBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + double adxpBuffer[]; + double adxnBuffer[]; + double peakBuffer[]; + double valeBuffer[]; + double deltaBuffer[]; + double trendBuffer[]; + double hkLowBuffer[]; + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkCloseBuffer[]; + double sarStateBuffer[]; + double atrUpperBuffer[]; + double atrLowerBuffer[]; + double sBarOpenBuffer[]; + double sBarCloseBuffer[]; + double trendStateBuffer[]; + double hkSBarOpenBuffer[]; + double peakGoldenBuffer[]; + double valeGoldenBuffer[]; + double hkSBarCloseBuffer[]; + double deltaSignalBuffer[]; + double bullishVolumeBuffer[]; + double bearishVolumeBuffer[]; + double bullishVolumeSignalBuffer[]; + double bearishVolumeSignalBuffer[]; + + // + double rsiOBLevel; // Over Bought Level + double rsiOSLevel; // Over Sold Level + double adxThreshold; // Big Movement Threshold + + // + // Conditions ... + + // + // ATR Band ... + + // + bool isATRUp; + bool isATRDown; + + // + bool isClosedOverATRUpper; + bool isClosedUnderATRLower; + + // + // SAR ... + + // + bool isSarBullish; + bool isSarBearish; + + // + bool isSarSwitchedToBullish; + bool isSarSwitchedToBearish; + + // + // ADX ... + + // + bool isADXBiggerLast; + bool isADXLesserLast; + + // + bool isADXOverThreshold; + bool isADXUnderThreshold; + + // + bool isDXPBiggerThanDXN; + bool isDXNBiggerThanDXP; + + // + bool isADXBullish; + bool isADXBearish; + + // + bool isADXSwitchedToBullish; + bool isADXSwitchedToBearish; + + // + // RSI ... + + // + bool isRSIBullish; + bool isRSIBearish; + + // + bool isRSISwitchedToBullish; + bool isRSISwitchedToBearish; + + // + bool isRSIOB; + bool isRSIOS; + + // + bool isRSICrossedOverOB; + bool isRSICrossedOverOS; + + // + bool isRSICrossedUnderOB; + bool isRSICrossedUnderOS; + + // + // DELTA ... + + // + bool isDeltaUp; + bool isDeltaDown; + + // + bool isDeltaBullish; + bool isDeltaBearish; + + // + bool isDeltaSwitchedToBullish; + bool isDeltaSwitchedToBearish; + + // + // VOLUME ... + + // + bool isVolumeBullish; + bool isVolumeBearish; + + // + bool isVolumeSwitchedToBullish; + bool isVolumeSwitchedToBearish; + + // + // SIGNAL Bar ... + + // + bool isSBarBullish; + bool isSBarBearish; + + // + bool isSBarSwitchedToBullish; + bool isSBarSwitchedToBearish; + + // + // XHK Signal Bar ... + + // + bool isHKSBarBullish; + bool isHKSBarBearish; + + // + bool isHKSBarSwitchedToBullish; + bool isHKSBarSwitchedToBearish; + + // + // TREND ... + + // + bool isTrendUp; + bool isTrendDown; + + // + bool isTrendBullish; + bool isTrendBearish; + + // + bool isTrendSwitchedToBullish; + bool isTrendSwitchedToBearish; + + // + // PEAK ... + + // + bool isPeakSameLast; + bool isPeakOverLast; + bool isPeakUnderLast; + + // + // VALE ... + + // + bool isValeSameLast; + bool isValeOverLast; + bool isValeUnderLast; + + // + // Constructor ... + X121XCatbConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + to = NULL; + from = NULL; + time = NULL; + symbol = NULL; + period = NULL; + + // + // Buffers ... + + // + Clean(bars); + Clean(sarBuffer); + Clean(atrBuffer); + Clean(rsiBuffer); + Clean(adxBuffer); + Clean(sHHBuffer); + Clean(sLLBuffer); + Clean(mHHBuffer); + Clean(mLLBuffer); + Clean(lHHBuffer); + Clean(lLLBuffer); + Clean(hHHBuffer); + Clean(hLLBuffer); + Clean(adxpBuffer); + Clean(adxnBuffer); + Clean(peakBuffer); + Clean(valeBuffer); + Clean(deltaBuffer); + Clean(trendBuffer); + Clean(hkLowBuffer); + Clean(hkOpenBuffer); + Clean(hkHighBuffer); + Clean(hkCloseBuffer); + Clean(sarStateBuffer); + Clean(atrUpperBuffer); + Clean(atrLowerBuffer); + Clean(sBarOpenBuffer); + Clean(sBarCloseBuffer); + Clean(trendStateBuffer); + Clean(hkSBarOpenBuffer); + Clean(peakGoldenBuffer); + Clean(valeGoldenBuffer); + Clean(hkSBarCloseBuffer); + Clean(deltaSignalBuffer); + Clean(bullishVolumeBuffer); + Clean(bearishVolumeBuffer); + Clean(bullishVolumeSignalBuffer); + Clean(bearishVolumeSignalBuffer); + + // + ArraySetAsSeries(bars, true); + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(atrBuffer, true); + ArraySetAsSeries(rsiBuffer, true); + ArraySetAsSeries(adxBuffer, true); + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + ArraySetAsSeries(hHHBuffer, true); + ArraySetAsSeries(hLLBuffer, true); + ArraySetAsSeries(adxpBuffer, true); + ArraySetAsSeries(adxnBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); + ArraySetAsSeries(deltaBuffer, true); + ArraySetAsSeries(trendBuffer, true); + ArraySetAsSeries(hkLowBuffer, true); + ArraySetAsSeries(hkOpenBuffer, true); + ArraySetAsSeries(hkHighBuffer, true); + ArraySetAsSeries(hkCloseBuffer, true); + ArraySetAsSeries(sarStateBuffer, true); + ArraySetAsSeries(atrUpperBuffer, true); + ArraySetAsSeries(atrLowerBuffer, true); + ArraySetAsSeries(sBarOpenBuffer, true); + ArraySetAsSeries(sBarCloseBuffer, true); + ArraySetAsSeries(trendStateBuffer, true); + ArraySetAsSeries(hkSBarOpenBuffer, true); + ArraySetAsSeries(peakGoldenBuffer, true); + ArraySetAsSeries(valeGoldenBuffer, true); + ArraySetAsSeries(hkSBarCloseBuffer, true); + ArraySetAsSeries(deltaSignalBuffer, true); + ArraySetAsSeries(bullishVolumeBuffer, true); + ArraySetAsSeries(bearishVolumeBuffer, true); + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + + // + rsiOBLevel = 0; // Over Bought Level + rsiOSLevel = 0; // Over Sold Level + adxThreshold = 0; // Big Movement Threshold + + // + // Conditions ... + + // + // Conditions ... + + // + // ATR Band ... + + // + isATRUp = false; + isATRDown = false; + + // + isClosedOverATRUpper = false; + isClosedUnderATRLower = false; + + // + // SAR ... + + // + isSarBullish = false; + isSarBearish = false; + + // + isSarSwitchedToBullish = false; + isSarSwitchedToBearish = false; + + // + // ADX ... + + // + isADXBiggerLast = false; + isADXLesserLast = false; + + // + isADXOverThreshold = false; + isADXUnderThreshold = false; + + // + isDXPBiggerThanDXN = false; + isDXNBiggerThanDXP = false; + + // + isADXBullish = false; + isADXBearish = false; + + // + isADXSwitchedToBullish = false; + isADXSwitchedToBearish = false; + + // + // RSI ... + + // + isRSIBullish = false; + isRSIBearish = false; + + // + isRSISwitchedToBullish = false; + isRSISwitchedToBearish = false; + + // + isRSIOB = false; + isRSIOS = false; + + // + isRSICrossedOverOB = false; + isRSICrossedOverOS = false; + + // + isRSICrossedUnderOB = false; + isRSICrossedUnderOS = false; + + // + // DELTA ... + + // + isDeltaUp = false; + isDeltaDown = false; + + // + isDeltaBullish = false; + isDeltaBearish = false; + + // + isDeltaSwitchedToBullish = false; + isDeltaSwitchedToBearish = false; + + // + // VOLUME ... + + // + isVolumeBullish = false; + isVolumeBearish = false; + + // + isVolumeSwitchedToBullish = false; + isVolumeSwitchedToBearish = false; + // + // SIGNAL Bar ... + + // + isSBarBullish = false; + isSBarBearish = false; + + // + isSBarSwitchedToBullish = false; + isSBarSwitchedToBearish = false; + + // + // XHK Signal Bar ... + + // + isHKSBarBullish = false; + isHKSBarBearish = false; + + // + isHKSBarSwitchedToBullish = false; + isHKSBarSwitchedToBearish = false; + + // + // TREND ... + + // + isTrendUp = false; + isTrendDown = false; + + // + isTrendBullish = false; + isTrendBearish = false; + + // + isTrendSwitchedToBullish = false; + isTrendSwitchedToBearish = false; + + // + // PEAK ... + + // + isPeakSameLast = false; + isPeakOverLast = false; + isPeakUnderLast = false; + + // + // VALE ... + + // + isValeSameLast = false; + isValeOverLast = false; + isValeUnderLast = false; + + // + ZeroMemory(this); + } + + /** + * 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; + + // + // ATR Band ... + + // + if (isATRUp) + { + bullishScore += score; + } + if (isClosedOverATRUpper) + { + bullishScore += score; + } + + // + if (isATRDown) + { + bearishScore += score; + } + if (isClosedUnderATRLower) + { + bearishScore += score; + } + + // + // SAR ... + + // + if (isSarBullish) + { + bullishScore += score; + } + if (isSarSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isSarBearish) + { + bearishScore += score; + } + if (isSarSwitchedToBearish) + { + bearishScore += score; + } + + // + // ADX ... + + // + if (isADXBullish) + { + bullishScore += score; + } + if (isADXBiggerLast) + { + bullishScore += score; + } + if (isDXPBiggerThanDXN) + { + bullishScore += score; + } + if (isADXOverThreshold) + { + bullishScore += score; + } + if (isADXSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isADXBearish) + { + bearishScore += score; + } + if (isADXLesserLast) + { + bearishScore += score; + } + if (isDXNBiggerThanDXP) + { + bearishScore += score; + } + if (isADXUnderThreshold) + { + bearishScore += score; + } + if (isADXSwitchedToBearish) + { + bearishScore += score; + } + + // + // RSI ... + + // + if (isRSIOS) + { + bullishScore += score; + } + if (isRSIBullish) + { + bullishScore += score; + } + if (isRSICrossedOverOS) + { + bullishScore += score; + } + if (isRSICrossedOverOB) + { + bullishScore += score; + } + if (isRSISwitchedToBullish) + { + bullishScore += score; + } + + // + if (isRSIOB) + { + bearishScore += score; + } + if (isRSIBearish) + { + bearishScore += score; + } + if (isRSICrossedUnderOB) + { + bearishScore += score; + } + if (isRSICrossedUnderOS) + { + bearishScore += score; + } + if (isRSISwitchedToBearish) + { + bearishScore += score; + } + + // + // DELTA ... + + // + if (isDeltaUp) + { + bullishScore += score; + } + if (isDeltaBullish) + { + bullishScore += score; + } + if (isDeltaSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isDeltaDown) + { + bearishScore += score; + } + if (isDeltaBearish) + { + bearishScore += score; + } + if (isDeltaSwitchedToBearish) + { + bearishScore += score; + } + + // + // VOLUME ... + + // + if (isVolumeBullish) + { + bullishScore += score; + } + if (isVolumeSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isVolumeBearish) + { + bearishScore += score; + } + if (isVolumeSwitchedToBearish) + { + bearishScore += score; + } + + // + // SIGNAL Bar ... + + // + if (isSBarBullish) + { + bullishScore += score; + } + if (isSBarSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isSBarBearish) + { + bearishScore += score; + } + if (isSBarSwitchedToBearish) + { + bearishScore += score; + } + + // + // XHK Signal Bar ... + + // + if (isHKSBarBullish) + { + bullishScore += score; + } + if (isHKSBarSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isHKSBarBearish) + { + bearishScore += score; + } + if (isHKSBarSwitchedToBearish) + { + bearishScore += score; + } + + // + // TREND ... + + // + if (isTrendUp) + { + bullishScore += score; + } + if (isTrendBullish) + { + bullishScore += score; + } + if (isTrendSwitchedToBullish) + { + bullishScore += score; + } + + // + if (isTrendDown) + { + bearishScore += score; + } + if (isTrendBearish) + { + bearishScore += score; + } + if (isTrendSwitchedToBearish) + { + bearishScore += score; + } + + // + // PEAK and VALE ... + + // + if (isValeSameLast) + { + bullishScore += score; + } + if (isValeOverLast) + { + bullishScore += score; + } + if (isPeakOverLast) + { + bullishScore += score; + } + + // + if (isPeakSameLast) + { + bearishScore += score; + } + if (isPeakUnderLast) + { + bearishScore += score; + } + if (isValeUnderLast) + { + 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 + + "XCATB: " + separator + + "-----------------------" + separator + + "" + separator + + // + "-----------------------" + separator + + "ATR Band: " + separator + + "-----------------------" + separator + + ToString("isATRUp", isATRUp, ignoreFalseConditions, separator) + + ToString("isATRDown", isATRDown, ignoreFalseConditions, separator) + + ToString("isClosedOverATRUpper", isClosedOverATRUpper, ignoreFalseConditions, separator) + + ToString("isClosedUnderATRLower", isClosedUnderATRLower, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "SAR: " + separator + + "-----------------------" + separator + + ToString("isSarBullish", isSarBullish, ignoreFalseConditions, separator) + + ToString("isSarBearish", isSarBearish, ignoreFalseConditions, separator) + + ToString("isSarSwitchedToBullish", isSarSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSarSwitchedToBearish", isSarSwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "ADX: " + separator + + "-----------------------" + separator + + ToString("isADXBiggerLast", isADXBiggerLast, ignoreFalseConditions, separator) + + ToString("isADXLesserLast", isADXLesserLast, ignoreFalseConditions, separator) + + ToString("isADXOverThreshold", isADXOverThreshold, ignoreFalseConditions, separator) + + ToString("isADXUnderThreshold", isADXUnderThreshold, ignoreFalseConditions, separator) + + ToString("isDXPBiggerThanDXN", isDXPBiggerThanDXN, ignoreFalseConditions, separator) + + ToString("isDXNBiggerThanDXP", isDXNBiggerThanDXP, ignoreFalseConditions, separator) + + ToString("isADXBullish", isADXBullish, ignoreFalseConditions, separator) + + ToString("isADXBearish", isADXBearish, ignoreFalseConditions, separator) + + ToString("isADXSwitchedToBullish", isADXSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isADXSwitchedToBearish", isADXSwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "RSI: " + separator + + "-----------------------" + separator + + ToString("isRSIBullish", isRSIBullish, ignoreFalseConditions, separator) + + ToString("isRSIBearish", isRSIBearish, ignoreFalseConditions, separator) + + ToString("isRSISwitchedToBullish", isRSISwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isRSISwitchedToBearish", isRSISwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isRSIOB", isRSIOB, ignoreFalseConditions, separator) + + ToString("isRSIOS", isRSIOS, ignoreFalseConditions, separator) + + ToString("isRSICrossedOverOB", isRSICrossedOverOB, ignoreFalseConditions, separator) + + ToString("isRSICrossedOverOS", isRSICrossedOverOS, ignoreFalseConditions, separator) + + ToString("isRSICrossedUnderOB", isRSICrossedUnderOB, ignoreFalseConditions, separator) + + ToString("isRSICrossedUnderOS", isRSICrossedUnderOS, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "DELTA: " + separator + + "-----------------------" + separator + + ToString("isDeltaUp", isDeltaUp, ignoreFalseConditions, separator) + + ToString("isDeltaDown", isDeltaDown, ignoreFalseConditions, separator) + + ToString("isDeltaBullish", isDeltaBullish, ignoreFalseConditions, separator) + + ToString("isDeltaBearish", isDeltaBearish, ignoreFalseConditions, separator) + + ToString("isDeltaSwitchedToBullish", isDeltaSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isDeltaSwitchedToBearish", isDeltaSwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "VOLUME: " + separator + + "-----------------------" + separator + + ToString("isVolumeBullish", isVolumeBullish, ignoreFalseConditions, separator) + + ToString("isVolumeBearish", isVolumeBearish, ignoreFalseConditions, separator) + + ToString("isVolumeSwitchedToBullish", isVolumeSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isVolumeSwitchedToBearish", isVolumeSwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "SIGNAL Bar: " + separator + + "-----------------------" + separator + + ToString("isSBarBullish", isSBarBullish, ignoreFalseConditions, separator) + + ToString("isSBarBearish", isSBarBearish, ignoreFalseConditions, separator) + + ToString("isSBarSwitchedToBullish", isSBarSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSBarSwitchedToBearish", isSBarSwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "XHK Signal Bar: " + separator + + "-----------------------" + separator + + ToString("isHKSBarBullish", isHKSBarBullish, ignoreFalseConditions, separator) + + ToString("isHKSBarBearish", isHKSBarBearish, ignoreFalseConditions, separator) + + ToString("isHKSBarSwitchedToBullish", isHKSBarSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isHKSBarSwitchedToBearish", isHKSBarSwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "Trend: " + separator + + "-----------------------" + separator + + ToString("isTrendUp", isTrendUp, ignoreFalseConditions, separator) + + ToString("isTrendDown", isTrendDown, ignoreFalseConditions, separator) + + ToString("isTrendBullish", isTrendBullish, ignoreFalseConditions, separator) + + ToString("isTrendBearish", isTrendBearish, ignoreFalseConditions, separator) + + ToString("isTrendSwitchedToBullish", isTrendSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isTrendSwitchedToBearish", isTrendSwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "Peak: " + separator + + "-----------------------" + separator + + ToString("isPeakSameLast", isPeakSameLast, ignoreFalseConditions, separator) + + ToString("isPeakOverLast", isPeakOverLast, ignoreFalseConditions, separator) + + ToString("isPeakUnderLast", isPeakUnderLast, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "Vale: " + separator + + "-----------------------" + separator + + ToString("isValeSameLast", isValeSameLast, ignoreFalseConditions, separator) + + ToString("isValeOverLast", isValeOverLast, ignoreFalseConditions, separator) + + ToString("isValeUnderLast", isValeUnderLast, 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 XCX121XCatbHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Buffers ... + double sarBuffer[]; + double atrBuffer[]; + double rsiBuffer[]; + double adxBuffer[]; + double sHHBuffer[]; + double sLLBuffer[]; + double mHHBuffer[]; + double mLLBuffer[]; + double lHHBuffer[]; + double lLLBuffer[]; + double hHHBuffer[]; + double hLLBuffer[]; + double adxpBuffer[]; + double adxnBuffer[]; + double peakBuffer[]; + double valeBuffer[]; + double deltaBuffer[]; + double trendBuffer[]; + double hkLowBuffer[]; + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkCloseBuffer[]; + double sarStateBuffer[]; + double atrUpperBuffer[]; + double atrLowerBuffer[]; + double sBarOpenBuffer[]; + double sBarCloseBuffer[]; + double trendStateBuffer[]; + double hkSBarOpenBuffer[]; + double peakGoldenBuffer[]; + double valeGoldenBuffer[]; + double hkSBarCloseBuffer[]; + double deltaSignalBuffer[]; + double bullishVolumeBuffer[]; + double bearishVolumeBuffer[]; + double bullishVolumeSignalBuffer[]; + double bearishVolumeSignalBuffer[]; + + // + // Market Shift ... + + // + // SAR ... + XDirectionShift lastSarBullish; + XDirectionShift lastSarBearish; + + // + // TREND ... + XDirectionShift lastTrendBullish; + XDirectionShift lastTrendBearish; + + // + // DELTA ... + XDirectionShift lastDeltaBullish; + XDirectionShift lastDeltaBearish; + + // + // VOLUME ... + XDirectionShift lastVolumeBullish; + XDirectionShift lastVolumeBearish; + + // + // SIGNAL Bar ... + XDirectionShift lastSignalBarBullish; + XDirectionShift lastSignalBarBearish; + + // + // XHK SIGNAL Bar ... + XDirectionShift lastHKSignalBarBullish; + XDirectionShift lastHKSignalBarBearish; + + // + // Constructors ... + XCX121XCatbHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121XCatbHelper() + { + // + mInputs.Clean(); + + // + Clean(sarBuffer); + Clean(atrBuffer); + Clean(rsiBuffer); + Clean(adxBuffer); + Clean(sHHBuffer); + Clean(sLLBuffer); + Clean(mHHBuffer); + Clean(mLLBuffer); + Clean(lHHBuffer); + Clean(lLLBuffer); + Clean(hHHBuffer); + Clean(hLLBuffer); + Clean(adxpBuffer); + Clean(adxnBuffer); + Clean(peakBuffer); + Clean(valeBuffer); + Clean(deltaBuffer); + Clean(trendBuffer); + Clean(hkLowBuffer); + Clean(hkOpenBuffer); + Clean(hkHighBuffer); + Clean(hkCloseBuffer); + Clean(sarStateBuffer); + Clean(atrUpperBuffer); + Clean(atrLowerBuffer); + Clean(sBarOpenBuffer); + Clean(sBarCloseBuffer); + Clean(trendStateBuffer); + Clean(hkSBarOpenBuffer); + Clean(peakGoldenBuffer); + Clean(valeGoldenBuffer); + Clean(hkSBarCloseBuffer); + Clean(deltaSignalBuffer); + Clean(bullishVolumeBuffer); + Clean(bearishVolumeBuffer); + Clean(bullishVolumeSignalBuffer); + Clean(bearishVolumeSignalBuffer); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121XCatbInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + ArraySetAsSeries(sarBuffer, true); + ArraySetAsSeries(atrBuffer, true); + ArraySetAsSeries(rsiBuffer, true); + ArraySetAsSeries(adxBuffer, true); + ArraySetAsSeries(sHHBuffer, true); + ArraySetAsSeries(sLLBuffer, true); + ArraySetAsSeries(mHHBuffer, true); + ArraySetAsSeries(mLLBuffer, true); + ArraySetAsSeries(lHHBuffer, true); + ArraySetAsSeries(lLLBuffer, true); + ArraySetAsSeries(hHHBuffer, true); + ArraySetAsSeries(hLLBuffer, true); + ArraySetAsSeries(adxpBuffer, true); + ArraySetAsSeries(adxnBuffer, true); + ArraySetAsSeries(peakBuffer, true); + ArraySetAsSeries(valeBuffer, true); + ArraySetAsSeries(deltaBuffer, true); + ArraySetAsSeries(trendBuffer, true); + ArraySetAsSeries(hkLowBuffer, true); + ArraySetAsSeries(hkOpenBuffer, true); + ArraySetAsSeries(hkHighBuffer, true); + ArraySetAsSeries(hkCloseBuffer, true); + ArraySetAsSeries(sarStateBuffer, true); + ArraySetAsSeries(atrUpperBuffer, true); + ArraySetAsSeries(atrLowerBuffer, true); + ArraySetAsSeries(sBarOpenBuffer, true); + ArraySetAsSeries(sBarCloseBuffer, true); + ArraySetAsSeries(trendStateBuffer, true); + ArraySetAsSeries(hkSBarOpenBuffer, true); + ArraySetAsSeries(peakGoldenBuffer, true); + ArraySetAsSeries(valeGoldenBuffer, true); + ArraySetAsSeries(hkSBarCloseBuffer, true); + ArraySetAsSeries(deltaSignalBuffer, true); + ArraySetAsSeries(bullishVolumeBuffer, true); + ArraySetAsSeries(bearishVolumeBuffer, true); + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xcatb", + "", // Market ... + mInputs.scMethod, + mInputs.scPeriod, + mInputs.mcMethod, + mInputs.mcPeriod, + mInputs.lcMethod, + mInputs.lcPeriod, + mInputs.hcMethod, + mInputs.hcPeriod, + mInputs.appliedCycle, + "", // Signal ... + mInputs.signalR2R, + mInputs.drawSignals, + mInputs.drawTriggerBlock, + mInputs.slAtrMultiplier, + "", // Validating ... + mInputs.forceHasSwing, + mInputs.forceOBBarType, + mInputs.forceOBFVGBarType, + mInputs.forceHasFLiquidity, + mInputs.forceHasRLiquidity, + mInputs.validateGapSequence, + mInputs.validateBlockEdgeBreakout, + "", // Filtering ... + mInputs.filterBasedOnPV, + mInputs.filterBasedOnSar, + mInputs.filterBasedOnRSI, + mInputs.filterBasedOnADX, + mInputs.filterBasedOnATR, + mInputs.filterBasedOnTrend, + mInputs.filterBasedOnDelta, + mInputs.filterBasedOnVolume, + mInputs.filterBasedOnSignalBar, + mInputs.filterBasedOnHKSignalBar, + "", // Alerts ... + mInputs.alertPrefix, + mInputs.logAlerts, + mInputs.pushAlerts, + mInputs.mailAlerts, + mInputs.terminalAlerts, + "", // Presentation ... + mInputs.showBars, + mInputs.showPV, + mInputs.showPVGolden, + mInputs.showSar, + mInputs.showTrend, + mInputs.showATRBand, + mInputs.showSignalBars, + mInputs.showHKSignalBars, + mInputs.startCalculationForLastBars + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + void Check(int barIndex = 0) + { + // + bool has = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + barIndex = NormalizeInt(barIndex, 0); + + // + X121XCatbConditions conditions; + has = GetConditions( + conditions, + barIndex, + 4 // + ); + if (!has) + { + // + conditions.Clean(); + return; + } + + // + // Checking Shifts ... + + // + // SAR ... + + // + isBullish = conditions.isSarSwitchedToBullish; + isBearish = conditions.isSarSwitchedToBearish; + + // + has = isBullish || + isBearish; + if (has) + { + // + // Bullish ... + has = + isBullish && + (!lastSarBullish.IsValid() + ? true + : lastSarBullish.at < conditions.bars[1].time); + if (has) + { + // + lastSarBullish.Clean(); + + // + lastSarBullish.type = "SAR"; + lastSarBullish.symbol = conditions.symbol; + lastSarBullish.period = conditions.period; + lastSarBullish.at = conditions.bars[1].time; + lastSarBullish.shiftTo = X_DIRECTION_BULLISH; + lastSarBullish.after = conditions.sarBuffer[1]; + lastSarBullish.before = conditions.sarBuffer[2]; + } + + // + // Bearish ... + has = + isBearish && + (!lastSarBearish.IsValid() + ? true + : lastSarBearish.at < conditions.bars[1].time); + if (has) + { + // + lastSarBearish.Clean(); + + // + lastSarBearish.type = "SAR"; + lastSarBearish.symbol = conditions.symbol; + lastSarBearish.period = conditions.period; + lastSarBearish.at = conditions.bars[1].time; + lastSarBearish.shiftTo = X_DIRECTION_BEARISH; + lastSarBearish.after = conditions.sarBuffer[1]; + lastSarBearish.before = conditions.sarBuffer[2]; + } + } + + // + // TREND ... + + // + isBullish = conditions.isTrendSwitchedToBullish; + isBearish = conditions.isTrendSwitchedToBearish; + + // + has = isBullish || + isBearish; + if (has) + { + // + // Bullish ... + has = + isBullish && + (!lastTrendBullish.IsValid() + ? true + : lastTrendBullish.at < conditions.bars[1].time); + if (has) + { + // + lastTrendBullish.Clean(); + + // + lastTrendBullish.type = "TREND"; + lastTrendBullish.symbol = conditions.symbol; + lastTrendBullish.period = conditions.period; + lastTrendBullish.at = conditions.bars[1].time; + lastTrendBullish.shiftTo = X_DIRECTION_BULLISH; + lastTrendBullish.after = conditions.trendBuffer[1]; + lastTrendBullish.before = conditions.trendBuffer[2]; + } + + // + // Bearish ... + has = + isBearish && + (!lastTrendBearish.IsValid() + ? true + : lastTrendBearish.at < conditions.bars[1].time); + if (has) + { + // + lastTrendBearish.Clean(); + + // + lastTrendBearish.type = "TREND"; + lastTrendBearish.symbol = conditions.symbol; + lastTrendBearish.period = conditions.period; + lastTrendBearish.at = conditions.bars[1].time; + lastTrendBearish.shiftTo = X_DIRECTION_BEARISH; + lastTrendBearish.after = conditions.trendBuffer[1]; + lastTrendBearish.before = conditions.trendBuffer[2]; + } + } + + // + // DELTA ... + + // + isBullish = + // + ( + // + // Delta is Up ... + conditions.deltaBuffer[1] > conditions.deltaBuffer[2] && + // + // Delta Signal is Up ... + conditions.deltaSignalBuffer[1] > conditions.deltaSignalBuffer[2] && + // + // Delta Crossed Over Delta ... + conditions.deltaBuffer[1] > conditions.deltaSignalBuffer[1] && + conditions.deltaBuffer[2] <= conditions.deltaSignalBuffer[2] + // + ) + // + ; + + // + isBearish = + // + ( + // + // Delta is Down ... + conditions.deltaBuffer[1] < conditions.deltaBuffer[2] && + // + // Delta Signal is Down ... + conditions.deltaSignalBuffer[1] < conditions.deltaSignalBuffer[2] && + // + // Delta Crossed Under Delta Signal ... + conditions.deltaBuffer[1] < conditions.deltaSignalBuffer[1] && + conditions.deltaBuffer[2] >= conditions.deltaSignalBuffer[2] + // + ) + // + ; + + // + has = isBullish || + isBearish; + if (has) + { + // + // Bullish ... + has = + isBullish && + (!lastDeltaBullish.IsValid() + ? true + : lastDeltaBullish.at < conditions.bars[1].time); + if (has) + { + // + lastDeltaBullish.Clean(); + + // + lastDeltaBullish.type = "DELTA"; + lastDeltaBullish.symbol = conditions.symbol; + lastDeltaBullish.period = conditions.period; + lastDeltaBullish.at = conditions.bars[1].time; + lastDeltaBullish.shiftTo = X_DIRECTION_BULLISH; + lastDeltaBullish.after = conditions.bars[1].close; + lastDeltaBullish.before = conditions.bars[2].close; + } + + // + // Bearish ... + has = + isBearish && + (!lastDeltaBearish.IsValid() + ? true + : lastDeltaBearish.at < conditions.bars[1].time); + if (has) + { + // + lastDeltaBearish.Clean(); + + // + lastDeltaBearish.type = "DELTA"; + lastDeltaBearish.symbol = conditions.symbol; + lastDeltaBearish.period = conditions.period; + lastDeltaBearish.at = conditions.bars[1].time; + lastDeltaBearish.shiftTo = X_DIRECTION_BEARISH; + lastDeltaBearish.after = conditions.bars[1].close; + lastDeltaBearish.before = conditions.bars[2].close; + } + } + + // + // VOLUME ... + + // + isBullish = + // + ( + // + // Volume is Up ... + conditions.bullishVolumeBuffer[1] > conditions.bullishVolumeBuffer[2] && + // + // Volume Signal is Up ... + conditions.bullishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[2] && + // + // Volume Signals Crossed Over ... + conditions.bullishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[1] && + conditions.bullishVolumeSignalBuffer[2] <= conditions.bearishVolumeSignalBuffer[2] + // + ) + // + ; + + // + isBullish = + // + ( + // + // Volume is Up ... + conditions.bearishVolumeBuffer[1] > conditions.bearishVolumeBuffer[2] && + // + // Volume Signal is Up ... + conditions.bearishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[2] && + // + // Volume Signals Crossed Over ... + conditions.bearishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[1] && + conditions.bearishVolumeSignalBuffer[2] <= conditions.bullishVolumeSignalBuffer[2] + // + ) + // + ; + + // + has = isBullish || + isBearish; + if (has) + { + // + // Bullish ... + has = + isBullish && + (!lastVolumeBullish.IsValid() + ? true + : lastVolumeBullish.at < conditions.bars[1].time); + if (has) + { + // + lastVolumeBullish.Clean(); + + // + lastVolumeBullish.type = "VOLUME"; + lastVolumeBullish.symbol = conditions.symbol; + lastVolumeBullish.period = conditions.period; + lastVolumeBullish.at = conditions.bars[1].time; + lastVolumeBullish.shiftTo = X_DIRECTION_BULLISH; + lastVolumeBullish.after = conditions.bars[1].close; + lastVolumeBullish.before = conditions.bars[2].close; + } + + // + // Bearish ... + has = + isBearish && + (!lastVolumeBearish.IsValid() + ? true + : lastVolumeBearish.at < conditions.bars[1].time); + if (has) + { + // + lastVolumeBearish.Clean(); + + // + lastVolumeBearish.type = "VOLUME"; + lastVolumeBearish.symbol = conditions.symbol; + lastVolumeBearish.period = conditions.period; + lastVolumeBearish.at = conditions.bars[1].time; + lastVolumeBearish.shiftTo = X_DIRECTION_BEARISH; + lastVolumeBearish.after = conditions.bars[1].close; + lastVolumeBearish.before = conditions.bars[2].close; + } + } + + // + // SIGNAL Bar ... + + // + isBullish = conditions.isSBarSwitchedToBullish; + isBearish = conditions.isSBarSwitchedToBearish; + + // + has = isBullish || + isBearish; + if (has) + { + // + // Bullish ... + has = + isBullish && + (!lastSignalBarBullish.IsValid() + ? true + : lastSignalBarBullish.at < conditions.bars[1].time); + if (has) + { + // + lastSignalBarBullish.Clean(); + + // + lastSignalBarBullish.type = "SIGNALBAR"; + lastSignalBarBullish.symbol = conditions.symbol; + lastSignalBarBullish.period = conditions.period; + lastSignalBarBullish.at = conditions.bars[1].time; + lastSignalBarBullish.shiftTo = X_DIRECTION_BULLISH; + lastSignalBarBullish.after = conditions.sBarCloseBuffer[1]; + lastSignalBarBullish.before = conditions.sBarCloseBuffer[2]; + } + + // + // Bearish ... + has = + isBearish && + (!lastSignalBarBearish.IsValid() + ? true + : lastSignalBarBearish.at < conditions.bars[1].time); + if (has) + { + // + lastSignalBarBearish.Clean(); + + // + lastSignalBarBearish.type = "SIGNALBAR"; + lastSignalBarBearish.symbol = conditions.symbol; + lastSignalBarBearish.period = conditions.period; + lastSignalBarBearish.at = conditions.bars[1].time; + lastSignalBarBearish.shiftTo = X_DIRECTION_BEARISH; + lastSignalBarBearish.after = conditions.sBarCloseBuffer[1]; + lastSignalBarBearish.before = conditions.sBarCloseBuffer[2]; + } + } + + // + // HKSIGNAL Bar ... + + // + isBullish = conditions.isHKSBarSwitchedToBullish; + isBearish = conditions.isHKSBarSwitchedToBearish; + + // + has = isBullish || + isBearish; + if (has) + { + // + // Bullish ... + has = + isBullish && + (!lastHKSignalBarBullish.IsValid() + ? true + : lastHKSignalBarBullish.at < conditions.bars[1].time); + if (has) + { + // + lastHKSignalBarBullish.Clean(); + + // + lastHKSignalBarBullish.type = "HKSIGNALBAR"; + lastHKSignalBarBullish.symbol = conditions.symbol; + lastHKSignalBarBullish.period = conditions.period; + lastHKSignalBarBullish.at = conditions.bars[1].time; + lastHKSignalBarBullish.shiftTo = X_DIRECTION_BULLISH; + lastHKSignalBarBullish.after = conditions.hkSBarCloseBuffer[1]; + lastHKSignalBarBullish.before = conditions.hkSBarCloseBuffer[2]; + } + + // + // Bearish ... + has = + isBearish && + (!lastHKSignalBarBearish.IsValid() + ? true + : lastHKSignalBarBearish.at < conditions.bars[1].time); + if (has) + { + // + lastHKSignalBarBearish.Clean(); + + // + lastHKSignalBarBearish.type = "HKSIGNALBAR"; + lastHKSignalBarBearish.symbol = conditions.symbol; + lastHKSignalBarBearish.period = conditions.period; + lastHKSignalBarBearish.at = conditions.bars[1].time; + lastHKSignalBarBearish.shiftTo = X_DIRECTION_BEARISH; + lastHKSignalBarBearish.after = conditions.hkSBarCloseBuffer[1]; + lastHKSignalBarBearish.before = conditions.hkSBarCloseBuffer[2]; + } + } + + // + // Cleanup Resources ... + + // + conditions.Clean(); + } + + // + // Inputs ... + + // + X121XCatbInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121XCatbInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Readers ... + + // + // SAR ... + + // + double GetSar( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sarBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sarBuffer[barIndex]; + } + + // + int CopySar( + 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, + sarBuffer, + buffer, + forceClean + // + ); + } + + // + // SAR State ... + + // + double GetSarState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sarStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sarStateBuffer[barIndex]; + } + + // + int CopySarState( + 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, + sarStateBuffer, + buffer, + forceClean + // + ); + } + + // + // PEAK ... + + // + double GetPeak( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(peakBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return peakBuffer[barIndex]; + } + + // + int CopyPeak( + 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, + peakBuffer, + buffer, + forceClean + // + ); + } + + // + // VALE ... + + // + double GetVale( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(valeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return valeBuffer[barIndex]; + } + + // + int CopyVale( + 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, + valeBuffer, + buffer, + forceClean + // + ); + } + + // + // PEAK Golden ... + + // + double GetPeakGolden( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(peakGoldenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return peakGoldenBuffer[barIndex]; + } + + // + int CopyPeakGolden( + 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, + peakGoldenBuffer, + buffer, + forceClean + // + ); + } + + // + // VALE Golden ... + + // + double GetValeGolden( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(valeGoldenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return valeGoldenBuffer[barIndex]; + } + + // + int CopyValeGolden( + 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, + valeGoldenBuffer, + buffer, + forceClean + // + ); + } + + // + // ATR ... + + // + double GetATR( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(atrBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return atrBuffer[barIndex]; + } + + // + int CopyATR( + 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, + atrBuffer, + buffer, + forceClean + // + ); + } + + // + // ATR Band Upper ... + + // + double GetATRUpper( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(atrUpperBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return atrUpperBuffer[barIndex]; + } + + // + int CopyATRUpper( + 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, + atrUpperBuffer, + buffer, + forceClean + // + ); + } + + // + // ATR Band Lower ... + + // + double GetATRLower( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(atrLowerBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return atrLowerBuffer[barIndex]; + } + + // + int CopyATRLower( + 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, + atrLowerBuffer, + buffer, + forceClean + // + ); + } + + // + // TREND ... + + // + double GetTrend( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(trendBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return trendBuffer[barIndex]; + } + + // + int CopyTrend( + 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, + trendBuffer, + buffer, + forceClean + // + ); + } + + // + // TREND State ... + + // + double GetTrendState( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(trendStateBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return trendStateBuffer[barIndex]; + } + + // + int CopyTrendState( + 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, + trendStateBuffer, + buffer, + forceClean + // + ); + } + + // + // SIGNAL Bar ... + + // + // OPEN ... + + // + double GetSBarOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sBarOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sBarOpenBuffer[barIndex]; + } + + // + int CopySBarOpen( + 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, + sBarOpenBuffer, + buffer, + forceClean + // + ); + } + + // + // CLOSE ... + + // + double GetSBarClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sBarCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sBarCloseBuffer[barIndex]; + } + + // + int CopySBarClose( + 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, + sBarCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK SIGNAL Bar ... + + // + // OPEN ... + + // + double GetHKSBarOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkSBarOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkSBarOpenBuffer[barIndex]; + } + + // + int CopyHKSBarOpen( + 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, + hkSBarOpenBuffer, + buffer, + forceClean + // + ); + } + + // + // CLOSE ... + + // + double GetHKSBarClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkSBarCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkSBarCloseBuffer[barIndex]; + } + + // + int CopyHKSBarClose( + 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, + hkSBarCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // CYCLES Range ... + + // + // SHORT ... + + // + // HH ... + + // + double GetSHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sHHBuffer[barIndex]; + } + + // + int CopySHH( + 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, + sHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetSLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(sLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return sLLBuffer[barIndex]; + } + + // + int CopySLL( + 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, + sLLBuffer, + buffer, + forceClean + // + ); + } + + // + // MEDIUM ... + + // + // HH ... + + // + double GetMHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mHHBuffer[barIndex]; + } + + // + int CopyMHH( + 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, + mHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetMLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(mLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return mLLBuffer[barIndex]; + } + + // + int CopyMLL( + 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, + mLLBuffer, + buffer, + forceClean + // + ); + } + + // + // LONG ... + + // + // HH ... + + // + double GetLHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(lHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lHHBuffer[barIndex]; + } + + // + int CopyLHH( + 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, + lHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetLLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(lLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return lLLBuffer[barIndex]; + } + + // + int CopyLLL( + 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, + lLLBuffer, + buffer, + forceClean + // + ); + } + + // + // HIND ... + + // + // HH ... + + // + double GetHHH( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hHHBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hHHBuffer[barIndex]; + } + + // + int CopyHHH( + 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, + hHHBuffer, + buffer, + forceClean + // + ); + } + + // + // LL ... + + // + double GetHLL( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hLLBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hLLBuffer[barIndex]; + } + + // + int CopyHLL( + 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, + hLLBuffer, + buffer, + forceClean + // + ); + } + + // + // ADX ... + + // + double GetADX( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(adxBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return adxBuffer[barIndex]; + } + + // + int CopyADX( + 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, + adxBuffer, + buffer, + forceClean + // + ); + } + + // + // ADXP ... + + // + double GetADXP( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(adxpBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return adxpBuffer[barIndex]; + } + + // + int CopyADXP( + 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, + adxpBuffer, + buffer, + forceClean + // + ); + } + + // + // ADXN ... + + // + double GetADXN( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(adxnBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return adxnBuffer[barIndex]; + } + + // + int CopyADXN( + 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, + adxnBuffer, + buffer, + forceClean + // + ); + } + + // + // DELTA ... + + // + double GetDelta( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(deltaBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return deltaBuffer[barIndex]; + } + + // + int CopyDelta( + 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, + deltaBuffer, + buffer, + forceClean + // + ); + } + + // + // DELTA Signal ... + + // + double GetDeltaSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(deltaSignalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return deltaSignalBuffer[barIndex]; + } + + // + int CopyDeltaSignal( + 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, + deltaSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // VOLUME ... + + // + // Bullish ... + + // + double GetBullishVolume( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bullishVolumeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bullishVolumeBuffer[barIndex]; + } + + // + int CopyBullishVolume( + 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, + bullishVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Bearish ... + + // + double GetBearishVolume( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bearishVolumeBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bearishVolumeBuffer[barIndex]; + } + + // + int CopyBearishVolume( + 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, + bearishVolumeBuffer, + buffer, + forceClean + // + ); + } + + // + // VOLUME Signal ... + + // + // Bullish ... + + // + double GetBullishVolumeSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bullishVolumeSignalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bullishVolumeSignalBuffer[barIndex]; + } + + // + int CopyBullishVolumeSignal( + 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, + bullishVolumeSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // Bearish ... + + // + double GetBearishVolumeSignal( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(bearishVolumeSignalBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return bearishVolumeSignalBuffer[barIndex]; + } + + // + int CopyBearishVolumeSignal( + 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, + bearishVolumeSignalBuffer, + buffer, + forceClean + // + ); + } + + // + // XHK ... + + // + // Open ... + + // + double GetHKOpen( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkOpenBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkOpenBuffer[barIndex]; + } + + // + int CopyHKOpen( + 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, + hkOpenBuffer, + buffer, + forceClean + // + ); + } + + // + // High ... + + // + double GetHKHigh( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkHighBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkHighBuffer[barIndex]; + } + + // + int CopyHKHigh( + 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, + hkHighBuffer, + buffer, + forceClean + // + ); + } + + // + // Low ... + + // + double GetHKLow( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkLowBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkLowBuffer[barIndex]; + } + + // + int CopyHKLow( + 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, + hkLowBuffer, + buffer, + forceClean + // + ); + } + + // + // Close ... + + // + double GetHKClose( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(hkCloseBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return hkCloseBuffer[barIndex]; + } + + // + int CopyHKClose( + 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, + hkCloseBuffer, + buffer, + forceClean + // + ); + } + + // + // RSI ... + + // + double GetRSI( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(barIndex); + + // + int count = ArraySize(rsiBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return rsiBuffer[barIndex]; + } + + // + int CopyRSI( + 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, + rsiBuffer, + buffer, + forceClean + // + ); + } + + // + // Tools ... + + // + void Update( + int barIndex // Bar Index + ) + { + // + Calculate(barIndex); + } + + // + void Free() override + { + Cleanup(10); + } + + // + bool GetConditions( + X121XCatbConditions &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(); + + // + // Filling Bars ... + int barsCount = GetBars( + conditions.bars, + mSymbol, + mPeriod, + barIndex, + loopback // + ); + result = barsCount == loopback; + if (!result) + { + // + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + conditions.to = conditions.bars[0].time; + conditions.from = conditions.bars[ArraySize(conditions.bars) - 1].time; + + // + int zIndex = barIndex; + + // + // Buffers ... + + CopySar( + zIndex, + loopback, + conditions.sarBuffer // + ); + + // + CopySarState( + zIndex, + loopback, + conditions.sarStateBuffer // + ); + + // + CopyPeak( + zIndex, + loopback, + conditions.peakBuffer // + ); + + // + CopyVale( + zIndex, + loopback, + conditions.valeBuffer // + ); + + // + CopyPeakGolden( + zIndex, + loopback, + conditions.peakGoldenBuffer // + ); + + // + CopyValeGolden( + zIndex, + loopback, + conditions.valeGoldenBuffer // + ); + + // + CopyATR( + zIndex, + loopback, + conditions.atrBuffer // + ); + + // + CopyATRUpper( + zIndex, + loopback, + conditions.atrUpperBuffer // + ); + + // + CopyATRLower( + zIndex, + loopback, + conditions.atrLowerBuffer // + ); + + // + CopyTrend( + zIndex, + loopback, + conditions.trendBuffer // + ); + + // + CopyTrendState( + zIndex, + loopback, + conditions.trendStateBuffer // + ); + + // + CopySBarOpen( + zIndex, + loopback, + conditions.sBarOpenBuffer // + ); + + // + CopySBarClose( + zIndex, + loopback, + conditions.sBarCloseBuffer // + ); + + // + CopyHKSBarOpen( + zIndex, + loopback, + conditions.hkSBarOpenBuffer // + ); + + // + CopyHKSBarClose( + zIndex, + loopback, + conditions.hkSBarCloseBuffer // + ); + + // + CopySHH( + zIndex, + loopback, + conditions.sHHBuffer // + ); + + // + CopySLL( + zIndex, + loopback, + conditions.sLLBuffer // + ); + + // + CopyMHH( + zIndex, + loopback, + conditions.mHHBuffer // + ); + + // + CopyMLL( + zIndex, + loopback, + conditions.mLLBuffer // + ); + + // + CopyLHH( + zIndex, + loopback, + conditions.lHHBuffer // + ); + + // + CopyLLL( + zIndex, + loopback, + conditions.lLLBuffer // + ); + + // + CopyHHH( + zIndex, + loopback, + conditions.hHHBuffer // + ); + + // + CopyHLL( + zIndex, + loopback, + conditions.hLLBuffer // + ); + + // + CopyADX( + zIndex, + loopback, + conditions.adxBuffer // + ); + + // + CopyADXP( + zIndex, + loopback, + conditions.adxpBuffer // + ); + + // + CopyADXN( + zIndex, + loopback, + conditions.adxnBuffer // + ); + + // + CopyDelta( + zIndex, + loopback, + conditions.deltaBuffer // + ); + + // + CopyDeltaSignal( + zIndex, + loopback, + conditions.deltaSignalBuffer // + ); + + // + CopyBullishVolume( + zIndex, + loopback, + conditions.bullishVolumeBuffer // + ); + + // + CopyBearishVolume( + zIndex, + loopback, + conditions.bearishVolumeBuffer // + ); + + // + CopyBullishVolumeSignal( + zIndex, + loopback, + conditions.bullishVolumeSignalBuffer // + ); + + // + CopyBearishVolumeSignal( + zIndex, + loopback, + conditions.bearishVolumeSignalBuffer // + ); + + // + CopyHKOpen( + zIndex, + loopback, + conditions.hkOpenBuffer // + ); + + // + CopyHKHigh( + zIndex, + loopback, + conditions.hkHighBuffer // + ); + + // + CopyHKLow( + zIndex, + loopback, + conditions.hkLowBuffer // + ); + + // + CopyHKClose( + zIndex, + loopback, + conditions.hkCloseBuffer // + ); + + // + CopyRSI( + zIndex, + loopback, + conditions.rsiBuffer // + ); + + // + // Calculate ... + + // + double _rsiOBLevel = mInputs.rsiOBLevel; // Over Bought Level + double _rsiOSLevel = mInputs.rsiOSLevel; // Over Sold Level + double _adxThreshold = mInputs.adxThreshold; // Big Movement Threshold + + // + // Reading Values ... + + // + // ATR Upper ... + double zATRUpper = conditions.atrUpperBuffer[zIDX]; + double cATRUpper = conditions.atrUpperBuffer[cIDX]; + double pATRUpper = conditions.atrUpperBuffer[pIDX]; + double p2ATRUpper = conditions.atrUpperBuffer[p2IDX]; + double p3ATRUpper = conditions.atrUpperBuffer[p3IDX]; + + // + // ATR Lower ... + double zATRLower = conditions.atrLowerBuffer[zIDX]; + double cATRLower = conditions.atrLowerBuffer[cIDX]; + double pATRLower = conditions.atrLowerBuffer[pIDX]; + double p2ATRLower = conditions.atrLowerBuffer[p2IDX]; + double p3ATRLower = conditions.atrLowerBuffer[p3IDX]; + + // + // SAR ... + + // + double zSAR = conditions.sarBuffer[zIDX]; + double cSar = conditions.sarBuffer[cIDX]; + double pSAR = conditions.sarBuffer[pIDX]; + double p2SAR = conditions.sarBuffer[p2IDX]; + double p3SAR = conditions.sarBuffer[p3IDX]; + + // + double zSarState = conditions.sarStateBuffer[zIDX]; + double cSarState = conditions.sarStateBuffer[cIDX]; + double pSarState = conditions.sarStateBuffer[pIDX]; + double p2SarState = conditions.sarStateBuffer[p2IDX]; + double p3SarState = conditions.sarStateBuffer[p3IDX]; + + // + // ADX ... + + // + double zADX = conditions.adxBuffer[zIDX]; + double cADX = conditions.adxBuffer[cIDX]; + double pADX = conditions.adxBuffer[pIDX]; + double p2ADX = conditions.adxBuffer[p2IDX]; + double p3ADX = conditions.adxBuffer[p3IDX]; + + // + // ADX P ... + + // + double zADXP = conditions.adxpBuffer[zIDX]; + double cADXP = conditions.adxpBuffer[cIDX]; + double pADXP = conditions.adxpBuffer[pIDX]; + double p2ADXP = conditions.adxpBuffer[p2IDX]; + double p3ADXP = conditions.adxpBuffer[p3IDX]; + + // + // ADX N ... + + // + double zADXN = conditions.adxnBuffer[zIDX]; + double cADXN = conditions.adxnBuffer[cIDX]; + double pADXN = conditions.adxnBuffer[pIDX]; + double p2ADXN = conditions.adxnBuffer[p2IDX]; + double p3ADXN = conditions.adxnBuffer[p3IDX]; + + // + // RSI ... + + // + double zRSI = conditions.rsiBuffer[zIDX]; + double cRSI = conditions.rsiBuffer[cIDX]; + double pRSI = conditions.rsiBuffer[pIDX]; + double p2RSI = conditions.rsiBuffer[p2IDX]; + double p3RSI = conditions.rsiBuffer[p3IDX]; + + // + // SIGNAL Bar ... + + // + double zSBarO = conditions.sBarOpenBuffer[zIDX]; + double cSBarO = conditions.sBarOpenBuffer[cIDX]; + double pSBarO = conditions.sBarOpenBuffer[pIDX]; + double p2SBarO = conditions.sBarOpenBuffer[p2IDX]; + double p3SBarO = conditions.sBarOpenBuffer[p3IDX]; + + // + double zSBarC = conditions.sBarCloseBuffer[zIDX]; + double cSBarC = conditions.sBarCloseBuffer[cIDX]; + double pSBarC = conditions.sBarCloseBuffer[pIDX]; + double p2SBarC = conditions.sBarCloseBuffer[p2IDX]; + double p3SBarC = conditions.sBarCloseBuffer[p3IDX]; + + // + // XHK SIGNAL Bar ... + + // + double zHKSBarO = conditions.hkSBarOpenBuffer[zIDX]; + double cHKSBarO = conditions.hkSBarOpenBuffer[cIDX]; + double pHKSBarO = conditions.hkSBarOpenBuffer[pIDX]; + double p2HKSBarO = conditions.hkSBarOpenBuffer[p2IDX]; + double p3HKSBarO = conditions.hkSBarOpenBuffer[p3IDX]; + + // + double zHKSBarC = conditions.hkSBarCloseBuffer[zIDX]; + double cHKSBarC = conditions.hkSBarCloseBuffer[cIDX]; + double pHKSBarC = conditions.hkSBarCloseBuffer[pIDX]; + double p2HKSBarC = conditions.hkSBarCloseBuffer[p2IDX]; + double p3HKSBarC = conditions.hkSBarCloseBuffer[p3IDX]; + + // + // TREND ... + + // + double zTrend = conditions.trendBuffer[zIDX]; + double cTrend = conditions.trendBuffer[cIDX]; + double pTrend = conditions.trendBuffer[pIDX]; + double p2Trend = conditions.trendBuffer[p2IDX]; + double p3Trend = conditions.trendBuffer[p3IDX]; + + // + double zTrendState = conditions.trendStateBuffer[zIDX]; + double cTrendState = conditions.trendStateBuffer[cIDX]; + double pTrendState = conditions.trendStateBuffer[pIDX]; + double p2TrendState = conditions.trendStateBuffer[p2IDX]; + double p3TrendState = conditions.trendStateBuffer[p3IDX]; + + // + // XPV ... + + // + double zPEAK = conditions.peakBuffer[zIDX]; + double cPEAK = conditions.peakBuffer[cIDX]; + double pPEAK = conditions.peakBuffer[pIDX]; + double p2PEAK = conditions.peakBuffer[p2IDX]; + double p3PEAK = conditions.peakBuffer[p3IDX]; + + // + double zVALE = conditions.valeBuffer[zIDX]; + double cVALE = conditions.valeBuffer[cIDX]; + double pVALE = conditions.valeBuffer[pIDX]; + double p2VALE = conditions.valeBuffer[p2IDX]; + double p3VALE = conditions.valeBuffer[p3IDX]; + + // + // DELTA ... + + // + double zDelta = conditions.deltaBuffer[zIDX]; + double cDelta = conditions.deltaBuffer[cIDX]; + double pDelta = conditions.deltaBuffer[pIDX]; + double p2Delta = conditions.deltaBuffer[p2IDX]; + double p3Delta = conditions.deltaBuffer[p3IDX]; + + // + double zDeltaSignal = conditions.deltaSignalBuffer[zIDX]; + double cDeltaSignal = conditions.deltaSignalBuffer[cIDX]; + double pDeltaSignal = conditions.deltaSignalBuffer[pIDX]; + double p2DeltaSignal = conditions.deltaSignalBuffer[p2IDX]; + double p3DeltaSignal = conditions.deltaSignalBuffer[p3IDX]; + + // + // VOLUME ... + + // + double zBullishVolume = conditions.bullishVolumeBuffer[zIDX]; + double cBullishVolume = conditions.bullishVolumeBuffer[cIDX]; + double pBullishVolume = conditions.bullishVolumeBuffer[pIDX]; + double p2BullishVolume = conditions.bullishVolumeBuffer[p2IDX]; + double p3BullishVolume = conditions.bullishVolumeBuffer[p3IDX]; + + // + double zBearishVolume = conditions.bearishVolumeBuffer[zIDX]; + double cBearishVolume = conditions.bearishVolumeBuffer[cIDX]; + double pBearishVolume = conditions.bearishVolumeBuffer[pIDX]; + double p2BearishVolume = conditions.bearishVolumeBuffer[p2IDX]; + double p3BearishVolume = conditions.bearishVolumeBuffer[p3IDX]; + + // + double zBullishVolumeSignal = conditions.bullishVolumeSignalBuffer[zIDX]; + double cBullishVolumeSignal = conditions.bullishVolumeSignalBuffer[cIDX]; + double pBullishVolumeSignal = conditions.bullishVolumeSignalBuffer[pIDX]; + double p2BullishVolumeSignal = conditions.bullishVolumeSignalBuffer[p2IDX]; + double p3BullishVolumeSignal = conditions.bullishVolumeSignalBuffer[p3IDX]; + + // + double zBearishVolumeSignal = conditions.bearishVolumeSignalBuffer[zIDX]; + double cBearishVolumeSignal = conditions.bearishVolumeSignalBuffer[cIDX]; + double pBearishVolumeSignal = conditions.bearishVolumeSignalBuffer[pIDX]; + double p2BearishVolumeSignal = conditions.bearishVolumeSignalBuffer[p2IDX]; + double p3BearishVolumeSignal = conditions.bearishVolumeSignalBuffer[p3IDX]; + + // + // ATR Band ... + + // + bool isATRUp = + cATRUpper > pATRUpper && + cATRLower > pATRLower; + bool isATRDown = + cATRUpper < pATRUpper && + cATRLower < pATRLower; + + // + bool isClosedOverATRUpper = + conditions.bars[cIDX].close > cATRUpper; + bool isClosedUnderATRLower = + conditions.bars[cIDX].close < cATRLower; + + // + // SAR ... + + // + bool isSarBullish = cSarState > 0; + bool isSarBearish = cSarState < 0; + + // + bool isSarSwitchedToBullish = + cSarState > 0 && + pSarState <= 0; + bool isSarSwitchedToBearish = + cSarState < 0 && + pSarState >= 0; + + // + // ADX ... + + // + bool isADXBiggerLast = + cADX > pADX; + bool isADXLesserLast = + cADX < pADX; + + // + bool isPADXBiggerLast = + pADX > p2ADX; + bool isPADXLesserLast = + pADX < p2ADX; + + // + bool isADXOverThreshold = + cADX > _adxThreshold; + bool isADXUnderThreshold = + cADX < _adxThreshold; + + // + bool isPADXOverThreshold = + pADX > _adxThreshold; + bool isPADXUnderThreshold = + pADX < _adxThreshold; + + // + bool isDXPBiggerThanDXN = + cADXP > cADXN; + bool isDXNBiggerThanDXP = + cADXN > cADXP; + + // + bool isPDXPBiggerThanDXN = + pADXP > pADXN; + bool isPDXNBiggerThanDXP = + pADXN > pADXP; + + // + bool isADXBullish = + isADXBiggerLast && + isADXOverThreshold; + bool isADXBearish = + isADXLesserLast && + isADXUnderThreshold; + + // + bool isPADXBullish = + isPADXBiggerLast && + isPADXOverThreshold; + bool isPADXBearish = + isPADXLesserLast && + isPADXUnderThreshold; + + // + bool isADXSwitchedToBullish = + isADXBullish && + !isPADXBullish; + bool isADXSwitchedToBearish = + isADXBearish && + !isPADXBearish; + + // + // RSI ... + + // + bool isRSIBullish = + cRSI > pRSI; + bool isRSIBearish = + cRSI < pRSI; + + // + bool isRSISwitchedToBullish = + cRSI > pRSI && + pRSI <= cRSI; + bool isRSISwitchedToBearish = + cRSI < pRSI && + pRSI >= cRSI; + + // + bool isRSIOB = + cRSI > _rsiOBLevel; + bool isRSIOS = + cRSI < _rsiOSLevel; + + // + bool isRSICrossedOverOB = + cRSI > _rsiOBLevel && + pRSI <= _rsiOBLevel; + bool isRSICrossedOverOS = + cRSI > _rsiOSLevel && + pRSI <= _rsiOSLevel; + + // + bool isRSICrossedUnderOB = + cRSI < _rsiOBLevel && + pRSI >= _rsiOBLevel; + bool isRSICrossedUnderOS = + cRSI < _rsiOSLevel && + pRSI >= _rsiOSLevel; + + // + // DELTA ... + + // + bool isDeltaUp = + cDelta > pDelta; + bool isDeltaDown = + cDelta < pDelta; + + // + bool isDeltaBullish = + cDelta > pDelta && + cDeltaSignal > cDelta && + cDeltaSignal > pDeltaSignal; + bool isPDeltaBullish = + pDelta > p2Delta && + pDeltaSignal > pDelta && + pDeltaSignal > p2DeltaSignal; + + // + bool isDeltaBearish = + cDelta < pDelta && + cDeltaSignal < cDelta && + cDeltaSignal < pDeltaSignal; + bool isPDeltaBearish = + pDelta < p2Delta && + pDeltaSignal < pDelta && + pDeltaSignal < p2DeltaSignal; + + // + bool isDeltaSwitchedToBullish = + isDeltaBullish && + !isPDeltaBullish; + bool isDeltaSwitchedToBearish = + isDeltaBearish && + !isPDeltaBearish; + + // + // VOLUME ... + + // + bool isVolumeBullish = + cBullishVolume > pBullishVolume && + cBullishVolume > cBearishVolume; + bool isVolumeBearish = + cBearishVolume > pBearishVolume && + cBearishVolume > cBullishVolume; + + // + bool isVolumeSwitchedToBullish = + isVolumeBullish && + cBullishVolumeSignal > cBearishVolumeSignal && + pBullishVolumeSignal <= pBearishVolumeSignal; + bool isVolumeSwitchedToBearish = + isVolumeBearish && + cBearishVolumeSignal > cBullishVolumeSignal && + pBearishVolumeSignal <= pBullishVolumeSignal; + + // + // SIGNAL Bar ... + + // + bool isSBarBullish = + cSBarO < cSBarC; + bool isSBarBearish = + cSBarO > cSBarC; + + // + bool isSBarSwitchedToBullish = + cSBarO < cSBarC && + pSBarO >= pSBarC; + bool isSBarSwitchedToBearish = + cSBarO > cSBarC && + pSBarO <= pSBarC; + + // + // XHK Signal Bar ... + + // + bool isHKSBarBullish = + cHKSBarO < cHKSBarC; + bool isHKSBarBearish = + cHKSBarO > cHKSBarC; + + // + bool isHKSBarSwitchedToBullish = + cHKSBarO < cHKSBarC && + pHKSBarO >= pHKSBarC; + bool isHKSBarSwitchedToBearish = + cHKSBarO > cHKSBarC && + pHKSBarO <= pHKSBarC; + + // + // TREND ... + + // + bool isTrendUp = + cTrend > pTrend; + bool isTrendDown = + cTrend < pTrend; + + // + bool isTrendBullish = + cTrendState > 0; + bool isTrendBearish = + cTrendState < 0; + + // + bool isTrendSwitchedToBullish = + isTrendUp && + cTrendState > 0 && + pTrendState <= 0; + bool isTrendSwitchedToBearish = + isTrendDown && + cTrendState < 0 && + pTrendState >= 0; + + // + // PEAK ... + + // + bool isPeakSameLast = + cPEAK > 0 && + cPEAK == pPEAK; + bool isPeakOverLast = + pPEAK > 0 && + cPEAK > pPEAK; + bool isPeakUnderLast = + cPEAK > 0 && + cPEAK < pPEAK; + + // + // VALE ... + + // + bool isValeSameLast = + cVALE > 0 && + cVALE == pVALE; + bool isValeOverLast = + pVALE > 0 && + cVALE > pVALE; + bool isValeUnderLast = + cVALE > 0 && + cVALE < pVALE; + + // + // Attached ... + + // + conditions.isATRUp = isATRUp; + conditions.isRSIOB = isRSIOB; + conditions.isRSIOS = isRSIOS; + conditions.isDeltaUp = isDeltaUp; + conditions.isATRDown = isATRDown; + conditions.isTrendUp = isTrendUp; + conditions.rsiOBLevel = _rsiOBLevel; + conditions.rsiOSLevel = _rsiOSLevel; + conditions.isDeltaDown = isDeltaDown; + conditions.isTrendDown = isTrendDown; + conditions.adxThreshold = _adxThreshold; + conditions.isSarBullish = isSarBullish; + conditions.isSarBearish = isSarBearish; + conditions.isADXBullish = isADXBullish; + conditions.isADXBearish = isADXBearish; + conditions.isRSIBullish = isRSIBullish; + conditions.isRSIBearish = isRSIBearish; + conditions.isSBarBullish = isSBarBullish; + conditions.isSBarBearish = isSBarBearish; + conditions.isDeltaBullish = isDeltaBullish; + conditions.isDeltaBearish = isDeltaBearish; + conditions.isTrendBullish = isTrendBullish; + conditions.isTrendBearish = isTrendBearish; + conditions.isPeakSameLast = isPeakSameLast; + conditions.isPeakOverLast = isPeakOverLast; + conditions.isValeSameLast = isValeSameLast; + conditions.isValeOverLast = isValeOverLast; + conditions.isVolumeBullish = isVolumeBullish; + conditions.isVolumeBearish = isVolumeBearish; + conditions.isADXBiggerLast = isADXBiggerLast; + conditions.isADXLesserLast = isADXLesserLast; + conditions.isHKSBarBullish = isHKSBarBullish; + conditions.isHKSBarBearish = isHKSBarBearish; + conditions.isPeakUnderLast = isPeakUnderLast; + conditions.isValeUnderLast = isValeUnderLast; + conditions.isRSICrossedOverOB = isRSICrossedOverOB; + conditions.isRSICrossedOverOS = isRSICrossedOverOS; + conditions.isADXOverThreshold = isADXOverThreshold; + conditions.isDXPBiggerThanDXN = isDXPBiggerThanDXN; + conditions.isDXNBiggerThanDXP = isDXNBiggerThanDXP; + conditions.isRSICrossedUnderOB = isRSICrossedUnderOB; + conditions.isRSICrossedUnderOS = isRSICrossedUnderOS; + conditions.isADXUnderThreshold = isADXUnderThreshold; + conditions.isClosedOverATRUpper = isClosedOverATRUpper; + conditions.isClosedUnderATRLower = isClosedUnderATRLower; + conditions.isSarSwitchedToBullish = isSarSwitchedToBullish; + conditions.isSarSwitchedToBearish = isSarSwitchedToBearish; + conditions.isADXSwitchedToBullish = isADXSwitchedToBullish; + conditions.isADXSwitchedToBearish = isADXSwitchedToBearish; + conditions.isRSISwitchedToBullish = isRSISwitchedToBullish; + conditions.isRSISwitchedToBearish = isRSISwitchedToBearish; + conditions.isSBarSwitchedToBullish = isSBarSwitchedToBullish; + conditions.isSBarSwitchedToBearish = isSBarSwitchedToBearish; + conditions.isTrendSwitchedToBullish = isTrendSwitchedToBullish; + conditions.isTrendSwitchedToBearish = isTrendSwitchedToBearish; + conditions.isDeltaSwitchedToBullish = isDeltaSwitchedToBullish; + conditions.isDeltaSwitchedToBearish = isDeltaSwitchedToBearish; + conditions.isVolumeSwitchedToBullish = isVolumeSwitchedToBullish; + conditions.isVolumeSwitchedToBearish = isVolumeSwitchedToBearish; + conditions.isHKSBarSwitchedToBullish = isHKSBarSwitchedToBullish; + conditions.isHKSBarSwitchedToBearish = isHKSBarSwitchedToBearish; + + // + // Cleanup Resources ... + + // + Cleanup(); + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121XCatbInputs mInputs; // Inputs ... + + // + // Buffers ... + // Define in Public ... + + // + void Calculate( + int barIndex = 0, + int maxRequiredBars = 100 // + ) + { + // + // Buffers ... + if (barIndex < 0) + { + barIndex = 0; + } + + // + CopyBuffer( + mHandler, + X121_XCATB_SAR_LINE, + barIndex, + maxRequiredBars, + sarBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_SAR_STATE_LINE, + barIndex, + maxRequiredBars, + sarStateBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_PEAK_LINE, + barIndex, + maxRequiredBars, + peakBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VALE_LINE, + barIndex, + maxRequiredBars, + valeBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_PEAK_GOLDEN_LINE, + barIndex, + maxRequiredBars, + peakGoldenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VALE_GOLDEN_LINE, + barIndex, + maxRequiredBars, + valeGoldenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ATR_BAND_UPPER_LINE, + barIndex, + maxRequiredBars, + atrUpperBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ATR_BAND_LOWER_LINE, + barIndex, + maxRequiredBars, + atrLowerBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_TREND_LINE, + barIndex, + maxRequiredBars, + trendBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_TREND_STATE_LINE, + barIndex, + maxRequiredBars, + trendStateBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_SBAR_O_LINE, + barIndex, + maxRequiredBars, + sBarOpenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_SBAR_C_LINE, + barIndex, + maxRequiredBars, + sBarCloseBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_SBAR_O_LINE, + barIndex, + maxRequiredBars, + hkSBarOpenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_SBAR_C_LINE, + barIndex, + maxRequiredBars, + hkSBarCloseBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_S_HH_LINE, + barIndex, + maxRequiredBars, + sHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_S_LL_LINE, + barIndex, + maxRequiredBars, + sLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_M_HH_LINE, + barIndex, + maxRequiredBars, + mHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_M_LL_LINE, + barIndex, + maxRequiredBars, + mLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_L_HH_LINE, + barIndex, + maxRequiredBars, + lHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_L_LL_LINE, + barIndex, + maxRequiredBars, + lLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_H_HH_LINE, + barIndex, + maxRequiredBars, + hHHBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_H_LL_LINE, + barIndex, + maxRequiredBars, + hLLBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_RSI_LINE, + barIndex, + maxRequiredBars, + rsiBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ADX_LINE, + barIndex, + maxRequiredBars, + adxBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ADXP_LINE, + barIndex, + maxRequiredBars, + adxpBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ADXN_LINE, + barIndex, + maxRequiredBars, + adxnBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_DELTA_LINE, + barIndex, + maxRequiredBars, + deltaBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_DELTA_SIGNAL_LINE, + barIndex, + maxRequiredBars, + deltaSignalBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_BULLISH_LINE, + barIndex, + maxRequiredBars, + bullishVolumeBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_BEARISH_LINE, + barIndex, + maxRequiredBars, + bearishVolumeBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_VOLUME_BULLISH_SIGNAL_LINE, + barIndex, + maxRequiredBars, + bullishVolumeSignalBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_VOLUME_VOLUME_BEARISH_SIGNAL_LINE, + barIndex, + maxRequiredBars, + bearishVolumeSignalBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_ATR_LINE, + barIndex, + maxRequiredBars, + atrBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_O_LINE, + barIndex, + maxRequiredBars, + hkOpenBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_H_LINE, + barIndex, + maxRequiredBars, + hkHighBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_L_LINE, + barIndex, + maxRequiredBars, + hkLowBuffer // + ); + + // + CopyBuffer( + mHandler, + X121_XCATB_HK_BAR_C_LINE, + barIndex, + maxRequiredBars, + hkCloseBuffer // + ); + } + + // + void Cleanup( + int maxAllowed = 100 // + ) + { + // + CleanupArray( + sarBuffer, + maxAllowed // + ); + + // + CleanupArray( + sarStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + peakBuffer, + maxAllowed // + ); + + // + CleanupArray( + valeBuffer, + maxAllowed // + ); + + // + CleanupArray( + peakGoldenBuffer, + maxAllowed // + ); + + // + CleanupArray( + valeGoldenBuffer, + maxAllowed // + ); + + // + CleanupArray( + atrUpperBuffer, + maxAllowed // + ); + + // + CleanupArray( + atrLowerBuffer, + maxAllowed // + ); + + // + CleanupArray( + trendBuffer, + maxAllowed // + ); + + // + CleanupArray( + trendStateBuffer, + maxAllowed // + ); + + // + CleanupArray( + sBarOpenBuffer, + maxAllowed // + ); + + // + CleanupArray( + sBarCloseBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkSBarOpenBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkSBarCloseBuffer, + maxAllowed // + ); + + // + CleanupArray( + sHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + sLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + mHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + mLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + lHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + lLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + hHHBuffer, + maxAllowed // + ); + + // + CleanupArray( + hLLBuffer, + maxAllowed // + ); + + // + CleanupArray( + rsiBuffer, + maxAllowed // + ); + + // + CleanupArray( + adxBuffer, + maxAllowed // + ); + + // + CleanupArray( + adxpBuffer, + maxAllowed // + ); + + // + CleanupArray( + adxnBuffer, + maxAllowed // + ); + + // + CleanupArray( + deltaBuffer, + maxAllowed // + ); + + // + CleanupArray( + deltaSignalBuffer, + maxAllowed // + ); + + // + CleanupArray( + bullishVolumeBuffer, + maxAllowed // + ); + + // + CleanupArray( + bearishVolumeBuffer, + maxAllowed // + ); + + // + CleanupArray( + bullishVolumeSignalBuffer, + maxAllowed // + ); + + // + CleanupArray( + bearishVolumeSignalBuffer, + maxAllowed // + ); + + // + CleanupArray( + atrBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkOpenBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkHighBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkLowBuffer, + maxAllowed // + ); + + // + CleanupArray( + hkCloseBuffer, + maxAllowed // + ); + } + + // +}; + +// \ No newline at end of file diff --git a/Documents/Helpers/x-saherelm.x121.xcc.helper.mq5 b/Documents/Helpers/x-saherelm.x121.xcc.helper.mq5 new file mode 100644 index 00000000..67710361 --- /dev/null +++ b/Documents/Helpers/x-saherelm.x121.xcc.helper.mq5 @@ -0,0 +1,259 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCX121XCCHelper +// 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 ... + +// +// Input Models ... +struct X121XCCInputs +{ + // + // Props ... + + // + // Chart Style ... + ENUM_CHART_MODE mode; // Mode + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + + // + // Presentation ... + bool showCandles; // Show Candles + + // + // Constructor(s) ... + X121XCCInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + mode = CHART_CANDLES; + + // + upColor = CLR_NONE; + downColor = CLR_NONE; + lineColor = CLR_NONE; + bearishColor = CLR_NONE; + bullishColor = CLR_NONE; + volumesColor = CLR_NONE; + + // + showCandles = false; + + // + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + mode = CHART_CANDLES; + + // + upColor = clrLime; + downColor = clrRed; + lineColor = clrLime; + bearishColor = clrRed; + bullishColor = clrLime; + volumesColor = clrGreen; + // + showCandles = true; + } + + // + // Hide all Visible Buffers ... + void Hide() + { + showCandles = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + true + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, 0); + + // + return result; + } +}; + +// +// Class ... +class XCX121XCCHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCX121XCCHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121XCCHelper() + { + mInputs.Clean(); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121XCCInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xcc", + // + // Inputs ... + // + // Chart Style ... + "", + mInputs.mode, // Mode + mInputs.upColor, // Up Color + mInputs.downColor, // Down Color + mInputs.lineColor, // Line mode and Doji candlestick Color + mInputs.bullishColor, // Bearish Color + mInputs.bearishColor, // Bullish Color + mInputs.volumesColor, // Volumes Color + // + // Presentation ... + "", + mInputs.showCandles // Show Candles + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X121XCCInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121XCCInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121XCCInputs mInputs; // Inputs ... +}; + +// +// Tools ... \ No newline at end of file diff --git a/Documents/Helpers/x-saherelm.x121.xct.helper.mq5 b/Documents/Helpers/x-saherelm.x121.xct.helper.mq5 new file mode 100644 index 00000000..6c5284e2 --- /dev/null +++ b/Documents/Helpers/x-saherelm.x121.xct.helper.mq5 @@ -0,0 +1,241 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCX121XCTHelper +// 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 ... + +// +// Input Models ... +struct X121XCTInputs +{ + // + // Props ... + + // + string font; // Font + int fontSize; // Font Size; + color clr; // Text Color + ENUM_BASE_CORNER corner; // Text Position + + // + // Presentation ... + bool showCandleTime; // Show Candle Time + + // + // Constructor(s) ... + X121XCTInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + font = NULL; + fontSize = 15; + clr = CLR_NONE; + corner = CORNER_RIGHT_LOWER; + + // + // Presentation ... + showCandleTime = false; + + // + ZeroMemory(this); + } + + // + // Default ... + void Default() + { + // + font = "Arial"; + fontSize = 15; + clr = clrYellow; + corner = CORNER_RIGHT_LOWER; + + // + // Presentation ... + showCandleTime = true; + } + + // + // Hide all Visible Buffers ... + void Hide() + { + showCandleTime = false; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + true + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(0, 0); + + // + return result; + } +}; + +// +// Class ... +class XCX121XCTHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCX121XCTHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121XCTHelper() + { + mInputs.Clean(); + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121XCTInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xct", + // + // Inputs ... + mInputs.fontSize, // Font Size ... + mInputs.font, // Font ... + mInputs.clr, // Text Color ... + mInputs.corner, // Text Position ... + // + // Presentation ... + "", + mInputs.showCandleTime // Show Candle Time + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X121XCTInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121XCTInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121XCTInputs mInputs; // Inputs ... +}; + +// +// Tools ... \ No newline at end of file diff --git a/Helpers/x-saherelm.x121.xoscs.helper.mq5 b/Documents/Helpers/x-saherelm.x121.xoscs.helper.mq5 similarity index 100% rename from Helpers/x-saherelm.x121.xoscs.helper.mq5 rename to Documents/Helpers/x-saherelm.x121.xoscs.helper.mq5 diff --git a/Documents/Indicators/x-saherelm.x121.xcatb.mq5 b/Documents/Indicators/x-saherelm.x121.xcatb.mq5 new file mode 100644 index 00000000..8fb1e13d --- /dev/null +++ b/Documents/Indicators/x-saherelm.x121.xcatb.mq5 @@ -0,0 +1,2777 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XCATB +// Description: Integrates All Requirements inside +// this indicator for analyse Markets to +// Detect Trigger Blocks ... +// +// - HK Bars; +// - ATR Band; +// - Signal Bars; +// - Parabolic Sar; +// - HK Signal Bars; +// - Peaks and Vales; +// - Peaks and Vales Goldens; +// - Trending Average Prices; +// +// - ATR; +// - RSI; +// - ADX; +// - DELTA; +// - VOLUME; +// +// 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 XCATB Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 XCATB" + +// +// Imports ... +#include "../Classes/x-saherelm.x-alert.class.mq5" +#include "../Classes/x-saherelm.x-bar.analyser.class.mq5" +#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.x121.xcatb.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; + +// +// Short ... +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Short Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Short Period + +// +// Medium ... +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Medium Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Medium Period + +// +// Long ... +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Long Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Long Period + +// +// Hind ... +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Hind Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Hind Period + +// +// Select Trending Cycle ... +// this Cycle Used for All Calculations ... +input ENUM_X_MARKET_CYCLES appliedCycle = X_MARKET_CYCLE_HIND; // Applied Cycle + +// +// Signal ... +input group "Signal"; +input int signalR2R = 4; // Risk Reward Ratio +input bool drawSignals = true; // Draw Signal +input bool drawTriggerBlock = true; // Draw Trigger Block +input double slAtrMultiplier = 1.0; // ATR Multiplier for SL + +// +// Validating ... +input group "Validating"; +input bool forceHasSwing = false; // Force Blocks to Have Swing +input bool forceObBarType = false; // Force Block Has Reversal Bar +input bool forceOBFVGBarType = false; // Force FVG Has Same Bars +input bool forceHasFLiquidity = false; // Force Blocks to Have Following Liquidity +input bool forceHasRLiquidity = false; // Force Blocks to Have Reversal Liquidity +input bool validateGapSequence = false; // Validate Block's Gap Sequence +input bool validateBlockEdgeBreakout = false; // Validate Block's Edge Breakout + +// +// Filtering ... +input group "Filtering"; +input bool filterBasedOnPV = false; // Filter Based on Peak and Vale +input bool filterBasedOnSar = false; // Filter Based on Sar +input bool filterBasedOnRSI = false; // Filter Based on RSI +input bool filterBasedOnADX = false; // Filter Based on ADX +input bool filterBasedOnATR = false; // Filter Based on ATR +input bool filterBasedOnTrend = false; // Filter Based on Trend +input bool filterBasedOnDelta = false; // Filter Based on Delta +input bool filterBasedOnVolume = false; // Filter Based on Volume +input bool filterBasedOnSignalBar = false; // Filter Based on Signal Bar +input bool filterBasedOnHKSignalBar = false; // Filter Based on Hiken Ashi Signal Bar + +// +// Alert ... +input group "Alerts"; +input string mAlertPrefix = ""; // Alert Prefix +input bool _logAlerts = false; // Log Alerts +input bool _pushAlerts = false; // Push Alerts +input bool _mailAlerts = false; // Mail Alerts +input bool _terminalAlerts = false; // Terminal Alerts + +// +// Presentation ... +input group "Presentation"; +input bool showBars = true; // Show Bars +input bool showPV = false; // Show PV +input bool showPVGolden = false; // Show PV Golden +input bool showSar = false; // Show Sar +input bool showTrend = false; // Show Trend +input bool showATRBand = false; // Show ATR Band +input bool showSignalBars = false; // Show Signal Bars +input bool showHKSignalBars = false; // Show Hiken Ashi Signal Bars + +// +input int startCalculationForLastBars = 1500; // Calculate Last n Bars + +// +// Non Inputs ... +double sarStep = 0.02; // Step +double sarMax = 0.2; // Maximum +double rsiOBLevel = 70.0; // RSI OB Level +double rsiOSLevel = 30.0; // RSI OS Level +double adxThreshold = 25.0; // ADX Threshold +int sarArrowCode = 159; // Parabolic Sar Arrow Code +int peakArrowCode = 159; // Peaks Arrow Code +int valeArrowCode = 159; // Vales Arrow Code +double atrMultiplier = 1.5; // ATR Band Multiplier +bool showShortCycle = false; // Show Short Cycle Range +bool showMediumCycle = false; // Show Medium Cycle Range +bool showLongCycle = false; // Show Long Cycle Range +bool showHindCycle = false; // Show Hind Cycle Range +ENUM_MA_METHOD trendMode = MODE_SMA; // Trend Mode +ENUM_SERIESMODE upperMode = MODE_HIGH; // Peak Method +ENUM_SERIESMODE lowerMode = MODE_LOW; // Vale Method +ENUM_X_PRICE atrUpperPriceType = X_PRICE_HIGH; // ATR Upper Zone Applied To +ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // ATR Lower Zone Applied To +ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To +ENUM_APPLIED_PRICE trendAppliedTo = PRICE_MEDIAN; // Trend Applied To +ENUM_X_MA_METHOD atrSignalMethod = X_MA_MODE_EMA; // ATR Signalling Method +ENUM_X_MA_METHOD barsSignalMethod = X_MA_MODE_EMA; // Bars Signalling Method +ENUM_X_MA_METHOD deltaSignalMethod = X_MA_MODE_EMA; // Delta Signalling Method +ENUM_X_MA_METHOD hkSignalBarMethod = X_MA_MODE_EMA; // Hiken Ashi Signal Method +ENUM_X_MA_METHOD volumeSignalMethod = X_MA_MODE_EMA; // Volume Signalling Method + +// +#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 + +// +// Buffers ... + +// +#property indicator_chart_window + +// +// Plot: 18 +// Color: 4 +// Bar: 8 +// Data Buffer: 19 +#property indicator_buffers 49 +#property indicator_plots 18 + +// +// Plot Buffers ... + +// +// SAR ... + +// +#define sarBufferIndex 0 +#define sarBufferPlotIndex 0 +double sarBuffer[]; + +// +#define sarColorBufferIndex 1 +double sarColorBuffer[]; + +// +#property indicator_label1 "SAR" +#property indicator_type1 DRAW_COLOR_ARROW +#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray +#property indicator_width1 2 + +// +// PEAKS ... + +// +#define peakBufferIndex 2 +#define peakBufferPlotIndex 1 +double peakBuffer[]; + +// +#property indicator_label2 "PEAK" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +// VALES ... + +// +#define valeBufferIndex 3 +#define valeBufferPlotIndex 2 +double valeBuffer[]; + +// +#property indicator_label3 "VALE" +#property indicator_type3 DRAW_ARROW +#property indicator_color3 clrAqua +#property indicator_width3 1 + +// +// PEAKS Golden ... + +// +#define peakGoldenBufferIndex 4 +#define peakGoldenBufferPlotIndex 3 +double peakGoldenBuffer[]; + +// +#property indicator_label4 "PEAK Golden" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// VALE Golden ... + +// +#define valeGoldenBufferIndex 5 +#define valeGoldenBufferPlotIndex 4 +double valeGoldenBuffer[]; + +// +#property indicator_label5 "VALES Golden" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrAqua +#property indicator_style5 STYLE_DOT +#property indicator_width5 1 + +// +// ATR ... + +// +// Upper ... + +// +#define atrUpperBufferIndex 6 +#define atrUpperBufferPlotIndex 5 +double atrUpperBuffer[]; + +// +#property indicator_label6 "XATRU" +#property indicator_type6 DRAW_LINE +#property indicator_color6 clrYellow +#property indicator_style6 STYLE_SOLID +#property indicator_width6 1 + +// +// Lower ... + +// +#define atrLowerBufferIndex 7 +#define atrLowerBufferPlotIndex 6 +double atrLowerBuffer[]; + +// +#property indicator_label7 "XATRL" +#property indicator_type7 DRAW_LINE +#property indicator_color7 clrYellow +#property indicator_style7 STYLE_SOLID +#property indicator_width7 1 + +// +// TREND ... + +// +#define trendBufferIndex 8 +#define trendBufferPlotIndex 7 +double trendBuffer[]; + +// +#define trendColorBufferIndex 9 +double trendColorBuffer[]; + +// +#property indicator_label8 "Trend" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrAqua, clrMagenta, clrGray +#property indicator_style8 STYLE_SOLID +#property indicator_width8 2 + +// +// Signal Bar ... + +// +#define sBarOpenBufferIndex 10 +double sBarOpenBuffer[]; + +// +#define sBarHighBufferIndex 11 +double sBarHighBuffer[]; + +// +#define sBarLowBufferIndex 12 +double sBarLowBuffer[]; + +// +#define sBarCloseBufferIndex 13 +double sBarCloseBuffer[]; + +// +#define sBarColorBufferIndex 14 +double sBarColorBuffer[]; + +// +#define sBarBufferPlotIndex 8 +#property indicator_label9 "XSGB Open;XSGB High;XSGB Low;XSGB Close" +#property indicator_type9 DRAW_COLOR_CANDLES +#property indicator_color9 CLR_NONE, clrLime, clrRed + +// +// XHK SIGNAL ... + +// +#define hkSBarOpenBufferIndex 15 +double hkSBarOpenBuffer[]; + +// +#define hkSBarHighBufferIndex 16 +double hkSBarHighBuffer[]; + +// +#define hkSBarLowBufferIndex 17 +double hkSBarLowBuffer[]; + +// +#define hkSBarCloseBufferIndex 18 +double hkSBarCloseBuffer[]; + +// +#define hkSBarColorBufferIndex 19 +double hkSBarColorBuffer[]; + +// +#define hkSBarBufferPlotIndex 9 +#property indicator_label10 "XHKSGB Open;XHKSGB High;XHKSGB Low;XHKSGB Close" +#property indicator_type10 DRAW_COLOR_CANDLES +#property indicator_color10 CLR_NONE, clrAqua, clrMagenta + +// +// CYCLES Range ... + +// +// SHORT ... + +// +#define sHHBufferIndex 20 +#define sHHBufferPlotIndex 10 +double sHHBuffer[]; + +// +#property indicator_label11 "SH" +#property indicator_type11 DRAW_LINE +#property indicator_color11 clrGray +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define sLLBufferIndex 21 +#define sLLBufferPlotIndex 11 +double sLLBuffer[]; + +// +#property indicator_label12 "SL" +#property indicator_type12 DRAW_LINE +#property indicator_color12 clrGray +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +// MEDIUM ... + +// +#define mHHBufferIndex 22 +#define mHHBufferPlotIndex 12 +double mHHBuffer[]; + +// +#property indicator_label13 "MH" +#property indicator_type13 DRAW_LINE +#property indicator_color13 clrIndigo +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define mLLBufferIndex 23 +#define mLLBufferPlotIndex 13 +double mLLBuffer[]; + +// +#property indicator_label14 "ML" +#property indicator_type14 DRAW_LINE +#property indicator_color14 clrIndigo +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +// LONG ... + +// +#define lHHBufferIndex 24 +#define lHHBufferPlotIndex 14 +double lHHBuffer[]; + +// +#property indicator_label15 "LH" +#property indicator_type15 DRAW_LINE +#property indicator_color15 clrGoldenrod +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define lLLBufferIndex 25 +#define lLLBufferPlotIndex 15 +double lLLBuffer[]; + +// +#property indicator_label16 "LL" +#property indicator_type16 DRAW_LINE +#property indicator_color16 clrGoldenrod +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +// HIND ... + +// +#define hHHBufferIndex 26 +#define hHHBufferPlotIndex 16 +double hHHBuffer[]; + +// +#property indicator_label17 "HH" +#property indicator_type17 DRAW_LINE +#property indicator_color17 clrBrown +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +#define hLLBufferIndex 27 +#define hLLBufferPlotIndex 17 +double hLLBuffer[]; + +// +#property indicator_label18 "HL" +#property indicator_type18 DRAW_LINE +#property indicator_color18 clrBrown +#property indicator_style18 STYLE_DOT +#property indicator_width18 1 + +// +// Data Buffers ... + +// +#define mLastBufferIndex 27 + +// +// SAR ... + +// +#define sarStateBufferIndex mLastBufferIndex + 1 +double sarStateBuffer[]; + +// +// TREND State ... + +// +#define trendStateBufferIndex mLastBufferIndex + 2 +double trendStateBuffer[]; + +// +// RSI ... + +// +#define rsiBufferIndex mLastBufferIndex + 3 +double rsiBuffer[]; + +// +// ADX ... + +// +#define adxBufferIndex mLastBufferIndex + 4 +double adxBuffer[]; + +// +#define adxpBufferIndex mLastBufferIndex + 5 +double adxpBuffer[]; + +// +#define adxnBufferIndex mLastBufferIndex + 6 +double adxnBuffer[]; + +// +// DELTA ... + +// +#define deltaBufferIndex mLastBufferIndex + 7 +double deltaBuffer[]; + +// +#define deltaSignalBufferIndex mLastBufferIndex + 8 +double deltaSignalBuffer[]; + +// +// VOLUMES ... + +// +#define bullishVolumeBufferIndex mLastBufferIndex + 9 +double bullishVolumeBuffer[]; + +// +#define bearishVolumeBufferIndex mLastBufferIndex + 10 +double bearishVolumeBuffer[]; + +// +#define bullishVolumeSignalBufferIndex mLastBufferIndex + 11 +double bullishVolumeSignalBuffer[]; + +// +#define bearishVolumeSignalBufferIndex mLastBufferIndex + 12 +double bearishVolumeSignalBuffer[]; + +// +// ATR ... + +// +#define atrBufferIndex mLastBufferIndex + 13 +double atrBuffer[]; + +// +#define atrUpperRawBufferIndex mLastBufferIndex + 14 +double atrUpperRawBuffer[]; + +// +#define atrLowerRawBufferIndex mLastBufferIndex + 15 +double atrLowerRawBuffer[]; + +// +// HK ... + +// +#define openHKBufferIndex mLastBufferIndex + 16 +double openHKBuffer[]; + +// +#define highHKBufferIndex mLastBufferIndex + 17 +double highHKBuffer[]; + +// +#define lowHKBufferIndex mLastBufferIndex + 18 +double lowHKBuffer[]; + +// +#define closeHKBufferIndex mLastBufferIndex + 19 +double closeHKBuffer[]; + +// +// Variables, Properties and etc ... + +// +int limit; + +// +int maxLength; + +// +int firstBarIndex; + +// +// Bars Color Variables ... +color _upColor = clrLime; +color _downColor = clrRed; +color _lineColor = clrLime; +color _bullishColor = clrLime; +color _bearishColor = clrRed; + +// +// XMarketCycle sc; +int mSCLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// XMarketCycle mc; +int mMCLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// XMarketCycle lc; +int mLCLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// XMarketCycle hc; +int mHCLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +// Applied Cycle ... +int mAppliedLength; +ENUM_TIMEFRAMES mAppliedPeriod = NULL; + +// +// Handlers ... +int atrHandler = INVALID_HANDLE; +int sarHandler = INVALID_HANDLE; +int rsiHandler = INVALID_HANDLE; +int adxHandler = INVALID_HANDLE; +int trendHandler = INVALID_HANDLE; + +// +XCAlert *mAlert; +CArrayObj mObjects; +XCPOIDrawer *mDrawer; +bool mEnableAlerts = false; +XCBarAnalyser *mBarAnalyser; + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + bool has = false; + + // + ReadBarStyle(); + + // + // Validate Inputs ... + has = ValidateInputs(); + if (!has) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + has = InitCycles(); + if (!has) + { + 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(); + + // + // Initial Requirements ... + has = InitRequirements(); + if (!has) + { + return INIT_FAILED; + } + + // + if (showBars) + { + ShowBars(); + } + else + { + HideBars(); + } + + // + // 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 + + // + ShowBars(); + + // + mObjects.Clear(); + + // + delete mAlert; + ZeroMemory(mAlert); + + // + delete mDrawer; + ZeroMemory(mDrawer); + + // + delete mBarAnalyser; + ZeroMemory(mBarAnalyser); + + // + // De Initialize all Handlers and etc ... + IndicatorRelease(atrHandler); + IndicatorRelease(sarHandler); + IndicatorRelease(rsiHandler); + IndicatorRelease(adxHandler); + IndicatorRelease(trendHandler); +} + +/** + * 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 ... + + // + // ATR ... + int atrCalculatedBars = BarsCalculated(atrHandler); + + // + // SAR ... + int sarCalculatedBars = BarsCalculated(sarHandler); + + // + // RSI ... + int rsiCalculatedBars = BarsCalculated(rsiHandler); + + // + // ADX ... + int adxCalculatedBars = BarsCalculated(adxHandler); + + // + // TREND ... + int trendCalculatedBars = BarsCalculated(trendHandler); + + // + bool isPassedRequiredCalculatedBars = + // + // ATR ... + atrCalculatedBars >= maxLength && + // + // SAR ... + sarCalculatedBars >= maxLength && + // + // RSI ... + rsiCalculatedBars >= maxLength && + // + // ADX ... + adxCalculatedBars >= maxLength && + // + // TREND ... + trendCalculatedBars >= maxLength + // + ; + if (!isPassedRequiredCalculatedBars) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) + ? rates_total + : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + + // + // ATR ... + int copiedAtrs = CopyBuffer(atrHandler, MAIN_LINE, 0, limit, atrBuffer); + + // + // SAR ... + int copiedSars = CopyBuffer(sarHandler, MAIN_LINE, 0, limit, sarBuffer); + + // + // RSI ... + int copiedRSIs = CopyBuffer(rsiHandler, MAIN_LINE, 0, limit, rsiBuffer); + + // + // ADX ... + int copiedADXs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer); + + // + // ADX Plus ... + int copiedADXPs = CopyBuffer(adxHandler, PLUSDI_LINE, 0, limit, adxpBuffer); + + // + // ADX Negative ... + int copiedADXNs = CopyBuffer(adxHandler, MINUSDI_LINE, 0, limit, adxnBuffer); + + // + // TREND ... + int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit, trendBuffer); + + // + // Validate Copied Items ... + bool isPassedRequiredCopiedItems = + // + // ATR ... + copiedAtrs >= limit && + // + // SAR ... + copiedSars >= limit && + // + // RSI ... + copiedRSIs >= limit && + // + // TREND ... + copiedTrends >= 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 // + ); + } + + // + if (prev_calculated == 0) + { + // + string message = "History Finished ..."; + Print(message); + } + + // + return rates_total; +} + +// +// Custom Functions ... + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + // + IndicatorSetInteger(INDICATOR_DIGITS, _Digits); + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + sarMax > 0 && + sarStep > 0 && + rsiOBLevel > 0 && + rsiOSLevel > 0 && + adxThreshold > 0 && + sarMax > sarStep && + atrMultiplier > 0 && + // + IsValid(appliedCycle) && + // + IsValid(atrUpperPriceType) && + IsValid(atrLowerPriceType) && + // + // CYCLES ... + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mSCLength, mMCLength); + result = MathMax(result, mLCLength); + result = MathMax(result, mHCLength); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // Plot Buffers ... + + // + // SAR ... + + // + ArraySetAsSeries(sarBuffer, true); + SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_SHOW_DATA, showSar); + PlotIndexSetDouble(sarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sarBufferPlotIndex, PLOT_ARROW, sarArrowCode); + + // + ArraySetAsSeries(sarColorBuffer, true); + SetIndexBuffer(sarColorBufferIndex, sarColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(sarStateBuffer, true); + SetIndexBuffer(sarStateBufferIndex, sarStateBuffer, INDICATOR_CALCULATIONS); + + // + // PEAK / VALE ... + + // + ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE; + + // + // PEAK ... + + // + ArraySetAsSeries(peakBuffer, true); + SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode); + + // + // VALE ... + + // + ArraySetAsSeries(valeBuffer, true); + SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode); + + // + // PV GOLDEN ... + + // + ENUM_DRAW_TYPE pvGoldenDrawType = showPVGolden ? DRAW_LINE : DRAW_NONE; + + // + // PEAK Golden ... + + // + ArraySetAsSeries(peakGoldenBuffer, true); + SetIndexBuffer(peakGoldenBufferIndex, peakGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(peakGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(peakGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // VALE Golden ... + + // + ArraySetAsSeries(valeGoldenBuffer, true); + SetIndexBuffer(valeGoldenBufferIndex, valeGoldenBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_SHOW_DATA, showPVGolden); + PlotIndexSetInteger(valeGoldenBufferPlotIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); + + // + PlotIndexSetDouble(valeGoldenBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // ATR Band ... + + // + // UPPER ... + ENUM_DRAW_TYPE atrUpperDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrUpperBuffer, true); + SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrUpperBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrUpperBufferPlotIndex, PLOT_DRAW_TYPE, atrUpperDrawType); + + // + // LOWER ... + ENUM_DRAW_TYPE atrLowerDrawType = showATRBand ? DRAW_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atrLowerBuffer, true); + SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA); + + // + PlotIndexSetDouble(atrLowerBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_SHOW_DATA, showATRBand); + PlotIndexSetInteger(atrLowerBufferPlotIndex, PLOT_DRAW_TYPE, atrLowerDrawType); + + // + // TREND ... + + // + ArraySetAsSeries(trendBuffer, true); + SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrend); + PlotIndexSetDouble(trendBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + ArraySetAsSeries(trendColorBuffer, true); + SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); + + // + ArraySetAsSeries(trendStateBuffer, true); + SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); + + // + // SIGNAL Bar ... + + // + // Signal Bars Color ... + ArraySetAsSeries(sBarColorBuffer, true); + SetIndexBuffer(sBarColorBufferIndex, sBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(sBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(sBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(sBarOpenBuffer, true); + SetIndexBuffer(sBarOpenBufferIndex, sBarOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(sBarHighBuffer, true); + SetIndexBuffer(sBarHighBufferIndex, sBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(sBarLowBuffer, true); + SetIndexBuffer(sBarLowBufferIndex, sBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(sBarCloseBuffer, true); + SetIndexBuffer(sBarCloseBufferIndex, sBarCloseBuffer, INDICATOR_DATA); + + // + // XHK SIGNAL Bar ... + + // + // HK Bars Color ... + ArraySetAsSeries(hkSBarColorBuffer, true); + SetIndexBuffer(hkSBarColorBufferIndex, hkSBarColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on XHK Bar Buffer ... + PlotIndexSetDouble(hkSBarBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetInteger(hkSBarBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hkSBarOpenBuffer, true); + SetIndexBuffer(hkSBarOpenBufferIndex, hkSBarOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hkSBarHighBuffer, true); + SetIndexBuffer(hkSBarHighBufferIndex, hkSBarHighBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(hkSBarLowBuffer, true); + SetIndexBuffer(hkSBarLowBufferIndex, hkSBarLowBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(hkSBarCloseBuffer, true); + SetIndexBuffer(hkSBarCloseBufferIndex, hkSBarCloseBuffer, INDICATOR_DATA); + + // + // CYCLES ... + + // + // SHORT ... + + // + ENUM_DRAW_TYPE sDrawType = showShortCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(sHHBuffer, true); + SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sHHBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(sLLBuffer, true); + SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_SHOW_DATA, showShortCycle); + PlotIndexSetInteger(sLLBufferPlotIndex, PLOT_DRAW_TYPE, sDrawType); + PlotIndexSetDouble(sLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // MEDIUM ... + + // + ENUM_DRAW_TYPE mDrawType = showMediumCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(mHHBuffer, true); + SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mHHBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(mLLBuffer, true); + SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_SHOW_DATA, showMediumCycle); + PlotIndexSetInteger(mLLBufferPlotIndex, PLOT_DRAW_TYPE, mDrawType); + PlotIndexSetDouble(mLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LONG ... + + // + ENUM_DRAW_TYPE lDrawType = showLongCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(lHHBuffer, true); + SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lHHBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(lLLBuffer, true); + SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_SHOW_DATA, showLongCycle); + PlotIndexSetInteger(lLLBufferPlotIndex, PLOT_DRAW_TYPE, lDrawType); + PlotIndexSetDouble(lLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // HIND ... + + // + ENUM_DRAW_TYPE hDrawType = showHindCycle ? DRAW_LINE : DRAW_NONE; + + // + // HH ... + + // + ArraySetAsSeries(hHHBuffer, true); + SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hHHBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hHHBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // LL ... + + // + ArraySetAsSeries(hLLBuffer, true); + SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_SHOW_DATA, showHindCycle); + PlotIndexSetInteger(hLLBufferPlotIndex, PLOT_DRAW_TYPE, hDrawType); + PlotIndexSetDouble(hLLBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + + // + // Data Buffers ... + + // + // RSI ... + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); + + // + // ADX ... + + // + ArraySetAsSeries(adxBuffer, true); + SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxpBuffer, true); + SetIndexBuffer(adxpBufferIndex, adxpBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(adxnBuffer, true); + SetIndexBuffer(adxnBufferIndex, adxnBuffer, INDICATOR_CALCULATIONS); + + // + // DELTA ... + + // + ArraySetAsSeries(deltaBuffer, true); + SetIndexBuffer(deltaBufferIndex, deltaBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(deltaSignalBuffer, true); + SetIndexBuffer(deltaSignalBufferIndex, deltaSignalBuffer, INDICATOR_CALCULATIONS); + + // + // VOLUME ... + + // + ArraySetAsSeries(bullishVolumeBuffer, true); + SetIndexBuffer(bullishVolumeBufferIndex, bullishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeBuffer, true); + SetIndexBuffer(bearishVolumeBufferIndex, bearishVolumeBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bullishVolumeSignalBuffer, true); + SetIndexBuffer(bullishVolumeSignalBufferIndex, bullishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(bearishVolumeSignalBuffer, true); + SetIndexBuffer(bearishVolumeSignalBufferIndex, bearishVolumeSignalBuffer, INDICATOR_CALCULATIONS); + + // + // ATR ... + + ArraySetAsSeries(atrBuffer, true); + SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrUpperRawBuffer, true); + SetIndexBuffer(atrUpperRawBufferIndex, atrUpperRawBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(atrLowerRawBuffer, true); + SetIndexBuffer(atrLowerRawBufferIndex, atrLowerRawBuffer, INDICATOR_CALCULATIONS); + + // + // XHK ... + + // + ArraySetAsSeries(openHKBuffer, true); + SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(highHKBuffer, true); + SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(lowHKBuffer, true); + SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(closeHKBuffer, true); + SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_CALCULATIONS); + + // +} + +/** + * Initial Market Cycles ... + * + * @return ( bool ) + */ +bool InitCycles() +{ + // + bool result = false; + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + if (IsValid(mSCPeriod)) + { + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + if (IsValid(mMCPeriod)) + { + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + if (IsValid(mLCPeriod)) + { + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + if (IsValid(mHCPeriod)) + { + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + } + + // + result = mSCLength > 0 && + mMCLength > mSCLength && + mLCLength > mMCLength && + mHCLength > mLCLength; + + // + // Selecte Applied Cycle ... + if (result) + { + // + switch (appliedCycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + mAppliedLength = mSCLength; + mAppliedPeriod = mSCPeriod; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + mAppliedLength = mMCLength; + mAppliedPeriod = mMCPeriod; + break; + + // + case X_MARKET_CYCLE_LONG: + // + mAppliedLength = mLCLength; + mAppliedPeriod = mLCPeriod; + break; + + // + case X_MARKET_CYCLE_HIND: + // + mAppliedLength = mHCLength; + mAppliedPeriod = mHCPeriod; + break; + } + } + + // + return result; +} + +/** + * Initial all Indicator Requirements ... + * + * @return ( false ) + * + */ +bool InitRequirements() +{ + // + bool result = false; + + // + // Handlers ... + + // + // SAR ... + sarHandler = iSAR( + _Symbol, + _Period, + sarStep, + sarMax // + ); + result = sarHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ATR ... + atrHandler = iATR( + _Symbol, + _Period, + mAppliedLength // + ); + result = atrHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // RSI ... + rsiHandler = iRSI( + _Symbol, + _Period, + mAppliedLength, + rsiAppliedTo // + ); + result = rsiHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // ADX ... + adxHandler = iADX( + _Symbol, + _Period, + mAppliedLength // + ); + result = adxHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // TREND ... + trendHandler = iMA( + _Symbol, + _Period, + mAppliedLength, + 0, + trendMode, + trendAppliedTo // + ); + result = trendHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + // Initial Class Instances ... + + // + mDrawer = new XCPOIDrawer(); + mBarAnalyser = new XCBarAnalyser(); + + // + // Initialize and Configure Alert ... + mAlert = new XCAlert(); + mEnableAlerts = + _logAlerts || + _pushAlerts || + _mailAlerts || + _terminalAlerts; + string mPrefix = ShortName + + (!IsValid(mAlertPrefix) + ? "" + : "[" + mAlertPrefix + "]"); + mAlert.SetPrefix(mPrefix); + mAlert.SetLogAlerts(_logAlerts); + mAlert.SetMailAlerts(_mailAlerts); + mAlert.SetPushAlerts(_pushAlerts); + mAlert.SetEnableAlerts(mEnableAlerts); + mAlert.SetTerminalAlerts(_terminalAlerts); + + // + return result; +} + +/** + * Calculate Custom Buffers ... + * + * @param barIndex: 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 barIndex, + 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; + if (barsLimit == 0) + { + // + barsLimit = ratesTotal; + firstBarIndex = barsLimit - 1; + } + else + { + firstBarIndex = startCalculationForLastBars; + } + + // + // bool canCalculate = true; + bool canCalculate = + barIndex <= barsLimit; + if (canCalculate) + { + // + // Calculate Values ... + CalculateValues( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + } + else + { + FillBuffersZero(barIndex); + } +} + +/** + * Fill All Bufers to Zero Vlue for Specified Bar Index ... + * + * @param barIndex: Integer ... + */ +void FillBuffersZero(int barIndex) +{ + // + sarColorBuffer[barIndex] = hideColorIDX; + trendColorBuffer[barIndex] = hideColorIDX; + + // + atrUpperRawBuffer[barIndex] = emptyValue; + atrLowerRawBuffer[barIndex] = emptyValue; +} + +// +// Custom Handlers ... + +/** + * Calculate Values ... + * + * @param barIndex: 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 barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + int maxBarIndex = startCalculationForLastBars > 0 + ? startCalculationForLastBars + : ratesTotal; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + // Cycle Ranges ... + CalculateCycleRanges( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // PV ... + CalculatePV( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SAR ... + CalculateSAR( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // SBAR ... + CalculateSBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // HKBAR ... + CalculateHKBar( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // DELTA ... + CalculateDelta( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // TREND ... + CalculateTrend( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // VOLUME ... + CalculateVolume( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // ATR Band ... + CalculateATRBand( + barIndex, + prevCalculated, + ratesTotal, + open, + high, + close, + low, + tickVolume // + ); + + // + // Try To Detect Trigger Block ... + + // + // Prevent Calculation ... + if (maxBarIndex - barIndex < maxLength) + { + return; + } + + // + XTriggerBlock tb; + bool has = DetectTriggerBlock( + // + _Symbol, + _Period, + // + tb, + // + mBarAnalyser, + // + // Required Buffers ... + atrBuffer, + rsiBuffer, + adxBuffer, + adxpBuffer, + adxnBuffer, + peakBuffer, + valeBuffer, + deltaBuffer, + sarBuffer, + sarStateBuffer, + trendBuffer, + trendStateBuffer, + atrUpperBuffer, + atrLowerBuffer, + sBarOpenBuffer, + sBarCloseBuffer, + hkSBarOpenBuffer, + hkSBarCloseBuffer, + peakGoldenBuffer, + valeGoldenBuffer, + deltaSignalBuffer, + bullishVolumeSignalBuffer, + bearishVolumeSignalBuffer, + // + barIndex, + // + // Signalling ... + signalR2R, + slAtrMultiplier, + // + // Configs ... + rsiOBLevel, + rsiOSLevel, + adxThreshold, + // + // Validators ... + forceObBarType, + forceOBFVGBarType, + forceHasSwing, + forceHasFLiquidity, + forceHasRLiquidity, + validateGapSequence, + validateBlockEdgeBreakout, + // + // Filters ... + filterBasedOnPV, + filterBasedOnSar, + filterBasedOnRSI, + filterBasedOnADX, + filterBasedOnATR, + filterBasedOnTrend, + filterBasedOnDelta, + filterBasedOnVolume, + filterBasedOnSignalBar, + filterBasedOnHKSignalBar // + ); + if (has) + { + // + // Draw ... + if (drawTriggerBlock) + { + // + has = DrawTriggerBlock( + tb, + mDrawer, + mObjects, + NULL, + drawSignals // + ); + } + + // + // Alert ... + bool canAlert = + mEnableAlerts && + prevCalculated > 0; + bool canLogOnly = + mEnableAlerts && + prevCalculated == 0; + if (has && + (canAlert || + canLogOnly)) + { + // + string message = + tb.trigger.symbol + "," + + ToString(tb.trigger.period) + "> " + + ToString(tb.trigger.dir) + + " Zone Detected at: " + ToString(tb.trigger.to); + + // + if (canLogOnly) + { + mAlert.LogAlert(message); + } + else if (canAlert) + { + mAlert.SendAlert(message); + } + } + } +} + +// +void CalculateCycleRanges( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // SHORT ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_SHORT, + sHHBuffer, + sLLBuffer // + ); + + // + // MEDIUM ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_MEDIUM, + mHHBuffer, + mLLBuffer // + ); + + // + // LONG ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_LONG, + lHHBuffer, + lLLBuffer // + ); + + // + // HIND ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_HIND, + hHHBuffer, + hLLBuffer // + ); +} + +// +void CalculatePV( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iSHH = sHHBuffer[barIndex]; + double iSLL = sLLBuffer[barIndex]; + + // + double iMHH = mHHBuffer[barIndex]; + double iMLL = mLLBuffer[barIndex]; + + // + double iLHH = lHHBuffer[barIndex]; + double iLLL = lLLBuffer[barIndex]; + + // + double iHHH = hHHBuffer[barIndex]; + double iHLL = hLLBuffer[barIndex]; + + // + // Calculate VALE ... + bool isVale = iSLL == iMLL && + iMLL == iLLL && + iLLL == iHLL; + double iPVale = + isFirstBar + ? emptyValue + : valeBuffer[lastBarIndex]; + double iVale = + isVale + ? iSLL + : iPVale; + valeBuffer[barIndex] = iVale; + + // + // Calculate PEAK ... + bool isPeak = iSHH == iMHH && + iMHH == iLHH && + iLHH == iHHH; + double iPPeak = + isFirstBar + ? emptyValue + : peakBuffer[lastBarIndex]; + double iPeak = + isPeak + ? iSHH + : iPPeak; + peakBuffer[barIndex] = iPeak; + + // + // GOLDEN ... + + XOHCL iBar; + bool isInited = iBar.Init( + _Symbol, + _Period, + barIndex // + ); + + // + // Calculate PV Gold ... + double lastPeakGold = + isFirstBar + ? emptyValue + : peakGoldenBuffer[lastBarIndex]; + double lastValeGold = + isFirstBar + ? emptyValue + : valeGoldenBuffer[lastBarIndex]; + double iPeakGold = lastPeakGold; + double iValeGold = lastValeGold; + if (isInited) + { + // + iPeakGold = iBar.FindHighest(mHCLength, MODE_CLOSE); + if (iPeakGold == 0) + { + iPeakGold = lastPeakGold; + } + + // + iValeGold = iBar.FindLowest(mHCLength, MODE_CLOSE); + if (iValeGold == 0) + { + iValeGold = lastValeGold; + } + } + else + { + // + iPeakGold = lastPeakGold; + iValeGold = lastValeGold; + } + + // + peakGoldenBuffer[barIndex] = iPeakGold; + valeGoldenBuffer[barIndex] = iValeGold; + + // + iBar.Clean(); +} + +// +void CalculateSAR( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = low[barIndex]; + double iSar = sarBuffer[barIndex]; + + // + bool isBullish = iSar < iLow; + bool isBearish = iSar > iHigh; + + // + double iSarState = isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iSarColor = iSarState > 0 + ? bullishColorIDX + : iSarState < 0 + ? bearishColorIDX + : neuturalColorIDX; + sarStateBuffer[barIndex] = iSarState; + sarColorBuffer[barIndex] = showSar + ? iSarColor + : hideColorIDX; +} + +// +void CalculateSBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + open, + sBarOpenBuffer, + barsSignalMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + close, + sBarCloseBuffer, + barsSignalMethod // + ); + + // + double min = MathMin(sBarCloseBuffer[barIndex], sBarOpenBuffer[barIndex]); + double max = MathMin(sBarCloseBuffer[barIndex], sBarOpenBuffer[barIndex]); + + // + sBarLowBuffer[barIndex] = min; + sBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iSignalColorValue = + sBarOpenBuffer[barIndex] < sBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + sBarColorBuffer[barIndex] = + showSignalBars + ? iSignalColorValue + : hideColorIDX; +} + +// +void CalculateHKBar( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double lastHKOpen = + isFirstBar + ? emptyValue + : openHKBuffer[lastBarIndex]; + double lastHKClose = + isFirstBar + ? emptyValue + : closeHKBuffer[lastBarIndex]; + + // + double iHKOpenValue = (lastHKOpen + lastHKClose) / 2; + double iHKCloseValue = (open[barIndex] + high[barIndex] + close[barIndex] + low[barIndex]) / 4; + double iHKHighValue = MathMax(high[barIndex], MathMax(iHKOpenValue, iHKCloseValue)); + double iHKLowValue = MathMin(low[barIndex], MathMin(iHKOpenValue, iHKCloseValue)); + + // + // Raw HK Buffers ... + openHKBuffer[barIndex] = iHKOpenValue; + highHKBuffer[barIndex] = iHKHighValue; + lowHKBuffer[barIndex] = iHKLowValue; + closeHKBuffer[barIndex] = iHKCloseValue; + + // + // XHK Signal ... + + // + // Open ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + openHKBuffer, + hkSBarOpenBuffer, + hkSignalBarMethod // + ); + + // + // Close ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + closeHKBuffer, + hkSBarCloseBuffer, + hkSignalBarMethod // + ); + + // + double min = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + double max = MathMin(hkSBarCloseBuffer[barIndex], hkSBarOpenBuffer[barIndex]); + + // + hkSBarLowBuffer[barIndex] = min; + hkSBarHighBuffer[barIndex] = max; + + // + // Calculate HK Signal Color ... + double iHKSignalColorValue = + hkSBarOpenBuffer[barIndex] < hkSBarCloseBuffer[barIndex] + ? bullishColorIDX + : bearishColorIDX; + hkSBarColorBuffer[barIndex] = + showHKSignalBars + ? iHKSignalColorValue + : hideColorIDX; +} + +// +void CalculateDelta( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + int lastBarIndex = barIndex + 1; + bool isFirstBar = + startCalculationForLastBars > 0 + ? barIndex == startCalculationForLastBars + : barIndex == firstBarIndex; + + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + // DELTA ... + double lastDelta = + isFirstBar + ? emptyValue + : deltaBuffer[lastBarIndex]; + double iAppliedVolume = + isBullish + ? iVolume + : -1 * iVolume; + double iDelta = + lastDelta + iAppliedVolume; + deltaBuffer[barIndex] = iDelta; + + // + // Calculate Delta Signal ... + int deltaSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + deltaBuffer, + deltaSignalBuffer, + deltaSignalMethod // + ); +} + +// +void CalculateTrend( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iLow = low[barIndex]; + double iHigh = high[barIndex]; + double iClose = close[barIndex]; + double iTrend = trendBuffer[barIndex]; + + // + bool isBullish = iTrend < iLow; + bool isBearish = iTrend > iHigh; + + // + double iTrendState = + isBullish + ? 1 + : isBearish + ? -1 + : 0; + double iTrendColor = + iTrendState > 0 + ? bullishColorIDX + : iTrendState < 0 + ? bearishColorIDX + : neuturalColorIDX; + trendStateBuffer[barIndex] = iTrendState; + trendColorBuffer[barIndex] = showTrend + ? iTrendColor + : hideColorIDX; +} + +// +void CalculateVolume( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iClose = close[barIndex]; + double iOpen = open[barIndex]; + double iVolume = (double)iVolume(_Symbol, _Period, barIndex); + + // + bool isBullish = iClose > iOpen; + bool isBearish = iClose < iOpen; + + // + double iBullishVolume = emptyValue; + double iBearishVolume = emptyValue; + if (isBullish) + { + iBullishVolume = iVolume; + } + else if (isBearish) + { + iBearishVolume = iVolume; + } + else + { + // + double iHalfVolume = iVolume / 2; + + // + iBullishVolume = iHalfVolume; + iBearishVolume = iHalfVolume; + } + bullishVolumeBuffer[barIndex] = iBullishVolume; + bearishVolumeBuffer[barIndex] = iBearishVolume; + + // + // Calculate Volume Signals ... + + // + int bullishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bullishVolumeBuffer, + bullishVolumeSignalBuffer, + volumeSignalMethod // + ); + + // + int bearishVolumeSignalsCount = iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + bearishVolumeBuffer, + bearishVolumeSignalBuffer, + volumeSignalMethod // + ); +} + +// +void CalculateATRBand( + int barIndex, + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[], + const long &tickVolume[] // +) +{ + // + double iATR = atrBuffer[barIndex]; + double iAppliedATR = atrMultiplier * iATR; + double iATRUpperPrice = GetAppliedPrice( + atrUpperPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRLowerPrice = GetAppliedPrice( + atrLowerPriceType, + open, + high, + low, + close, + barIndex // + ); + double iATRUpper = iATRUpperPrice + iAppliedATR; + double iATRLower = iATRLowerPrice - iAppliedATR; + atrUpperRawBuffer[barIndex] = iATRUpper; + atrLowerRawBuffer[barIndex] = iATRLower; + + // + bool canSignalATR = IsValid(atrSignalMethod); + if (canSignalATR) + { + // + // Upper ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrUpperRawBuffer, + atrUpperBuffer, + atrSignalMethod // + ); + + // + // Lower ... + iMAOnBuffer( + ratesTotal, + prevCalculated, + barIndex, + mAppliedLength, + atrLowerRawBuffer, + atrLowerBuffer, + atrSignalMethod // + ); + } + else + { + // + atrUpperBuffer[barIndex] = iATRUpper; + atrLowerBuffer[barIndex] = iATRLower; + } +} + +/** + * Calculate Specified Market Cycle Info ... + * + * @param barIndex: Integer, Bar Index ... + * @param cycle: ENUM_X_MARKET_CYCLES member, Specified Cycle ... + * @param hhBuffer: Highest High Buffer Reference ... + * @param llBuffer: Lowest Low Buffer Reference ... + */ +void CalculateCycle( + int barIndex, + ENUM_X_MARKET_CYCLES cycle, + double &hhBuffer[], + double &llBuffer[] // +) +{ + // + XOHCL bar; + bool isBarInited = bar.Init( + _Symbol, + _Period, + barIndex + // + ); + if (!isBarInited) + { + return; + } + + // + int mLength = 0; + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + mLength = mSCLength; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + mLength = mMCLength; + break; + + // + case X_MARKET_CYCLE_LONG: + mLength = mLCLength; + break; + + // + case X_MARKET_CYCLE_HIND: + mLength = mHCLength; + break; + } + + // + if (mLength == 0) + { + return; + } + + // + // Find Highest High ... + double hhValue = bar.FindHighest( + mLength, + upperMode // + ); + hhBuffer[barIndex] = hhValue; + + // + // Find Lowest Low ... + double llValue = bar.FindLowest( + mLength, + lowerMode // + ); + llBuffer[barIndex] = llValue; + + // + bar.Clean(); +} + +// +void ReadBarStyle() +{ + // + long chartId = ChartID(); + + // + _upColor = GetChartUpColor(chartId); + _downColor = GetChartDownColor(chartId); + _lineColor = GetChartLineColor(chartId); + _bullishColor = GetChartBullishColor(chartId); + _bearishColor = GetChartBearishColor(chartId); +} + +// +void ShowBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(_upColor, chartId); + SetChartDownColor(_downColor, chartId); + SetChartLineColor(_lineColor, chartId); + SetChartBullishColor(_bullishColor, chartId); + SetChartBearishColor(_bearishColor, chartId); +} + +// +void HideBars() +{ + // + long chartId = ChartID(); + + // + SetChartUpColor(CLR_NONE, chartId); + SetChartDownColor(CLR_NONE, chartId); + SetChartLineColor(CLR_NONE, chartId); + SetChartBullishColor(CLR_NONE, chartId); + SetChartBearishColor(CLR_NONE, chartId); +} + +// \ No newline at end of file diff --git a/Experts/xcatb.test.ea.mq5 b/Experts/xcatb.test.ea.mq5 index f488a06d..7ff5a07e 100644 --- a/Experts/xcatb.test.ea.mq5 +++ b/Experts/xcatb.test.ea.mq5 @@ -26,9 +26,8 @@ #include "../Classes/x-saherelm.x-trade.class.mq5" #include "../Classes/x-saherelm.x-volume.class.mq5" #include "../Helpers/x-saherelm.x121.xcatb.helper.mq5" -#include "../Libraries/x-saherelm.common.lib.mq5" -#include "../Libraries/x-saherelm.x121.xcatb.lib.mq5" -#include "../XCAEA/Classes/xcaea.x-trade.manager.class.mq5" +#include "../XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5" +#include "../XCATBEA/Libraries/xcatbea.signaller.lib.mq5" // #define ShortName "XCATBEA" @@ -97,7 +96,7 @@ input bool eaAllowTrade = true; input bool eaAllowLongs = true; // Allow Long Trades input bool eaAllowShorts = true; // Allow Short Trades input string eaSessions = ""; // Active Sessions -input ENUM_XCAEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCAEA_TRADE_RESTRICATION_NONE; // Restrictions Period +input ENUM_XCATBEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod = XCATBEA_TRADE_RESTRICATION_NONE; // Restrictions Period input int eaMaxAllowedTPs = 0; // Max Allowed TP(s) in Restrictions Period input int eaMaxAllowedSLs = 0; // Max Allowed SL(s) in Restrictions Period input int eaMaxAllowedTrades = 0; // Max Allowed Trades in Restrictions Period @@ -145,8 +144,8 @@ X121XCatbInputs eaInputs; XTimeTracker eaTimeTracker; XCX121XCatbHelper *eaHelper; XCBarAnalyser *eaBarAnalyser; -XCXCAEATradeManager *eaTradeManager; -XCAEAStrategyConditions eaConditions; +XCXCATBEATradeManager *eaTradeManager; +XCATBEAStrategyConditions eaConditions; // // Event Handlers ... @@ -299,77 +298,6 @@ void OnTick() // Check Trigger Block Detected or Not ... if (tradeUsingTriggerBlock) { - // - // XTriggerBlock iTB; - // X121XCatbConditions iConditions; - // has = DetectTriggerBlock( - // // - // _Symbol, - // _Period, - // // - // iTB, - // // - // eaDrawer, - // eaBarAnalyser, - // // - // // Required Buffers ... - // eaHelper.atrBuffer, - // eaHelper.rsiBuffer, - // eaHelper.adxBuffer, - // eaHelper.adxpBuffer, - // eaHelper.adxnBuffer, - // eaHelper.peakBuffer, - // eaHelper.valeBuffer, - // eaHelper.deltaBuffer, - // eaHelper.sarBuffer, - // eaHelper.sarStateBuffer, - // eaHelper.trendBuffer, - // eaHelper.trendStateBuffer, - // eaHelper.atrUpperBuffer, - // eaHelper.atrLowerBuffer, - // eaHelper.sBarOpenBuffer, - // eaHelper.sBarCloseBuffer, - // eaHelper.hkSBarOpenBuffer, - // eaHelper.hkSBarCloseBuffer, - // eaHelper.peakGoldenBuffer, - // eaHelper.valeGoldenBuffer, - // eaHelper.deltaSignalBuffer, - // eaHelper.bullishVolumeSignalBuffer, - // eaHelper.bearishVolumeSignalBuffer, - // // - // cBarIndex, - // // - // // Signalling ... - // eaInputs.signalR2R, - // eaInputs.slAtrMultiplier, - // // - // // Configs ... - // eaInputs.rsiOBLevel, - // eaInputs.rsiOSLevel, - // eaInputs.adxThreshold, - // // - // // Validators ... - // eaInputs.forceObBarType, - // eaInputs.forceOBFVGBarType, - // eaInputs.forceHasSwing, - // eaInputs.forceHasFLiquidity, - // eaInputs.forceHasRLiquidity, - // eaInputs.validateGapSequence, - // eaInputs.validateBlockEdgeBreakout, - // // - // // Filters ... - // eaInputs.filterBasedOnPV, - // eaInputs.filterBasedOnSar, - // eaInputs.filterBasedOnRSI, - // eaInputs.filterBasedOnADX, - // eaInputs.filterBasedOnATR, - // eaInputs.filterBasedOnTrend, - // eaInputs.filterBasedOnDelta, - // eaInputs.filterBasedOnVolume, - // eaInputs.filterBasedOnSignalBar, - // eaInputs.filterBasedOnHKSignalBar // - // ); - // // Define Requirements ... XTriggerBlock iTB; @@ -869,7 +797,7 @@ void InitRequirements() // // EA Trae Manager ... - eaTradeManager = new XCXCAEATradeManager( + eaTradeManager = new XCXCATBEATradeManager( eaTrade // ); eaTradeManager.SaveTrades(true); diff --git a/Helpers/x-saherelm.x121.xcatb.helper.mq5 b/Helpers/x-saherelm.x121.xcatb.helper.mq5 index fb3752fe..6bfab823 100644 --- a/Helpers/x-saherelm.x121.xcatb.helper.mq5 +++ b/Helpers/x-saherelm.x121.xcatb.helper.mq5 @@ -23,6 +23,7 @@ // // Imports ... #include "../Classes/x-saherelm.x-helper.class.mq5" +#include "../Libraries/x-saherelm.x-poi.lib.mq5" // // Definitions ... diff --git a/Indicators/x-saherelm.x121.x3ma.mq5 b/Indicators/x-saherelm.x121.x3ma.mq5 deleted file mode 100644 index e5355715..00000000 --- a/Indicators/x-saherelm.x121.x3ma.mq5 +++ /dev/null @@ -1,788 +0,0 @@ -/////////////////////////////////////////////////////// -// -// 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; // Method -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; // Method -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; // Method -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 showMedium = true; // Show Medium -input bool showSlow = 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/Indicators/x-saherelm.x121.xatr.mq5 b/Indicators/x-saherelm.x121.xatr.mq5 deleted file mode 100644 index 08dbc820..00000000 --- a/Indicators/x-saherelm.x121.xatr.mq5 +++ /dev/null @@ -1,882 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Indicator -// ------------------------------------------------- -// Name: X121 XATR -// Description: XATR ... -// -// -// 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 XATR Indicator" -#property strict - -// -// Definitions ... - -// -#define ShortName "X121 XATR" - -// -// Includes Common Library ... -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// Inputs ... - -// -// Market ... -input group "Market"; - -// -input group "RSI Detection"; -input int rsiLength = 14; // Length -input ENUM_X_PRICE rsiPriceType = X_PRICE_CLOSE; // Applied To -input ENUM_X_MA_METHOD rsiSmoothingMethod = X_MA_MODE_SMA; // Smoothing Method; - -// -input group "ATR Detection"; -input int atrLength = 14; // Length -input double atrMultiplier = 1; // Multiplier -input ENUM_X_PRICE atrUpperPriceType = X_PRICE_HIGH; // Upper Zone Applied To -input ENUM_X_PRICE atrLowerPriceType = X_PRICE_LOW; // Lower Zone Applied To -input ENUM_X_MA_METHOD atrSmoothingMethod = X_MA_MODE_SMA; // Smoothing Method - -// -input group "Price Change"; -input int priceChangeSmoothingLength = 14; // Length -input ENUM_X_PRICE priceChangeType = X_PRICE_CLOSE; // Price Type -input ENUM_X_MA_METHOD priceChangeSmoothingMethod = X_MA_MODE_SMA; // Moving Average Moethod - -// -input group "Presentation"; - -// -input int startCalculationForLastBars = 1000; // Calculate Last n Bars - -// -input bool showAtrUpper = true; // Show Upper Zone -input bool showAtrLower = true; // Show Lower Zone -input bool showSmoothedAtrUpper = true; // Show Smoothed Upper Zone -input bool showSmoothedAtrLower = true; // Show Smoothed Lower Zone -input bool showRSIChange = true; // Show RSI Change -input bool showSmoothedRSIChange = true; // ShowSmoothed RSI Change -input bool showPriceChange = true; // Show Price Change -input bool showSmoothedPriceChange = true; // ShowSmoothed Price Change - -// -// Buffers ... - -// -#define hideColorIDX 0 -#define bullishColorIDX 1 -#define bearishColorIDX 2 -#define neuturalColorIDX 3 - -// -#property indicator_chart_window - -// -#property indicator_buffers 10 -#property indicator_plots 8 - -// -// ATR ... - -// -// Upper ... - -// -#define atrUpperBufferIndex 0 -double atrUpperBuffer[]; - -#property indicator_label1 "X121 ATRU" -#property indicator_type1 DRAW_LINE -#property indicator_color1 clrYellow -#property indicator_style1 STYLE_SOLID -#property indicator_width1 1 - -// -// Lower ... - -// -#define atrLowerBufferIndex 1 -double atrLowerBuffer[]; - -#property indicator_label2 "X121 ATRL" -#property indicator_type2 DRAW_LINE -#property indicator_color2 clrYellow -#property indicator_style2 STYLE_SOLID -#property indicator_width2 1 - -// -// ATR Smoothed ... - -// -// Upper ... - -// -#define atrSmoothedUpperBufferIndex 2 -double atrSmoothedUpperBuffer[]; - -#property indicator_label3 "X121 ATRUSM" -#property indicator_type3 DRAW_LINE -#property indicator_color3 clrYellow -#property indicator_style3 STYLE_DASH -#property indicator_width3 1 - -// -// Lower ... - -// -#define atrSmoothedLowerBufferIndex 3 -double atrSmoothedLowerBuffer[]; - -#property indicator_label4 "X121 ATRLSM" -#property indicator_type4 DRAW_LINE -#property indicator_color4 clrYellow -#property indicator_style4 STYLE_DASH -#property indicator_width4 1 - -// -// Price Change ... - -// -#define priceChangeBufferIndex 4 -double priceChangeBuffer[]; - -#property indicator_label5 "X121 PCH" -#property indicator_type5 DRAW_LINE -#property indicator_color5 clrOrchid -#property indicator_style5 STYLE_SOLID -#property indicator_width5 1 - -// -// Price Change Smoothed ... - -// -#define priceChangeSmoothedBufferIndex 5 -double priceChangeSmoothedBuffer[]; - -#property indicator_label6 "X121 PCHSM" -#property indicator_type6 DRAW_LINE -#property indicator_color6 clrOrchid -#property indicator_style6 STYLE_SOLID -#property indicator_width6 1 - -// -// RSI Change ... - -// -#define rsiChangeBufferIndex 6 -double rsiChangeBuffer[]; - -#property indicator_label7 "X121 RSICH" -#property indicator_type7 DRAW_LINE -#property indicator_color7 clrCornflowerBlue -#property indicator_style7 STYLE_SOLID -#property indicator_width7 1 - -// -// RSI Change Smoothed ... - -// -#define rsiChangeSmoothedBufferIndex 7 -double rsiChangeSmoothedBuffer[]; - -#property indicator_label8 "X121 RSICHSM" -#property indicator_type8 DRAW_LINE -#property indicator_color8 clrCornflowerBlue -#property indicator_style8 STYLE_SOLID -#property indicator_width8 1 - -// -// Data Buffers ... - -// -int mLastBufferIndex = 7; - -// -// ATR ... - -#define atrBufferIndex mLastBufferIndex + 1 -double atrBuffer[]; - -// -// RSI ... -#define rsiBufferIndex mLastBufferIndex + 2 -double rsiBuffer[]; - -// -// Variables, Properties and etc ... - -// -// this counts Available Bars ... -int limit; - -// -int maxLength; - -// -// RSI Handler ... -int rsiHandler = INVALID_HANDLE; - -// -// ATR Handler ... -int atrHandler = INVALID_HANDLE; - -// -ENUM_APPLIED_PRICE rsiAppliedTo = ToAppliedPrice(rsiPriceType); - -// -// Event Handlers ... - -/** - * Initialize Indicator ... - * - * @return ( int ) - */ -int OnInit() -{ - // - // Validate Inputs ... - if (!ValidateInputs()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - // Initialize Indicator Handlers ... - - // - // RSI ... - rsiHandler = iRSI( - _Symbol, - _Period, - rsiLength, - rsiAppliedTo // - ); - bool isInited = rsiHandler != INVALID_HANDLE; - if (!isInited) - { - return INIT_FAILED; - } - - // - // ATR ... - atrHandler = iATR( - _Symbol, - _Period, - atrLength // - ); - isInited = atrHandler != 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(rsiHandler); - IndicatorRelease(atrHandler); -} - -/** - * 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); - - // - // Fill All Buffers by Zero ... - if (prev_calculated == 0) - { - } - - // - // Validate Calculated Bars ... - - // - // RSI ... - int rsiCalculatedBars = BarsCalculated(rsiHandler); - - // - // ATR ... - int atrCalculatedBars = BarsCalculated(atrHandler); - - // - bool isPassedRequiredCalculatedBars = - // - // RSI ... - rsiCalculatedBars >= maxLength && - // - // ATR ... - atrCalculatedBars >= maxLength - // - ; - if (!isPassedRequiredCalculatedBars) - { - return prev_calculated; - } - - // - limit = (prev_calculated > rates_total || prev_calculated <= 0) - ? rates_total - : (rates_total - prev_calculated) + 1; - - // - // Buffers Copy ... - - // - // RSI ... - int copiedRsis = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); - - // - // ATR ... - int copiedAtrs = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer); - - // - // Validate Copied Items ... - bool isPassedRequiredCopiedItems = - // - // - // RSI ... - copiedRsis > 0 && - // - // ATR ... - copiedAtrs > 0 - // - ; - 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 = - // - // RSI ... - rsiLength > 0 && - // - // ATR ... - atrLength > 0 && - atrMultiplier > 0 && - // - priceChangeSmoothingLength > 0 && - // - IsValid(rsiPriceType) && - IsValid(priceChangeType) && - IsValid(atrUpperPriceType) && - IsValid(atrLowerPriceType) - // - ; - - // - return result; -} - -/** - * Extract Max Length of Inputs ... - * - * @return ( int ) - */ -int ExtractMaxLengthOfInputs() -{ - // - int result = 0; - - // - result = MathMax(rsiLength, atrLength); - result = MathMax(result, priceChangeSmoothingLength); - - // - return result; -} - -/** - * Define Required Buffers ... - */ -void DefineBuffers() -{ - // - // ATR ... - - // - // UPPER ... - ENUM_DRAW_TYPE atrUpperDrawType = showAtrUpper ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(atrUpperBuffer, true); - SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA); - PlotIndexSetDouble(atrUpperBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); - PlotIndexSetInteger(atrUpperBufferIndex, PLOT_SHOW_DATA, showAtrUpper); - PlotIndexSetInteger(atrUpperBufferIndex, PLOT_DRAW_TYPE, atrUpperDrawType); - - // - // LOWER ... - ENUM_DRAW_TYPE atrLowerDrawType = showAtrLower ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(atrLowerBuffer, true); - SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA); - PlotIndexSetDouble(atrLowerBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); - PlotIndexSetInteger(atrLowerBufferIndex, PLOT_SHOW_DATA, showAtrLower); - PlotIndexSetInteger(atrLowerBufferIndex, PLOT_DRAW_TYPE, atrLowerDrawType); - - // - // ATR Smoothed ... - - // - // UPPER ... - ENUM_DRAW_TYPE atrSmoothedUpperDrawType = showSmoothedAtrUpper ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(atrSmoothedUpperBuffer, true); - SetIndexBuffer(atrSmoothedUpperBufferIndex, atrSmoothedUpperBuffer, INDICATOR_DATA); - PlotIndexSetDouble(atrSmoothedUpperBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); - PlotIndexSetInteger(atrSmoothedUpperBufferIndex, PLOT_SHOW_DATA, showSmoothedAtrUpper); - PlotIndexSetInteger(atrSmoothedUpperBufferIndex, PLOT_DRAW_TYPE, atrSmoothedUpperDrawType); - - // - // LOWER ... - ENUM_DRAW_TYPE atrSmoothedLowerDrawType = showSmoothedAtrLower ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(atrSmoothedLowerBuffer, true); - SetIndexBuffer(atrSmoothedLowerBufferIndex, atrSmoothedLowerBuffer, INDICATOR_DATA); - PlotIndexSetDouble(atrSmoothedLowerBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); - PlotIndexSetInteger(atrSmoothedLowerBufferIndex, PLOT_SHOW_DATA, showSmoothedAtrLower); - PlotIndexSetInteger(atrSmoothedLowerBufferIndex, PLOT_DRAW_TYPE, atrSmoothedLowerDrawType); - - // - // PriceChange ... - ENUM_DRAW_TYPE priceChangeDrawType = showPriceChange ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(priceChangeBuffer, true); - SetIndexBuffer(priceChangeBufferIndex, priceChangeBuffer, INDICATOR_DATA); - PlotIndexSetDouble(priceChangeBufferIndex, PLOT_EMPTY_VALUE, 0.0); - PlotIndexSetInteger(priceChangeBufferIndex, PLOT_SHOW_DATA, showPriceChange); - PlotIndexSetInteger(priceChangeBufferIndex, PLOT_DRAW_TYPE, priceChangeDrawType); - - // - // PriceChange Smoothed ... - ENUM_DRAW_TYPE priceChangeSmoothedaDrawType = showSmoothedPriceChange ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(priceChangeSmoothedBuffer, true); - SetIndexBuffer(priceChangeSmoothedBufferIndex, priceChangeSmoothedBuffer, INDICATOR_DATA); - PlotIndexSetDouble(priceChangeSmoothedBufferIndex, PLOT_EMPTY_VALUE, 0.0); - PlotIndexSetInteger(priceChangeSmoothedBufferIndex, PLOT_SHOW_DATA, showSmoothedPriceChange); - PlotIndexSetInteger(priceChangeSmoothedBufferIndex, PLOT_DRAW_TYPE, priceChangeSmoothedaDrawType); - - // - // RSIChange ... - ENUM_DRAW_TYPE rsiChangeDrawType = showRSIChange ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(rsiChangeBuffer, true); - SetIndexBuffer(rsiChangeBufferIndex, rsiChangeBuffer, INDICATOR_DATA); - PlotIndexSetDouble(rsiChangeBufferIndex, PLOT_EMPTY_VALUE, 0.0); - PlotIndexSetInteger(rsiChangeBufferIndex, PLOT_SHOW_DATA, showRSIChange); - PlotIndexSetInteger(rsiChangeBufferIndex, PLOT_DRAW_TYPE, rsiChangeDrawType); - - // - // RSIChangeMa ... - ENUM_DRAW_TYPE rsiChangeMaDrawType = showSmoothedRSIChange ? DRAW_LINE : DRAW_NONE; - ArraySetAsSeries(rsiChangeSmoothedBuffer, true); - SetIndexBuffer(rsiChangeSmoothedBufferIndex, rsiChangeSmoothedBuffer, INDICATOR_DATA); - PlotIndexSetDouble(rsiChangeSmoothedBufferIndex, PLOT_EMPTY_VALUE, 0.0); - PlotIndexSetInteger(rsiChangeSmoothedBufferIndex, PLOT_SHOW_DATA, showSmoothedRSIChange); - PlotIndexSetInteger(rsiChangeSmoothedBufferIndex, PLOT_DRAW_TYPE, rsiChangeMaDrawType); - - // - // Data Buffers ... - - // - // ATR ... - ArraySetAsSeries(atrBuffer, true); - SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); - - // - // RSI ... - ArraySetAsSeries(rsiBuffer, true); - SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); -} - -/** - * Set Indicator Short Name and also we can define Buffers Labels ... - */ -void SetIndicatorName() -{ - // - IndicatorSetString(INDICATOR_SHORTNAME, ShortName); - IndicatorSetInteger(INDICATOR_DIGITS, 2); -} - -/** - * 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) - { - // - CalculateAtrZones( - bar_index, - prevCalculated, - ratesTotal, - open, - high, - close, - low // - ); - } - else - { - FillBuffersZero(bar_index); - } -} - -// -// Custom ... - -/** - * Fill All Bufers to Zero Vlue for Specified Bar Index ... - * - * @param barIndex: Integer ... - */ -void FillBuffersZero(int barIndex) -{ - // - rsiBuffer[barIndex] = 0; - atrBuffer[barIndex] = 0; - atrUpperBuffer[barIndex] = 0; - atrLowerBuffer[barIndex] = 0; - rsiChangeBuffer[barIndex] = 0; - priceChangeBuffer[barIndex] = 0; - atrSmoothedUpperBuffer[barIndex] = 0; - atrSmoothedLowerBuffer[barIndex] = 0; - rsiChangeSmoothedBuffer[barIndex] = 0; - priceChangeSmoothedBuffer[barIndex] = 0; -} - -/** - * Calculate ATR Zones ... - * - * @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 ... - */ -void CalculateAtrZones( - int bar_index, // Selected Bar Index - const int prevCalculated, - const int ratesTotal, - const double &open[], - const double &high[], - const double &close[], - const double &low[] // -) -{ - // - double points = GetPoints(_Symbol); - - // - // ATR Calculations ... - double iAtr = atrBuffer[bar_index]; - double iMultiPliedAtr = iAtr * atrMultiplier; - - // - // Select Upper Price ... - double iUpperPrice = GetAppliedPrice( - atrUpperPriceType, - open, - high, - low, - close, - bar_index // - ); - - // - // Select Lower Price ... - double iLowerPrice = GetAppliedPrice( - atrLowerPriceType, - open, - high, - low, - close, - bar_index // - ); - - // - // Calculate Atrs ... - - // - double iAtrUpper = iUpperPrice + iMultiPliedAtr; - double iAtrLower = iLowerPrice - iMultiPliedAtr; - - // - atrUpperBuffer[bar_index] = iAtrUpper; - atrLowerBuffer[bar_index] = iAtrLower; - - // - bool canSmoothAtr = atrSmoothingMethod != X_MA_MODE_NONE; - if (canSmoothAtr) - { - // - // Upper ... - iMAOnBuffer( - ratesTotal, - prevCalculated, - bar_index, - atrLength, - atrUpperBuffer, - atrSmoothedUpperBuffer, - atrSmoothingMethod // - ); - - // - // Lower ... - iMAOnBuffer( - ratesTotal, - prevCalculated, - bar_index, - atrLength, - atrLowerBuffer, - atrSmoothedLowerBuffer, - atrSmoothingMethod // - ); - } - else - { - // - atrSmoothedUpperBuffer[bar_index] = iAtrUpper; - atrSmoothedLowerBuffer[bar_index] = iAtrLower; - } - - // - // RSI Change Calculations ... - - // - double iRsi = rsiBuffer[bar_index]; - double iRsiP = rsiBuffer[bar_index + 1]; - double iRsiPrice = GetAppliedPrice( - rsiPriceType, - open, - high, - low, - close, - bar_index // - ); - - // - double iRsiChanged = iRsi - iRsiP; - double iRsiPointsChanged = iRsiChanged / points; - - // - double iRChange = iRsiPrice + (iRsiChanged * points); - rsiChangeBuffer[bar_index] = iRChange; - - // - bool canSmoothRsi = rsiSmoothingMethod != X_MA_MODE_NONE; - if (canSmoothRsi) - { - // - // Upper ... - iMAOnBuffer( - ratesTotal, - prevCalculated, - bar_index, - atrLength, - rsiChangeBuffer, - rsiChangeSmoothedBuffer, - rsiSmoothingMethod // - ); - } - else - { - rsiChangeSmoothedBuffer[bar_index] = iRChange; - } - - // - // PRICE Change Calculation ... - - // - double iPChangePrice = GetAppliedPrice( - priceChangeType, - open, - high, - low, - close, - bar_index // - ); - double iPPChangePrice = GetAppliedPrice( - priceChangeType, - open, - high, - low, - close, - bar_index + 1 // - ); - - // - double iPriceChange = iPChangePrice - iPPChangePrice; - double iPricePointsChanged = iPriceChange / points; - double iVolatilityChange = iPriceChange / iAtr; - - // - double iPChange = iPChangePrice + (iPricePointsChanged * points); - priceChangeBuffer[bar_index] = iPChange; - - // - bool canSmoothPriceChange = priceChangeSmoothingMethod != X_MA_MODE_NONE; - if (canSmoothPriceChange) - { - // - // Upper ... - iMAOnBuffer( - ratesTotal, - prevCalculated, - bar_index, - atrLength, - priceChangeBuffer, - priceChangeSmoothedBuffer, - priceChangeSmoothingMethod // - ); - } - else - { - priceChangeSmoothedBuffer[bar_index] = iPChange; - } -} - -// \ No newline at end of file diff --git a/Indicators/x-saherelm.x121.xca.mq5 b/Indicators/x-saherelm.x121.xca.mq5 deleted file mode 100644 index 7e1ec609..00000000 --- a/Indicators/x-saherelm.x121.xca.mq5 +++ /dev/null @@ -1,2601 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Indicator -// ------------------------------------------------- -// Name: X121 XCA -// Description: XCA ... -// -// -// 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 XCA Indicator" -#property strict - -// -// Definitions ... - -// -#define ShortName "X121 XCA" - -// -// Includes Common Library ... -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// Inputs ... - -// -input group "Market"; - -// -input group "Short"; -input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period -input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period - -// -input group "Medium"; -input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period -input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period - -// -input group "Long"; -input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period -input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period - -// -input group "Hind"; -input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period -input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period - -// -input group "Boundary Detection"; -input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method -input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method - -// -input group "Fibo Levels"; -input ENUM_X_FIBO_LEVELS fiboLevel1 = X_FIBO_LEVEL_236; // Fibo Level 1 -input ENUM_X_FIBO_LEVELS fiboLevel2 = X_FIBO_LEVEL_382; // Fibo Level 2 -input ENUM_X_FIBO_LEVELS fiboLevel3 = X_FIBO_LEVEL_500; // Fibo Level 3 -input ENUM_X_FIBO_LEVELS fiboLevel4 = X_FIBO_LEVEL_618; // Fibo Level 4 -input ENUM_X_FIBO_LEVELS fiboLevel5 = X_FIBO_LEVEL_764; // Fibo Level 5 - -// -input group "Sar Detection"; -input double sarStep = 0.02; // Step -input double sarMax = 0.2; // Maximum - -// -// KI ... -input group "KI"; -input int kiLength = 26; // KI Length - -// -// VIDYA ... -// Variable Index Dynamic Average ... -input group "VIDYA"; -input int vidyaCMOLength = 20; // CMO (Candle Momentum) Length -input int vidyaEMALength = 14; // EMA Length -input ENUM_APPLIED_PRICE vidyaAppliedTo = PRICE_CLOSE; // Applied To - -// -// Manalyser ... -input group "Manalyser"; -input int manalyserLength = 14; // Length -input ENUM_MA_METHOD manalyserMethod = MODE_SMA; // Method - -// -input group "Swing Detection"; -input int swingLength = 5; // Length - -// -input group "Support and Resistance"; -input int supResSmoothingLength = 7; // Smoothing Length -input ENUM_X_MA_METHOD supResSmoothingMode = X_MA_MODE_NONE; // Smoothing Method - -// -// Presentation ... -input group "Presentation"; - -// -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 showMAH = true; // Show MAH -input bool showMAL = true; // Show MAL -input bool showMAC = true; // Show MAC -input bool showVidya = true; // Show Vidya -input bool showTrend = true; // Show Trend -input bool showSwings = true; // Show Swings -input bool showFiboLevel1 = true; // Show Fibo Level 1 -input bool showFiboLevel2 = true; // Show Fibo Level 2 -input bool showFiboLevel3 = true; // Show Fibo Level 3 -input bool showFiboLevel4 = true; // Show Fibo Level 4 -input bool showFiboLevel5 = true; // Show Fibo Level 5 -input bool showPeaksAndVales = true; // Show Peaks And Vales -input bool showPeakAndValeGolden = true; // Show Peak and Vale Golden -input bool showSupportAndResistance = true; // Show Support and Resistance - -// -bool showShortCycle = false; // Show Short Cycle -bool showMediumCycle = false; // Show Medium Cycle -bool showLongCycle = false; // Show Long Cycle -bool showHindCycle = false; // Show Hind Cycle - -// -int sarArrowCode = 159; // Parabolic Sar Arrow Code -int peakArrowCode = 159; // Peaks Arrow Code -int valeArrowCode = 159; // Vales Arrow Code -int swingLowArrowCode = 225; // Swing Low Arrow Code -int swingHighArrowCode = 226; // Swing High Arrow Code - -// -// 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 39 -#property indicator_plots 29 - -// -// Plot Buffers ... - -// -// SHORT ... - -// -#define sHHBufferIndex 0 -double sHHBuffer[]; - -// -#property indicator_label1 "SH" -#property indicator_type1 DRAW_LINE -#property indicator_color1 clrGray -#property indicator_style1 STYLE_DOT -#property indicator_width1 1 - -// -#define sLLBufferIndex 1 -double sLLBuffer[]; - -// -#property indicator_label2 "SL" -#property indicator_type2 DRAW_LINE -#property indicator_color2 clrGray -#property indicator_style2 STYLE_DOT -#property indicator_width2 1 - -// -// MEDIUM ... - -// -#define mHHBufferIndex 2 -double mHHBuffer[]; - -// -#property indicator_label3 "MH" -#property indicator_type3 DRAW_LINE -#property indicator_color3 clrIndigo -#property indicator_style3 STYLE_DOT -#property indicator_width3 1 - -// -#define mLLBufferIndex 3 -double mLLBuffer[]; - -// -#property indicator_label4 "ML" -#property indicator_type4 DRAW_LINE -#property indicator_color4 clrIndigo -#property indicator_style4 STYLE_DOT -#property indicator_width4 1 - -// -// LONG ... - -// -#define lHHBufferIndex 4 -double lHHBuffer[]; - -// -#property indicator_label5 "LH" -#property indicator_type5 DRAW_LINE -#property indicator_color5 clrGoldenrod -#property indicator_style5 STYLE_DOT -#property indicator_width5 1 - -// -#define lLLBufferIndex 5 -double lLLBuffer[]; - -// -#property indicator_label6 "LL" -#property indicator_type6 DRAW_LINE -#property indicator_color6 clrGoldenrod -#property indicator_style6 STYLE_DOT -#property indicator_width6 1 - -// -// HIND ... - -// -#define hHHBufferIndex 6 -double hHHBuffer[]; - -// -#property indicator_label7 "HH" -#property indicator_type7 DRAW_LINE -#property indicator_color7 clrBrown -#property indicator_style7 STYLE_DOT -#property indicator_width7 1 - -// -#define hLLBufferIndex 7 -double hLLBuffer[]; - -// -#property indicator_label8 "HL" -#property indicator_type8 DRAW_LINE -#property indicator_color8 clrBrown -#property indicator_style8 STYLE_DOT -#property indicator_width8 1 - -// -// SUPPORT ... - -// -#define supportBufferIndex 8 -double supportBuffer[]; - -// -#property indicator_label9 "SUPPORT" -#property indicator_type9 DRAW_LINE -#property indicator_color9 clrLime -#property indicator_style9 STYLE_SOLID -#property indicator_width9 1 - -// -// RESISTANCE ... - -// -#define resistanceBufferIndex 9 -double resistanceBuffer[]; - -// -#property indicator_label10 "RESISTANCE" -#property indicator_type10 DRAW_LINE -#property indicator_color10 clrRed -#property indicator_style10 STYLE_SOLID -#property indicator_width10 1 - -// -// PEAKS ... - -// -#define peakBufferIndex 10 -double peakBuffer[]; - -// -#property indicator_label11 "PEAK" -#property indicator_type11 DRAW_ARROW -#property indicator_color11 clrMagenta -#property indicator_width11 1 - -// -// PEAKS Golden ... - -// -#define peakGoldenBufferIndex 11 -double peakGoldenBuffer[]; - -// -#property indicator_label12 "PEAK Golden" -#property indicator_type12 DRAW_LINE -#property indicator_color12 clrMagenta -#property indicator_style2 STYLE_DOT -#property indicator_width12 1 - -// -// VALES ... - -// -#define valeBufferIndex 12 -double valeBuffer[]; - -// -#property indicator_label13 "VALE" -#property indicator_type13 DRAW_ARROW -#property indicator_color13 clrAqua -#property indicator_width13 1 - -// -// VALE Golden ... - -// -#define valeGoldenBufferIndex 13 -double valeGoldenBuffer[]; - -// -#property indicator_label14 "VALES Golden" -#property indicator_type14 DRAW_LINE -#property indicator_color14 clrAqua -#property indicator_style4 STYLE_DOT -#property indicator_width14 1 - -// -// FIBO Level 1 - -// -#define fiboLevel1BufferIndex 14 -double fiboLevel1Buffer[]; - -// -#property indicator_label15 "Fibo L1" -#property indicator_type15 DRAW_LINE -#property indicator_color15 clrGold -#property indicator_style15 STYLE_DOT -#property indicator_width15 1 - -// -// FIBO Level 2 - -// -#define fiboLevel2BufferIndex 15 -double fiboLevel2Buffer[]; - -// -#property indicator_label16 "Fibo L2" -#property indicator_type16 DRAW_LINE -#property indicator_color16 clrGold -#property indicator_style16 STYLE_DOT -#property indicator_width16 1 - -// -// FIBO Level 3 - -// -#define fiboLevel3BufferIndex 16 -double fiboLevel3Buffer[]; - -// -#property indicator_label17 "Fibo L3" -#property indicator_type17 DRAW_LINE -#property indicator_color17 clrYellow -#property indicator_style17 STYLE_DASH -#property indicator_width17 1 - -// -// FIBO Level 4 - -// -#define fiboLevel4BufferIndex 17 -double fiboLevel4Buffer[]; - -// -#property indicator_label18 "Fibo L4" -#property indicator_type18 DRAW_LINE -#property indicator_color18 clrGold -#property indicator_style18 STYLE_DOT -#property indicator_width18 1 - -// -// FIBO Level 5 - -// -#define fiboLevel5BufferIndex 18 -double fiboLevel5Buffer[]; - -// -#property indicator_label19 "Fibo L5" -#property indicator_type19 DRAW_LINE -#property indicator_color19 clrGold -#property indicator_style19 STYLE_DOT -#property indicator_width19 1 - -// -// SAR ... - -// -#define sarBufferIndex 19 -double sarBuffer[]; - -// -#property indicator_label20 "SAR" -#property indicator_type20 DRAW_ARROW -#property indicator_color20 clrYellow -#property indicator_width20 1 - -// -// TREND ... - -// -#define trendBufferIndex 20 -#define trendBufferPlotIndex 20 -double trendBuffer[]; - -// -#define trendColorBufferIndex 21 -double trendColorBuffer[]; - -// -#property indicator_label21 "TRND" -#property indicator_type21 DRAW_COLOR_LINE -#property indicator_color21 CLR_NONE, clrAqua, clrMagenta, clrGray -#property indicator_style21 STYLE_DASH -#property indicator_width21 2 - -// -// KI ... - -// -#define kiBufferIndex 22 -#define kiBufferPlotIndex 21 -double kiBuffer[]; - -// -#define kiColorBufferIndex 23 -double kiColorBuffer[]; - -// -#property indicator_label22 "KI" -#property indicator_type22 DRAW_COLOR_LINE -#property indicator_color22 CLR_NONE, clrGreen, clrRed, clrGray -#property indicator_style22 STYLE_DASHDOTDOT -#property indicator_width22 2 - -// -// SWING Low ... - -// -#define swingLowBufferIndex 24 -#define swingLowBufferPlotIndex 22 -double swingLowBuffer[]; - -// -#property indicator_label23 "SWL" -#property indicator_type23 DRAW_ARROW -#property indicator_color23 clrGreen -#property indicator_width23 1 - -// -// SWING High ... - -// -#define swingHighBufferIndex 25 -#define swingHighBufferPlotIndex 23 -double swingHighBuffer[]; - -// -#property indicator_label24 "SWH" -#property indicator_type24 DRAW_ARROW -#property indicator_color24 clrRed -#property indicator_width24 1 - -// -// TKI ... - -// -#define tkiBufferIndex 26 -#define tkiBufferPlotIndex 24 -double tkiBuffer[]; - -// -#define tkiColorBufferIndex 27 -double tkiColorBuffer[]; - -// -#property indicator_label25 "TKI" -#property indicator_type25 DRAW_COLOR_LINE -#property indicator_color25 CLR_NONE, clrGreen, clrRed, clrGray -#property indicator_style25 STYLE_DASHDOTDOT -#property indicator_width25 2 - -// -// VIDYA ... - -// -#define vidyaBufferIndex 28 -#define vidyaBufferPlotIndex 25 -double vidyaBuffer[]; - -// -#define vidyaColorBufferIndex 29 -double vidyaColorBuffer[]; - -// -#property indicator_label26 "VIDYA" -#property indicator_type26 DRAW_COLOR_LINE -#property indicator_color26 CLR_NONE, clrAqua, clrMagenta, clrGray -#property indicator_style26 STYLE_SOLID -#property indicator_width26 1 - -// -// MAH ... - -// -#define mahBufferIndex 30 -#define mahBufferPlotIndex 26 -double mahBuffer[]; - -// -#property indicator_label27 "MAH" -#property indicator_type27 DRAW_LINE -#property indicator_color27 clrMagenta -#property indicator_style27 STYLE_SOLID -#property indicator_width27 1 - -// -// MAL ... - -// -#define malBufferIndex 31 -#define malBufferPlotIndex 27 -double malBuffer[]; - -// -#property indicator_label28 "MAL" -#property indicator_type28 DRAW_LINE -#property indicator_color28 clrAqua -#property indicator_style28 STYLE_SOLID -#property indicator_width28 1 - -// -// MAC ... - -// -#define macBufferIndex 32 -#define macBufferPlotIndex 28 -double macBuffer[]; - -// -#property indicator_label29 "MAC" -#property indicator_type29 DRAW_LINE -#property indicator_color29 clrYellow -#property indicator_style29 STYLE_SOLID -#property indicator_width29 1 - -// -// Data Buffers ... - -#define mLastBufferIndex 32 - -// -#define trendStateBufferIndex mLastBufferIndex + 1 -double trendStateBuffer[]; - -// -#define kiStateBufferIndex mLastBufferIndex + 2 -double kiStateBuffer[]; - -// -#define tkiStateBufferIndex mLastBufferIndex + 3 -double tkiStateBuffer[]; - -// -#define vidyaStateBufferIndex mLastBufferIndex + 4 -double vidyaStateBuffer[]; - -// -#define supBufferIndex mLastBufferIndex + 5 -double supBuffer[]; - -// -#define resBufferIndex mLastBufferIndex + 6 -double resBuffer[]; - -// -// Variables, Properties and etc ... - -// -// this counts Available Bars ... -int limit; - -// -int firstBarIndex; - -// -int maxLength; - -// -// SAR Handler ... -int sarHandler = INVALID_HANDLE; - -// -// TREND Handler ... -int tkiHandler = INVALID_HANDLE; -int vidyaHandler = INVALID_HANDLE; -int trendHandler = INVALID_HANDLE; - -// -// Manalyser Handlers ... -int mahHandler = INVALID_HANDLE; -int malHandler = INVALID_HANDLE; -int macHandler = INVALID_HANDLE; - -// -// XMarketCycle sc; -int mSCLength = 0; -ENUM_TIMEFRAMES mSCPeriod = NULL; - -// -// XMarketCycle mc; -int mMCLength = 0; -ENUM_TIMEFRAMES mMCPeriod = NULL; - -// -// XMarketCycle lc; -int mLCLength = 0; -ENUM_TIMEFRAMES mLCPeriod = NULL; - -// -// XMarketCycle hc; -int mHCLength = 0; -ENUM_TIMEFRAMES mHCPeriod = NULL; - -// -// Event Handlers ... - -/** - * Initialize Indicator ... - * - * @return ( int ) - */ -int OnInit() -{ - // - // Validate Inputs ... - if (!ValidateInputs()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - if (!InitMarketCycles()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - // Initialize Indicator Handlers ... - - // - // SAR ... - sarHandler = iSAR( - _Symbol, - _Period, - sarStep, - sarMax // - ); - bool isInited = sarHandler != INVALID_HANDLE; - if (!isInited) - { - return INIT_FAILED; - } - - // - // TKI ... - tkiHandler = iMA( - _Symbol, - _Period, - kiLength, - 0, - MODE_SMA, - PRICE_MEDIAN // - ); - isInited = tkiHandler != INVALID_HANDLE; - if (!isInited) - { - return INIT_FAILED; - } - - // - // VIDYA ... - vidyaHandler = iVIDyA( - _Symbol, - _Period, - vidyaCMOLength, - vidyaEMALength, - 0, - vidyaAppliedTo // - ); - isInited = vidyaHandler != INVALID_HANDLE; - if (!isInited) - { - return INIT_FAILED; - } - - // - // TREND ... - trendHandler = iMA( - _Symbol, - _Period, - mHCLength, - 0, - MODE_SMA, - PRICE_CLOSE // - ); - isInited = trendHandler != INVALID_HANDLE; - if (!isInited) - { - return INIT_FAILED; - } - - // - // MANALYSE ... - - // - // MAH ... - mahHandler = iMA( - _Symbol, - _Period, - manalyserLength, - 0, - manalyserMethod, - PRICE_HIGH // - ); - isInited = mahHandler != INVALID_HANDLE; - if (!isInited) - { - return INIT_FAILED; - } - - // - // MAL ... - malHandler = iMA( - _Symbol, - _Period, - manalyserLength, - 0, - manalyserMethod, - PRICE_LOW // - ); - isInited = malHandler != INVALID_HANDLE; - if (!isInited) - { - return INIT_FAILED; - } - - // - // MAC ... - macHandler = iMA( - _Symbol, - _Period, - manalyserLength, - 0, - manalyserMethod, - PRICE_CLOSE // - ); - isInited = macHandler != 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(sarHandler); - IndicatorRelease(tkiHandler); - IndicatorRelease(vidyaHandler); - IndicatorRelease(trendHandler); -} - -/** - * 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 ... - - // - // SAR ... - int sarCalculatedBars = BarsCalculated(sarHandler); - - // - // TKI ... - int tkiCalculatedBars = BarsCalculated(tkiHandler); - - // - // VIDYA ... - int vidyaCalculatedBars = BarsCalculated(vidyaHandler); - - // - // TREND ... - int trendCalculatedBars = BarsCalculated(trendHandler); - - // - // MANALYSER ... - - // - // MAH ... - int mahCalculatedBars = BarsCalculated(mahHandler); - - // - // MAL ... - int malCalculatedBars = BarsCalculated(malHandler); - - // - // MAC ... - int macCalculatedBars = BarsCalculated(macHandler); - - // - bool isPassedRequiredCalculatedBars = - // - // SAR ... - sarCalculatedBars >= maxLength && - // - // TKI ... - tkiCalculatedBars >= maxLength && - // - // VIDYA ... - vidyaCalculatedBars >= maxLength && - // - // TREND ... - trendCalculatedBars >= maxLength && - // - // MANALYSER ... - // MAH ... - mahCalculatedBars >= maxLength && - // MAL ... - malCalculatedBars >= maxLength && - // MAC ... - macCalculatedBars >= maxLength - // - ; - if (!isPassedRequiredCalculatedBars) - { - return prev_calculated; - } - - // - limit = (prev_calculated > rates_total || prev_calculated <= 0) - ? rates_total - : (rates_total - prev_calculated) + 1; - - // - // Buffers Copy ... - - // - // SAR ... - int copiedSars = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer); - - // - // TKI ... - int copiedTKIs = CopyBuffer(tkiHandler, 0, 0, limit, tkiBuffer); - - // - // TKI ... - int copiedVidyas = CopyBuffer(vidyaHandler, 0, 0, limit, vidyaBuffer); - - // - // TREND ... - int copiedTrends = CopyBuffer(trendHandler, MAIN_LINE, 0, limit + 1, trendBuffer); - - // - // MANALYSER ... - - // - // MAH ... - int copiedMahs = CopyBuffer(mahHandler, 0, 0, limit, mahBuffer); - - // - // MAL ... - int copiedMals = CopyBuffer(malHandler, 0, 0, limit, malBuffer); - - // - // MAC ... - int copiedMacs = CopyBuffer(macHandler, 0, 0, limit, macBuffer); - - // - // Validate Copied Items ... - bool isPassedRequiredCopiedItems = - // - // SAR ... - copiedSars >= limit && - // - // TKI ... - copiedTKIs >= limit && - // - // VIDYA ... - copiedVidyas >= limit && - // - // TREND ... - copiedTrends >= limit && - // - // MANALYSER ... - // MAH ... - copiedMahs >= limit && - // MAL ... - copiedMals >= limit && - // MAC ... - copiedMacs >= 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 = - // - // SAR ... - sarMax > 0 && - sarStep > 0 && - kiLength > 0 && - swingLength > 0 && - sarMax > sarStep && - vidyaEMALength > 0 && - vidyaCMOLength > 0 && - manalyserLength > 0 && - // - // XCA ... - (IsValid(scMethod, scPeriod) && - IsValid(mcMethod, mcPeriod) && - IsValid(lcMethod, lcPeriod) && - IsValid(hcMethod, hcPeriod)) - // - ; - - // - return result; -} - -/** - * Extract Max Length of Inputs ... - * - * @return ( int ) - */ -int ExtractMaxLengthOfInputs() -{ - // - int result = 0; - - // - result = MathMax(kiLength, swingLength); - result = MathMax(result, vidyaCMOLength); - result = MathMax(result, vidyaEMALength); - result = MathMax(result, manalyserLength); - - // - return result; -} - -/** - * Define Required Buffers ... - */ -void DefineBuffers() -{ - // - // Plot Buffers ... - - // - // SHORT ... - - // - ENUM_DRAW_TYPE sDrawType = showShortCycle ? DRAW_LINE : DRAW_NONE; - - // - // HH ... - - // - ArraySetAsSeries(sHHBuffer, true); - SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(sHHBufferIndex, PLOT_SHOW_DATA, showShortCycle); - PlotIndexSetInteger(sHHBufferIndex, PLOT_DRAW_TYPE, sDrawType); - - // - PlotIndexSetDouble(sHHBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // LL ... - - // - ArraySetAsSeries(sLLBuffer, true); - SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(sLLBufferIndex, PLOT_SHOW_DATA, showShortCycle); - PlotIndexSetInteger(sLLBufferIndex, PLOT_DRAW_TYPE, sDrawType); - - // - PlotIndexSetDouble(sLLBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // MEDIUM ... - - // - ENUM_DRAW_TYPE mDrawType = showMediumCycle ? DRAW_LINE : DRAW_NONE; - - // - // HH ... - - // - ArraySetAsSeries(mHHBuffer, true); - SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(mHHBufferIndex, PLOT_SHOW_DATA, showMediumCycle); - PlotIndexSetInteger(mHHBufferIndex, PLOT_DRAW_TYPE, mDrawType); - - // - PlotIndexSetDouble(mHHBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // LL ... - - // - ArraySetAsSeries(mLLBuffer, true); - SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(mLLBufferIndex, PLOT_SHOW_DATA, showMediumCycle); - PlotIndexSetInteger(mLLBufferIndex, PLOT_DRAW_TYPE, mDrawType); - - // - PlotIndexSetDouble(mLLBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // LONG ... - - // - ENUM_DRAW_TYPE lDrawType = showLongCycle ? DRAW_LINE : DRAW_NONE; - - // - // HH ... - - // - ArraySetAsSeries(lHHBuffer, true); - SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(lHHBufferIndex, PLOT_SHOW_DATA, showLongCycle); - PlotIndexSetInteger(lHHBufferIndex, PLOT_DRAW_TYPE, lDrawType); - - // - PlotIndexSetDouble(lHHBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // LL ... - - // - ArraySetAsSeries(lLLBuffer, true); - SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(lLLBufferIndex, PLOT_SHOW_DATA, showLongCycle); - PlotIndexSetInteger(lLLBufferIndex, PLOT_DRAW_TYPE, lDrawType); - - // - PlotIndexSetDouble(lLLBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // HIND ... - - // - ENUM_DRAW_TYPE hDrawType = showHindCycle ? DRAW_LINE : DRAW_NONE; - - // - // HH ... - - // - ArraySetAsSeries(hHHBuffer, true); - SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(hHHBufferIndex, PLOT_SHOW_DATA, showHindCycle); - PlotIndexSetInteger(hHHBufferIndex, PLOT_DRAW_TYPE, hDrawType); - - // - PlotIndexSetDouble(hHHBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // LL ... - - // - ArraySetAsSeries(hLLBuffer, true); - SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(hLLBufferIndex, PLOT_SHOW_DATA, showHindCycle); - PlotIndexSetInteger(hLLBufferIndex, PLOT_DRAW_TYPE, hDrawType); - - // - PlotIndexSetDouble(hLLBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // SUPPORT / RESISTANCE ... - - // - ENUM_DRAW_TYPE supResDrawType = showSupportAndResistance ? DRAW_LINE : DRAW_NONE; - - // - // SUPPORT ... - - // - ArraySetAsSeries(supportBuffer, true); - SetIndexBuffer(supportBufferIndex, supportBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(supportBufferIndex, PLOT_SHOW_DATA, showSupportAndResistance); - PlotIndexSetInteger(supportBufferIndex, PLOT_DRAW_TYPE, supResDrawType); - - // - PlotIndexSetDouble(supportBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // RESISTANCE ... - - // - ArraySetAsSeries(resistanceBuffer, true); - SetIndexBuffer(resistanceBufferIndex, resistanceBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(resistanceBufferIndex, PLOT_SHOW_DATA, showSupportAndResistance); - PlotIndexSetInteger(resistanceBufferIndex, PLOT_DRAW_TYPE, supResDrawType); - - // - PlotIndexSetDouble(resistanceBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // PEAK / VALE ... - - // - ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; - - // - // PEAK ... - - // - ArraySetAsSeries(peakBuffer, true); - SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(peakBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); - PlotIndexSetInteger(peakBufferIndex, PLOT_DRAW_TYPE, pvDrawType); - - // - PlotIndexSetDouble(peakBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - PlotIndexSetInteger(peakBufferIndex, PLOT_ARROW, peakArrowCode); - - // - // VALE ... - - // - ArraySetAsSeries(valeBuffer, true); - SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(valeBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); - PlotIndexSetInteger(valeBufferIndex, PLOT_DRAW_TYPE, pvDrawType); - - // - PlotIndexSetDouble(valeBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - PlotIndexSetInteger(valeBufferIndex, PLOT_ARROW, valeArrowCode); - - // - // PV GOLDEN ... - - // - ENUM_DRAW_TYPE pvGoldenDrawType = showPeakAndValeGolden ? DRAW_LINE : DRAW_NONE; - - // - // PEAK Golden ... - - // - ArraySetAsSeries(peakGoldenBuffer, true); - SetIndexBuffer(peakGoldenBufferIndex, peakGoldenBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(peakGoldenBufferIndex, PLOT_SHOW_DATA, showPeakAndValeGolden); - PlotIndexSetInteger(peakGoldenBufferIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); - - // - PlotIndexSetDouble(peakGoldenBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // VALE Golden ... - - // - ArraySetAsSeries(valeGoldenBuffer, true); - SetIndexBuffer(valeGoldenBufferIndex, valeGoldenBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(valeGoldenBufferIndex, PLOT_SHOW_DATA, showPeakAndValeGolden); - PlotIndexSetInteger(valeGoldenBufferIndex, PLOT_DRAW_TYPE, pvGoldenDrawType); - - // - PlotIndexSetDouble(valeGoldenBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // FIBO L1 ... - - // - ENUM_DRAW_TYPE fiboL1DrawType = showFiboLevel1 ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(fiboLevel1Buffer, true); - SetIndexBuffer(fiboLevel1BufferIndex, fiboLevel1Buffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(fiboLevel1BufferIndex, PLOT_SHOW_DATA, showFiboLevel1); - PlotIndexSetInteger(fiboLevel1BufferIndex, PLOT_DRAW_TYPE, fiboL1DrawType); - - // - PlotIndexSetDouble(fiboLevel1BufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // FIBO L2 ... - - // - ENUM_DRAW_TYPE fiboL2DrawType = showFiboLevel2 ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(fiboLevel2Buffer, true); - SetIndexBuffer(fiboLevel2BufferIndex, fiboLevel2Buffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(fiboLevel2BufferIndex, PLOT_SHOW_DATA, showFiboLevel2); - PlotIndexSetInteger(fiboLevel2BufferIndex, PLOT_DRAW_TYPE, fiboL2DrawType); - - // - PlotIndexSetDouble(fiboLevel2BufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // FIBO L3 ... - - // - ENUM_DRAW_TYPE fiboL3DrawType = showFiboLevel3 ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(fiboLevel3Buffer, true); - SetIndexBuffer(fiboLevel3BufferIndex, fiboLevel3Buffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(fiboLevel3BufferIndex, PLOT_SHOW_DATA, showFiboLevel3); - PlotIndexSetInteger(fiboLevel3BufferIndex, PLOT_DRAW_TYPE, fiboL3DrawType); - - // - PlotIndexSetDouble(fiboLevel3BufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // FIBO L4 ... - - // - ENUM_DRAW_TYPE fiboL4DrawType = showFiboLevel4 ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(fiboLevel4Buffer, true); - SetIndexBuffer(fiboLevel4BufferIndex, fiboLevel4Buffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(fiboLevel4BufferIndex, PLOT_SHOW_DATA, showFiboLevel4); - PlotIndexSetInteger(fiboLevel4BufferIndex, PLOT_DRAW_TYPE, fiboL4DrawType); - - // - PlotIndexSetDouble(fiboLevel4BufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // FIBO L5 ... - - // - ENUM_DRAW_TYPE fiboL5DrawType = showFiboLevel5 ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(fiboLevel5Buffer, true); - SetIndexBuffer(fiboLevel5BufferIndex, fiboLevel5Buffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(fiboLevel5BufferIndex, PLOT_SHOW_DATA, showFiboLevel5); - PlotIndexSetInteger(fiboLevel5BufferIndex, PLOT_DRAW_TYPE, fiboL5DrawType); - - // - PlotIndexSetDouble(fiboLevel5BufferIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // SAR ... - - // - ENUM_DRAW_TYPE sarDrawType = showSar ? DRAW_ARROW : DRAW_NONE; - - // - ArraySetAsSeries(sarBuffer, true); - SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(sarBufferIndex, PLOT_SHOW_DATA, showSar); - PlotIndexSetInteger(sarBufferIndex, PLOT_DRAW_TYPE, sarDrawType); - - // - PlotIndexSetDouble(sarBufferIndex, PLOT_EMPTY_VALUE, emptyValue); - PlotIndexSetInteger(sarBufferIndex, PLOT_ARROW, sarArrowCode); - - // - // TREND ... - - // - ENUM_DRAW_TYPE trendDrawType = showTrend ? DRAW_COLOR_LINE : DRAW_NONE; - - // - ArraySetAsSeries(trendBuffer, true); - SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(trendBufferPlotIndex, PLOT_SHOW_DATA, showTrend); - // PlotIndexSetInteger(trendBufferPlotIndex, PLOT_DRAW_TYPE, trendDrawType); - - // - PlotIndexSetDouble(trendBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - ArraySetAsSeries(trendColorBuffer, true); - SetIndexBuffer(trendColorBufferIndex, trendColorBuffer, INDICATOR_COLOR_INDEX); - - // - // KI ... - - // - ENUM_DRAW_TYPE kiDrawType = showKI ? DRAW_COLOR_LINE : DRAW_NONE; - - // - ArraySetAsSeries(kiBuffer, true); - SetIndexBuffer(kiBufferIndex, kiBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(kiBufferPlotIndex, PLOT_SHOW_DATA, showKI); - // PlotIndexSetInteger(kiBufferPlotIndex, PLOT_DRAW_TYPE, kiDrawType); - - // - PlotIndexSetDouble(kiBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - 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); - - // - // VIDYA ... - - // - ENUM_DRAW_TYPE vidyaDrawType = showVidya ? DRAW_COLOR_LINE : DRAW_NONE; - - // - ArraySetAsSeries(vidyaBuffer, true); - SetIndexBuffer(vidyaBufferIndex, vidyaBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(vidyaBufferPlotIndex, PLOT_SHOW_DATA, showKI); - // PlotIndexSetInteger(vidyaBufferPlotIndex, PLOT_DRAW_TYPE, vidyaDrawType); - - // - PlotIndexSetDouble(vidyaBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - ArraySetAsSeries(vidyaColorBuffer, true); - SetIndexBuffer(vidyaColorBufferIndex, vidyaColorBuffer, INDICATOR_COLOR_INDEX); - - // - // SWINGS ... - - // - ENUM_DRAW_TYPE swingDrawType = showSwings ? DRAW_ARROW : DRAW_NONE; - - // - // SWING Low ... - - // - ArraySetAsSeries(swingLowBuffer, true); - SetIndexBuffer(swingLowBufferIndex, swingLowBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(swingLowBufferPlotIndex, PLOT_SHOW_DATA, showSwings); - PlotIndexSetInteger(swingLowBufferPlotIndex, PLOT_DRAW_TYPE, swingDrawType); - - // - PlotIndexSetDouble(swingLowBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - PlotIndexSetInteger(swingLowBufferPlotIndex, PLOT_ARROW, swingLowArrowCode); - - // - // SWING High ... - - // - ArraySetAsSeries(swingHighBuffer, true); - SetIndexBuffer(swingHighBufferIndex, swingHighBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(swingHighBufferPlotIndex, PLOT_SHOW_DATA, showSwings); - PlotIndexSetInteger(swingHighBufferPlotIndex, PLOT_DRAW_TYPE, swingDrawType); - - // - PlotIndexSetDouble(swingHighBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - PlotIndexSetInteger(swingHighBufferPlotIndex, PLOT_ARROW, swingHighArrowCode); - - // - // MANALYSER ... - - // - // MAH ... - - // - ENUM_DRAW_TYPE mahDrawType = showMAH ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(mahBuffer, true); - SetIndexBuffer(mahBufferIndex, mahBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(mahBufferPlotIndex, PLOT_SHOW_DATA, showMAH); - PlotIndexSetInteger(mahBufferPlotIndex, PLOT_DRAW_TYPE, mahDrawType); - - // - PlotIndexSetDouble(mahBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // MAL ... - - // - ENUM_DRAW_TYPE malDrawType = showMAL ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(malBuffer, true); - SetIndexBuffer(malBufferIndex, malBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(malBufferPlotIndex, PLOT_SHOW_DATA, showMAL); - PlotIndexSetInteger(malBufferPlotIndex, PLOT_DRAW_TYPE, malDrawType); - - // - PlotIndexSetDouble(malBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // MAC ... - - // - ENUM_DRAW_TYPE macDrawType = showMAC ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(macBuffer, true); - SetIndexBuffer(macBufferIndex, macBuffer, INDICATOR_DATA); - - // - PlotIndexSetInteger(macBufferPlotIndex, PLOT_SHOW_DATA, showMAC); - PlotIndexSetInteger(macBufferPlotIndex, PLOT_DRAW_TYPE, mahDrawType); - - // - PlotIndexSetDouble(macBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); - - // - // Data Buffers ... - - // - ArraySetAsSeries(trendStateBuffer, true); - SetIndexBuffer(trendStateBufferIndex, trendStateBuffer, INDICATOR_CALCULATIONS); - - // - ArraySetAsSeries(kiStateBuffer, true); - SetIndexBuffer(kiStateBufferIndex, kiStateBuffer, INDICATOR_CALCULATIONS); - - // - ArraySetAsSeries(tkiStateBuffer, true); - SetIndexBuffer(tkiStateBufferIndex, tkiStateBuffer, INDICATOR_CALCULATIONS); - - // - ArraySetAsSeries(vidyaStateBuffer, true); - SetIndexBuffer(vidyaStateBufferIndex, vidyaStateBuffer, INDICATOR_CALCULATIONS); - - // - ArraySetAsSeries(supBuffer, true); - SetIndexBuffer(supBufferIndex, supBuffer, INDICATOR_CALCULATIONS); - - // - ArraySetAsSeries(resBuffer, true); - SetIndexBuffer(resBufferIndex, resBuffer, 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; - if (barsLimit == 0) - { - // - barsLimit = ratesTotal; - firstBarIndex = barsLimit - 1; - } - else - { - // - firstBarIndex = startCalculationForLastBars; - } - - // - // bool canCalculate = true; - bool canCalculate = - bar_index <= barsLimit; - if (canCalculate) - { - // - // Calculate Cycles ... - CalculateCycles(bar_index); - - // - // Calculate Support nad Resistance ... - CalculateValues( - bar_index, - prevCalculated, - ratesTotal, - open, - high, - close, - low, - tickVolume // - ); - } - else - { - FillBuffersZero(bar_index); - } -} - -// -// Custom ... - -/** - * Initial Market Cycles ... - * - * @return ( bool ) - */ -bool InitMarketCycles() -{ - // - bool result = false; - - // - int cPeriodSeconds = PeriodSeconds(_Period); - - // - // Find Cycle Period ... - if (scMethod == X_PERIOD_AUTO) - { - // - // Select Period ... - mSCPeriod = GetCyclePeriod( - X_MARKET_CYCLE_SHORT, - _Period // - ); - } - else - { - mSCPeriod = scPeriod; - } - - // - if (IsValid(mSCPeriod)) - { - mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; - } - - // - // Find Cycle Period ... - if (mcMethod == X_PERIOD_AUTO) - { - // - // Select Period ... - mMCPeriod = GetCyclePeriod( - X_MARKET_CYCLE_MEDIUM, - _Period // - ); - } - else - { - mMCPeriod = mcPeriod; - } - - // - if (IsValid(mMCPeriod)) - { - mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; - } - - // - // Find Cycle Period ... - if (lcMethod == X_PERIOD_AUTO) - { - // - // Select Period ... - mLCPeriod = GetCyclePeriod( - X_MARKET_CYCLE_LONG, - _Period // - ); - } - else - { - mLCPeriod = lcPeriod; - } - - // - if (IsValid(mLCPeriod)) - { - mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; - } - - // - // Find Cycle Period ... - if (hcMethod == X_PERIOD_AUTO) - { - // - // Select Period ... - mHCPeriod = GetCyclePeriod( - X_MARKET_CYCLE_HIND, - _Period // - ); - } - else - { - mHCPeriod = hcPeriod; - } - - // - if (IsValid(mHCPeriod)) - { - mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; - } - - // - result = mSCLength > 0 && - mMCLength > mSCLength && - mLCLength > mMCLength && - mHCLength > mLCLength; - - // - return result; -} - -/** - * Fill All Bufers to Zero Vlue for Specified Bar Index ... - * - * @param barIndex: Integer ... - */ -void FillBuffersZero(int barIndex) -{ - // - // SHORT ... - sHHBuffer[barIndex] = emptyValue; - sLLBuffer[barIndex] = emptyValue; - - // - // MEDIUM ... - mHHBuffer[barIndex] = emptyValue; - mLLBuffer[barIndex] = emptyValue; - - // - // LONG ... - lHHBuffer[barIndex] = emptyValue; - lLLBuffer[barIndex] = emptyValue; - - // - // HIND ... - hHHBuffer[barIndex] = emptyValue; - hLLBuffer[barIndex] = emptyValue; - - // - // SUPPORT / RESISTANCE ... - supBuffer[barIndex] = emptyValue; - resBuffer[barIndex] = emptyValue; - supportBuffer[barIndex] = emptyValue; - resistanceBuffer[barIndex] = emptyValue; - - // - // PEAKS ... - peakBuffer[barIndex] = emptyValue; - peakGoldenBuffer[barIndex] = emptyValue; - - // - // VALES ... - valeBuffer[barIndex] = emptyValue; - valeGoldenBuffer[barIndex] = emptyValue; - - // - // FiBo ... - fiboLevel1Buffer[barIndex] = emptyValue; - fiboLevel2Buffer[barIndex] = emptyValue; - fiboLevel3Buffer[barIndex] = emptyValue; - fiboLevel4Buffer[barIndex] = emptyValue; - fiboLevel5Buffer[barIndex] = emptyValue; - - // - // SAR ... - sarBuffer[barIndex] = emptyValue; - - // - // TREND ... - trendBuffer[barIndex] = emptyValue; - trendColorBuffer[barIndex] = hideColorIDX; - trendStateBuffer[barIndex] = neuturalState; - - // - // KI ... - kiBuffer[barIndex] = emptyValue; - kiColorBuffer[barIndex] = hideColorIDX; - kiStateBuffer[barIndex] = neuturalState; - - // - // TKI ... - tkiBuffer[barIndex] = emptyValue; - tkiColorBuffer[barIndex] = hideColorIDX; - tkiStateBuffer[barIndex] = neuturalState; - - // - // VIDYA ... - vidyaBuffer[barIndex] = emptyValue; - vidyaColorBuffer[barIndex] = hideColorIDX; - vidyaStateBuffer[barIndex] = neuturalState; - - // - // SWINGS ... - swingLowBuffer[barIndex] = emptyValue; - swingHighBuffer[barIndex] = emptyValue; -} - -/** - * Calculate Specified Market Cycle Info ... - * - * @param barIndex: Integer, Bar Index ... - * @param cycle: ENUM_X_MARKET_CYCLES member, Specified Cycle ... - * @param hhBuffer: Highest High Buffer Reference ... - * @param llBuffer: Lowest Low Buffer Reference ... - */ -void CalculateCycle( - int barIndex, - ENUM_X_MARKET_CYCLES cycle, - double &hhBuffer[], - double &llBuffer[] // -) -{ - // - XOHCL bar; - bool isBarInited = bar.Init( - _Symbol, - _Period, - barIndex - // - ); - if (!isBarInited) - { - return; - } - - // - int mLength = 0; - switch (cycle) - { - // - case X_MARKET_CYCLE_SHORT: - mLength = mSCLength; - break; - - // - case X_MARKET_CYCLE_MEDIUM: - mLength = mMCLength; - break; - - // - case X_MARKET_CYCLE_LONG: - mLength = mLCLength; - break; - - // - case X_MARKET_CYCLE_HIND: - mLength = mHCLength; - break; - } - - // - if (mLength == 0) - { - return; - } - - // - // Find Highest High ... - double hhValue = bar.FindHighest( - mLength, - hhMode - // - ); - hhBuffer[barIndex] = hhValue; - - // - // Find Lowest Low ... - double llValue = bar.FindLowest( - mLength, - llMode - // - ); - llBuffer[barIndex] = llValue; -} - -/** - * Claculate Cycles ... - * - * @param barIndex: Integer, Bar Index ... - */ -void CalculateCycles(int barIndex) -{ - // - // SHORT ... - CalculateCycle( - barIndex, - X_MARKET_CYCLE_SHORT, - sHHBuffer, - sLLBuffer // - ); - - // - // MEDIUM ... - CalculateCycle( - barIndex, - X_MARKET_CYCLE_MEDIUM, - mHHBuffer, - mLLBuffer // - ); - - // - // LONG ... - CalculateCycle( - barIndex, - X_MARKET_CYCLE_LONG, - lHHBuffer, - lLLBuffer // - ); - - // - // HIND ... - CalculateCycle( - barIndex, - X_MARKET_CYCLE_HIND, - hHHBuffer, - hLLBuffer // - ); -} - -/** - * 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 == firstBarIndex; - - XOHCL iBar; - bool isInited = iBar.Init( - _Symbol, - _Period, - bar_index // - ); - - // - double iSHH = sHHBuffer[bar_index]; - double iSLL = sLLBuffer[bar_index]; - - // - double iMHH = mHHBuffer[bar_index]; - double iMLL = mLLBuffer[bar_index]; - - // - double iLHH = lHHBuffer[bar_index]; - double iLLL = lLLBuffer[bar_index]; - - // - double iHHH = hHHBuffer[bar_index]; - double iHLL = hLLBuffer[bar_index]; - - // - // Calculate Support ... - double lastSupport = - isFirstBar - ? emptyValue - : supBuffer[lastBarIndex]; - bool isSupport = iSLL == iMLL; - double iSupport = - isSupport - ? iSLL - : lastSupport; - supBuffer[bar_index] = iSupport; - - // - // Calculate Vale ... - double lastVale = - isFirstBar - ? emptyValue - : valeBuffer[lastBarIndex]; - bool isVale = - isSupport && - iMLL == iLLL && - iLLL == iHLL; - double iVale = - isVale - ? iMLL - : lastVale; - valeBuffer[bar_index] = iVale; - - // - // Calculate Resistance ... - double lastResistance = - isFirstBar - ? emptyValue - : resBuffer[lastBarIndex]; - bool isResistance = iSHH == iMHH; - double iResistance = - isResistance - ? iSHH - : lastResistance; - resBuffer[bar_index] = iResistance; - - // - // Calculate Peak ... - double lastPeak = - isFirstBar - ? emptyValue - : peakBuffer[lastBarIndex]; - bool isPeak = - isResistance && - iMHH == iLHH && - iLHH == iHHH; - double iPeak = - isPeak - ? iMHH - : lastPeak; - peakBuffer[bar_index] = iPeak; - - // - bool canSmooth = - supResSmoothingLength > 0 && - supResSmoothingMode != X_MA_MODE_NONE; - if (!canSmooth) - { - // - supportBuffer[bar_index] = iSupport; - resistanceBuffer[bar_index] = iResistance; - } - else - { - // - // Support ... - iMAOnBuffer( - ratesTotal, - prevCalculated, - bar_index, - supResSmoothingLength, - supBuffer, - supportBuffer, - supResSmoothingMode // - ); - - // - // Resistance ... - iMAOnBuffer( - ratesTotal, - prevCalculated, - bar_index, - supResSmoothingLength, - resBuffer, - resistanceBuffer, - supResSmoothingMode // - ); - } - - // - // Calculate Swings ... - - // - double lastSwingLow = - isFirstBar - ? emptyValue - : swingLowBuffer[lastBarIndex]; - double lastSwingHigh = - isFirstBar - ? emptyValue - : swingHighBuffer[lastBarIndex]; - - // - bool isSwingLow = IsSwingLow( - high, - low, - bar_index, - swingLength // - ); - bool isSwingHigh = IsSwingHigh( - high, - low, - bar_index, - swingLength // - ); - bool hasSwing = isSwingLow || - isSwingHigh; - double iSwingLow = emptyValue; - double iSwingHigh = emptyValue; - if (!hasSwing) - { - // - // FillBuffersZero(bar_index); - - // - iSwingLow = lastSwingLow; - iSwingHigh = lastSwingHigh; - - // - swingLowBuffer[bar_index] = lastSwingLow; - swingHighBuffer[bar_index] = lastSwingHigh; - } - else - { - // - iSwingLow = low[bar_index]; - double iSwingHigh = high[bar_index]; - - // - if (isSwingLow && !isSwingHigh) - { - iSwingHigh = lastSwingHigh; - } - else if (isSwingHigh && !isSwingLow) - { - iSwingLow = lastSwingLow; - } - - // - if (iSwingLow > lastSwingLow && - iSwingHigh == lastSwingHigh) - { - iSwingLow = lastSwingLow; - } - - // - if (iSwingHigh < lastSwingHigh && - iSwingLow == lastSwingLow) - { - iSwingHigh = lastSwingHigh; - } - - // - swingLowBuffer[bar_index] = iSwingLow; - swingHighBuffer[bar_index] = iSwingHigh; - } - - // - // Calculate Fibo Levels ... - - // - double iFiboValues[] = { - peakBuffer[bar_index], - valeBuffer[bar_index], - supBuffer[bar_index], - swingLowBuffer[bar_index], - swingHighBuffer[bar_index], - resBuffer[bar_index], // - }; - - // - double iFiboUpper = GetMax(iFiboValues); - double iFiboLower = GetMin(iFiboValues); - - // - // Fibo Level 1 ... - double iFiboLevel1 = emptyValue; - iFiboLevel1 = GetFibonacciLevel( - iFiboUpper, - iFiboLower, - fiboLevel1, - X_DIRECTION_BEARISH // - ); - fiboLevel1Buffer[bar_index] = iFiboLevel1; - - // - // Fibo Level 2 ... - double iFiboLevel2 = emptyValue; - iFiboLevel2 = GetFibonacciLevel( - iFiboUpper, - iFiboLower, - fiboLevel2, - X_DIRECTION_BEARISH // - ); - fiboLevel2Buffer[bar_index] = iFiboLevel2; - - // - // Fibo Level 3 ... - double iFiboLevel3 = emptyValue; - iFiboLevel3 = GetFibonacciLevel( - iFiboUpper, - iFiboLower, - fiboLevel3, - X_DIRECTION_BEARISH // - ); - fiboLevel3Buffer[bar_index] = iFiboLevel3; - - // - // Fibo Level 4 ... - double iFiboLevel4 = emptyValue; - iFiboLevel4 = GetFibonacciLevel( - iFiboUpper, - iFiboLower, - fiboLevel4, - X_DIRECTION_BEARISH // - ); - fiboLevel4Buffer[bar_index] = iFiboLevel4; - - // - // Fibo Level 5 ... - double iFiboLevel5 = emptyValue; - iFiboLevel5 = GetFibonacciLevel( - iFiboUpper, - iFiboLower, - fiboLevel5, - X_DIRECTION_BEARISH // - ); - fiboLevel5Buffer[bar_index] = iFiboLevel5; - - // - // Calculate Trend Color Buffer ... - double iClose = close[bar_index]; - double iTrend = trendBuffer[bar_index]; - - // - 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; - trendColorBuffer[bar_index] = iTrendColor; - - // - // Calculate KI / Color ... - double lastKI = - isFirstBar - ? emptyValue - : kiBuffer[lastBarIndex]; - double iKI = lastKI; - if (isInited) - { - // - double iLLKI = iBar.FindLowest(kiLength, MODE_LOW); - double iHHKI = iBar.FindHighest(kiLength, MODE_HIGH); - - // - iKI = (iHHKI + iLLKI) / 2; - if (iLLKI == 0 || iHHKI == 0) - { - iKI = lastKI; - } - } - else - { - iKI = lastKI; - } - kiBuffer[bar_index] = iKI; - - // - 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; - kiColorBuffer[bar_index] = iKIColor; - - // - // Calculate PV Gold ... - double lastPeakGold = - isFirstBar - ? emptyValue - : peakGoldenBuffer[lastBarIndex]; - double lastValeGold = - isFirstBar - ? emptyValue - : valeGoldenBuffer[lastBarIndex]; - double iPeakGold = lastPeakGold; - double iValeGold = lastValeGold; - if (isInited) - { - // - iPeakGold = iBar.FindHighest(mHCLength, MODE_CLOSE); - if (iPeakGold == 0) - { - iPeakGold = lastPeakGold; - } - - // - iValeGold = iBar.FindLowest(mHCLength, MODE_CLOSE); - if (iValeGold == 0) - { - iValeGold = lastValeGold; - } - } - else - { - // - iPeakGold = lastPeakGold; - iValeGold = lastValeGold; - } - peakGoldenBuffer[bar_index] = iPeakGold; - valeGoldenBuffer[bar_index] = iValeGold; - - // - // 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; - - // - // VIDYA Color ... - - // - double iVIDYA = vidyaBuffer[bar_index]; - - // - double iVIDYAState = neuturalState; - double iVIDYAColor = neuturalColorIDX; - if (iClose > iVIDYA) - { - // - iVIDYAState = bullishState; - iVIDYAColor = - !showVidya - ? hideColorIDX - : bullishColorIDX; - } - else if (iClose < iVIDYA) - { - // - iVIDYAState = bearishState; - iVIDYAColor = - !showVidya - ? hideColorIDX - : bearishColorIDX; - } - vidyaStateBuffer[bar_index] = iVIDYAState; - vidyaColorBuffer[bar_index] = iVIDYAColor; - - // - // Cleanup Resources ... - - // - iBar.Clean(); -} - -// -bool IsSwingLow( - const double &high[], - const double &low[], - int index, - int length // -) -{ - // - bool result = false; - - // - result = index + 1 + length <= firstBarIndex; - if (!result) - { - return result; - } - - // - for (int i = index + 1; i <= index + length; i++) - { - // - result = low[index] < low[i]; - if (!result) - { - break; - } - } - - // - return result; -} - -// -bool IsSwingHigh( - const double &high[], - const double &low[], - int index, - int length // -) -{ - // - bool result = false; - - // - result = index + 1 + length <= firstBarIndex; - if (!result) - { - return result; - } - - // - for (int i = index + 1; i <= index + length; i++) - { - // - result = high[index] > high[i]; - if (!result) - { - break; - } - } - - // - return result; -} - -// \ No newline at end of file diff --git a/Indicators/x-saherelm.x121.xcatb.mq5 b/Indicators/x-saherelm.x121.xcatb.mq5 index 8fb1e13d..29432e7e 100644 --- a/Indicators/x-saherelm.x121.xcatb.mq5 +++ b/Indicators/x-saherelm.x121.xcatb.mq5 @@ -47,7 +47,6 @@ #include "../Classes/x-saherelm.x-bar.analyser.class.mq5" #include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" -#include "../Libraries/x-saherelm.x121.xcatb.lib.mq5" // // Inputs ... @@ -1938,131 +1937,6 @@ void CalculateValues( low, tickVolume // ); - - // - // Try To Detect Trigger Block ... - - // - // Prevent Calculation ... - if (maxBarIndex - barIndex < maxLength) - { - return; - } - - // - XTriggerBlock tb; - bool has = DetectTriggerBlock( - // - _Symbol, - _Period, - // - tb, - // - mBarAnalyser, - // - // Required Buffers ... - atrBuffer, - rsiBuffer, - adxBuffer, - adxpBuffer, - adxnBuffer, - peakBuffer, - valeBuffer, - deltaBuffer, - sarBuffer, - sarStateBuffer, - trendBuffer, - trendStateBuffer, - atrUpperBuffer, - atrLowerBuffer, - sBarOpenBuffer, - sBarCloseBuffer, - hkSBarOpenBuffer, - hkSBarCloseBuffer, - peakGoldenBuffer, - valeGoldenBuffer, - deltaSignalBuffer, - bullishVolumeSignalBuffer, - bearishVolumeSignalBuffer, - // - barIndex, - // - // Signalling ... - signalR2R, - slAtrMultiplier, - // - // Configs ... - rsiOBLevel, - rsiOSLevel, - adxThreshold, - // - // Validators ... - forceObBarType, - forceOBFVGBarType, - forceHasSwing, - forceHasFLiquidity, - forceHasRLiquidity, - validateGapSequence, - validateBlockEdgeBreakout, - // - // Filters ... - filterBasedOnPV, - filterBasedOnSar, - filterBasedOnRSI, - filterBasedOnADX, - filterBasedOnATR, - filterBasedOnTrend, - filterBasedOnDelta, - filterBasedOnVolume, - filterBasedOnSignalBar, - filterBasedOnHKSignalBar // - ); - if (has) - { - // - // Draw ... - if (drawTriggerBlock) - { - // - has = DrawTriggerBlock( - tb, - mDrawer, - mObjects, - NULL, - drawSignals // - ); - } - - // - // Alert ... - bool canAlert = - mEnableAlerts && - prevCalculated > 0; - bool canLogOnly = - mEnableAlerts && - prevCalculated == 0; - if (has && - (canAlert || - canLogOnly)) - { - // - string message = - tb.trigger.symbol + "," + - ToString(tb.trigger.period) + "> " + - ToString(tb.trigger.dir) + - " Zone Detected at: " + ToString(tb.trigger.to); - - // - if (canLogOnly) - { - mAlert.LogAlert(message); - } - else if (canAlert) - { - mAlert.SendAlert(message); - } - } - } } // diff --git a/Indicators/x-saherelm.x121.xdelta.mq5 b/Indicators/x-saherelm.x121.xdelta.mq5 deleted file mode 100644 index 9cadee69..00000000 --- a/Indicators/x-saherelm.x121.xdelta.mq5 +++ /dev/null @@ -1,550 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Ocillator -// ------------------------------------------------- -// Name: X121 XDelta -// Description: Detect Comulative Volumes Delta ... -// -// -// 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 XDelta Ocillator" -#property strict - -// -// Definitions ... - -// -#define ShortName "X121_XDELTA" - -// -// Imports ... -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// Inputs ... - -// -// Makret ... -input group "Market"; -input int maLength = 14; // Moving Averge Length -input ENUM_X_MA_METHOD maMethod = X_MA_MODE_EMA; // Moving Averge Method - -// -// Presentation ... -input group "Presentation"; -input int startCalculationForLastBars = 1000; // Calculate Last n Bars -input bool showDeltaLine = true; // Show Delta Line -input bool showDeltaHistogram = true; // Show Delta Histogram -input bool showDeltaMa = true; // Show Delta Moving Average - -// -// Buffers Props ... - -// -#property indicator_separate_window - -// -#property indicator_buffers 6 -#property indicator_plots 3 - -// -#define hideColorIDX 0 -#define bullishColorIDX 1 -#define bearishColorIDX 2 - -// -// Buffers ... - -// -#define deltaLineBufferIndex 0 -double deltaLineBuffer[]; - -#property indicator_label1 "Delta Line" -#property indicator_type1 DRAW_LINE -#property indicator_color1 clrYellow -#property indicator_style1 STYLE_SOLID -#property indicator_width1 1 - -// -#define deltaHistogramBufferIndex 1 -double deltaHistogramBuffer[]; - -// -#define deltaHistogramColorBufferIndex 2 -double deltaHistogramColorBuffer[]; - -#property indicator_label2 "Delta Histogram" -#property indicator_type2 DRAW_COLOR_HISTOGRAM -#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed -#property indicator_style2 STYLE_DOT -#property indicator_width2 1 - -// -#define deltaMaBufferIndex 3 -double deltaMaBuffer[]; - -#property indicator_label3 "Delta MA" -#property indicator_type3 DRAW_LINE -#property indicator_color3 clrOrchid -#property indicator_style3 STYLE_SOLID -#property indicator_width3 1 - -// -// Data Buffers ... - -#define mLastBufferIndex 3 - -// -#define rawDeltaBufferIndex mLastBufferIndex + 1 -double rawDeltaBuffer[]; - -// -#define deltaStateBufferIndex mLastBufferIndex + 2 -double deltaStateBuffer[]; - -// -// Variables, Properties and etc ... - -// -// this counts Available Bars ... -int limit; - -// -int maxLength; - -// -int firstBarIndex; - -// -// Event Handlers ... - -/** - * Initialize Indicator ... - * - * @return ( int ) - */ -int OnInit() -{ - // - // Validate Inputs ... - if (!ValidateInputs()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - // Initialize Indicator Handlers ... - - // - // 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(); - IndicatorSetInteger(INDICATOR_DIGITS, 2); - - // - // 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 -} - -/** - * 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); - - // - limit = (prev_calculated > rates_total || prev_calculated <= 0) - ? rates_total - : (rates_total - prev_calculated) + 1; - - // - // 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 = maLength > 0 && - IsValid(maMethod); - - // - return result; -} - -/** - * Extract Max Length of Inputs ... - * - * @return ( int ) - */ -int ExtractMaxLengthOfInputs() -{ - // - int result = 0; - - // - result = MathMax(0, maLength); - - // - return result; -} - -/** - * Set Indicator Short Name and also we can define Buffers Labels ... - */ -void SetIndicatorName() -{ - IndicatorSetString(INDICATOR_SHORTNAME, ShortName); -} - -/** - * Define Required Buffers ... - */ -void DefineBuffers() -{ - // - // Plot Buffers ... - - // - // Delta Line ... - ENUM_DRAW_TYPE deltaLineDrawType = showDeltaLine ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(deltaLineBuffer, true); - SetIndexBuffer(deltaLineBufferIndex, deltaLineBuffer, INDICATOR_DATA); - PlotIndexSetDouble(deltaLineBufferIndex, PLOT_EMPTY_VALUE, 0.0); - PlotIndexSetInteger(deltaLineBufferIndex, PLOT_SHOW_DATA, showDeltaLine); - PlotIndexSetInteger(deltaLineBufferIndex, PLOT_DRAW_TYPE, deltaLineDrawType); - - // - // Delta Histogram ... - ENUM_DRAW_TYPE deltaHistogramDrawType = showDeltaHistogram ? DRAW_COLOR_HISTOGRAM : DRAW_NONE; - - // - ArraySetAsSeries(deltaHistogramBuffer, true); - SetIndexBuffer(deltaHistogramBufferIndex, deltaHistogramBuffer, INDICATOR_DATA); - PlotIndexSetDouble(deltaHistogramBufferIndex, PLOT_EMPTY_VALUE, 0.0); - PlotIndexSetInteger(deltaHistogramBufferIndex, PLOT_SHOW_DATA, showDeltaHistogram); - PlotIndexSetInteger(deltaHistogramBufferIndex, PLOT_DRAW_TYPE, deltaHistogramDrawType); - - // - ArraySetAsSeries(deltaHistogramColorBuffer, true); - SetIndexBuffer(deltaHistogramColorBufferIndex, deltaHistogramColorBuffer, INDICATOR_COLOR_INDEX); - - // - // Delta Ma ... - ENUM_DRAW_TYPE deltaMaDrawType = showDeltaMa ? DRAW_LINE : DRAW_NONE; - - // - ArraySetAsSeries(deltaMaBuffer, true); - SetIndexBuffer(deltaMaBufferIndex, deltaMaBuffer, INDICATOR_DATA); - PlotIndexSetDouble(deltaMaBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); - PlotIndexSetInteger(deltaMaBufferIndex, PLOT_SHOW_DATA, showDeltaMa); - PlotIndexSetInteger(deltaMaBufferIndex, PLOT_DRAW_TYPE, deltaMaDrawType); - - // - // Data Buffers ... - - // - ArraySetAsSeries(rawDeltaBuffer, true); - SetIndexBuffer(rawDeltaBufferIndex, rawDeltaBuffer, INDICATOR_CALCULATIONS); - - // - ArraySetAsSeries(deltaStateBuffer, true); - SetIndexBuffer(deltaStateBufferIndex, deltaStateBuffer, INDICATOR_CALCULATIONS); -} - -/** - * 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; - if (barsLimit == 0) - { - // - barsLimit = ratesTotal; - firstBarIndex = barsLimit - 1; - } - else - { - // - firstBarIndex = startCalculationForLastBars; - } - - // - // bool canCalculate = true; - bool canCalculate = - bar_index <= barsLimit; - if (canCalculate) - { - // - 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) -{ - // - rawDeltaBuffer[barIndex] = 0.0; - deltaLineBuffer[barIndex] = 0.0; - deltaStateBuffer[barIndex] = 0.0; - deltaHistogramBuffer[barIndex] = 0.0; - deltaMaBuffer[barIndex] = 0.0; - deltaHistogramColorBuffer[barIndex] = hideColorIDX; -} - -/** - * Calculate Vales ... - * - * @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 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 == firstBarIndex; - - // - XOHCL bar; - bool has = bar.Init( - _Symbol, - _Period, - bar_index // - ); - if (!has) - { - return; - } - - // - double iDelta = 0.0; - - // - // Detecting Delta Volume ... - if (bar.IsBullish()) - { - iDelta = (double)bar.volume; - } - else if (bar.IsBearish()) - { - iDelta = -(double)bar.volume; - } - - // - // Setting iDelta Value ... - if (isFirstBar) - { - // - rawDeltaBuffer[bar_index] = iDelta; - deltaLineBuffer[bar_index] = iDelta; - deltaHistogramBuffer[bar_index] = iDelta; - } - else - { - // - iDelta += deltaLineBuffer[bar_index + 1]; - - // - rawDeltaBuffer[bar_index] = iDelta; - deltaLineBuffer[bar_index] = iDelta; - deltaHistogramBuffer[bar_index] = iDelta; - } - - // - // Setting iDelta State ... - double iState = iDelta > 0 - ? bullishColorIDX - : iDelta < 0 - ? bearishColorIDX - : hideColorIDX; - // - // Setting iDelta Color ... - double iDeltaColor = iDelta > 0 - ? bullishColorIDX - : iDelta < 0 - ? bearishColorIDX - : hideColorIDX; - - // - deltaStateBuffer[bar_index] = iState; - deltaHistogramColorBuffer[bar_index] = iDeltaColor; - - // - // Calculate Moving Averages ... - int deltaMAsCount = iMAOnBuffer( - ratesTotal, - prevCalculated, - bar_index, - maLength, - rawDeltaBuffer, - deltaMaBuffer, - maMethod // - ); - - // - bar.Clean(); -} - -// diff --git a/Indicators/x-saherelm.x121.xoscs.mq5 b/Indicators/x-saherelm.x121.xoscs.mq5 deleted file mode 100644 index 4c32077d..00000000 --- a/Indicators/x-saherelm.x121.xoscs.mq5 +++ /dev/null @@ -1,1026 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Indicator -// ------------------------------------------------- -// Name: X121 XWZ -// Description: XWZ ... -// -// -// 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 XWZ Indicator" -#property strict - -// -// Definitions ... - -// -#define ShortName "X121_X3MA" - -// -// Imports ... -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// Inputs ... - -// -input group "Accumulation/Distribution"; -input ENUM_APPLIED_VOLUME adAppliedTo = VOLUME_TICK; // Applied To - -// -input group "ADX"; -input int adxLength = 14; // Length - -// -input group "ATR"; -input int atrLength = 14; // Length - -// -input group "CCI"; -input int cciLength = 14; // Length -input ENUM_APPLIED_PRICE cciAppliedTo = PRICE_TYPICAL; // Applied To - -// -input group "RSI"; -input int rsiLength = 14; // Length -input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // Applied To - -// -input group "MFI"; -input int mfiLength = 14; // Length -input ENUM_APPLIED_VOLUME mfiAppliedTo = VOLUME_TICK; // Applied To - -// -input group "RVI"; -input int rviLength = 14; // Length - -// -input group "MACD"; -input int macdFastLength = 12; // Fast EMA Length -input int macdSlowLength = 26; // Slow EMA Length -input int macdSignalLength = 9; // Signal Length -input ENUM_APPLIED_PRICE macdAppliedTo = PRICE_CLOSE; // Applied To - -// -input group "Momentum"; -input int momentumLength = 14; // Length -input ENUM_APPLIED_PRICE momentumAppliedTo = PRICE_CLOSE; // Applied To - -// -input group "Stochastic"; -input int stochasticKLength = 5; // K Length (Bars for Calculation) -input int stochasticDLength = 3; // D Length (first Smoothing) -input int stochasticSmoothingLength = 3; // Smoothing Length -input ENUM_MA_METHOD stochasticSmoothingMethod = MODE_SMA; // Smoothing Method -input ENUM_STO_PRICE stochasticAppliedTo = STO_LOWHIGH; // Applied To - -// -// Presentation ... -input group "Presentation"; - -// -input int startCalculationForLastBars = 1000; // Calculate Last n Bars - -// -// Buffers ... - -// -#define emptyValue 0.0 - -// -#property indicator_chart_window - -// -#property indicator_buffers 16 -#property indicator_plots 0 - -// -// Plot Buffers ... - -// -// Data Buffers ... - -// -int mLastBufferIndex = -1; - -// -// AC ... -#define acBufferIndex mLastBufferIndex + 1 -double acBuffer[]; - -// -// AD ... -#define adBufferIndex mLastBufferIndex + 2 -double adBuffer[]; - -// -// ADX ... -#define adxBufferIndex mLastBufferIndex + 3 -double adxBuffer[]; - -// -// ADX Plus ... -#define adxpBufferIndex mLastBufferIndex + 4 -double adxpBuffer[]; - -// -// ADX Negative ... -#define adxnBufferIndex mLastBufferIndex + 5 -double adxnBuffer[]; - -// -// ATR ... -#define atrBufferIndex mLastBufferIndex + 6 -double atrBuffer[]; - -// -// CCI ... -#define cciBufferIndex mLastBufferIndex + 7 -double cciBuffer[]; - -// -// RSI ... -#define rsiBufferIndex mLastBufferIndex + 8 -double rsiBuffer[]; - -// -// MFI ... -#define mfiBufferIndex mLastBufferIndex + 9 -double mfiBuffer[]; - -// -// RVI ... -#define rviBufferIndex mLastBufferIndex + 10 -double rviBuffer[]; - -// -// RVI Signal ... -#define rviSignalBufferIndex mLastBufferIndex + 11 -double rviSignalBuffer[]; - -// -// MACD ... -#define macdBufferIndex mLastBufferIndex + 12 -double macdBuffer[]; - -// -// MACD Signal ... -#define macdSignalBufferIndex mLastBufferIndex + 13 -double macdSignalBuffer[]; - -// -// Momentum ... -#define momentumBufferIndex mLastBufferIndex + 14 -double momentumBuffer[]; - -// -// Stochstic ... -#define stochasticBufferIndex mLastBufferIndex + 15 -double stochasticBuffer[]; - -// -// Stochstic Signal ... -#define stochasticSignalBufferIndex mLastBufferIndex + 16 -double stochasticSignalBuffer[]; - -// -// Variables, Properties and etc ... - -// -// this counts Available Bars ... -int limit; - -// -int maxLength; - -// -int acHandler = INVALID_HANDLE; -int adHandler = INVALID_HANDLE; -int adxHandler = INVALID_HANDLE; -int atrHandler = INVALID_HANDLE; -int cciHandler = INVALID_HANDLE; -int rsiHandler = INVALID_HANDLE; -int rviHandler = INVALID_HANDLE; -int mfiHandler = INVALID_HANDLE; -int macdHandler = INVALID_HANDLE; -int momentumHandler = INVALID_HANDLE; -int stochasticHandler = INVALID_HANDLE; - -// -// Event Handlers ... - -/** - * Initialize Indicator ... - * - * @return ( int ) - */ -int OnInit() -{ - // - // Validate Inputs ... - if (!ValidateInputs()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - // Initialize Indicator Handlers ... - if (!InitializeHandlres()) - { - 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(); - IndicatorSetInteger(INDICATOR_DIGITS, 2); - - // - // 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 - - // - DeInitializeHandlres(); -} - -/** - * 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 ... - - // - // AC ... - int acCalculatedBars = BarsCalculated(acHandler); - - // - // AD ... - int adCalculatedBars = BarsCalculated(adHandler); - - // - // ADX ... - int adxCalculatedBars = BarsCalculated(adHandler); - - // - // ATR ... - int atrCalculatedBars = BarsCalculated(atrHandler); - - // - // CCI ... - int cciCalculatedBars = BarsCalculated(cciHandler); - - // - // RSI ... - int rsiCalculatedBars = BarsCalculated(rsiHandler); - - // - // MFI ... - int mfiCalculatedBars = BarsCalculated(mfiHandler); - - // - // RVI ... - int rviCalculatedBars = BarsCalculated(rviHandler); - - // - // MACD ... - int macdCalculatedBars = BarsCalculated(macdHandler); - - // - // Momentum ... - int momentumCalculatedBars = BarsCalculated(momentumHandler); - - // - // Stochastic ... - int stochasticCalculatedBars = BarsCalculated(stochasticHandler); - - // - bool isPassedRequiredCalculatedBars = - // - // AC ... - acCalculatedBars >= maxLength && - // - // AD ... - adCalculatedBars >= maxLength && - // - // ADX ... - adxCalculatedBars >= maxLength && - // - // ATR ... - atrCalculatedBars >= maxLength && - // - // CCI ... - cciCalculatedBars >= maxLength && - // - // RSI ... - rsiCalculatedBars >= maxLength && - // - // MFI ... - mfiCalculatedBars >= maxLength && - // - // RVI ... - rviCalculatedBars >= maxLength && - // - // MACD ... - macdCalculatedBars >= maxLength && - // - // Momentum ... - momentumCalculatedBars >= maxLength && - // - // Stochastic ... - stochasticCalculatedBars >= maxLength - // - ; - if (!isPassedRequiredCalculatedBars) - { - return prev_calculated; - } - - // - limit = (prev_calculated > rates_total || prev_calculated <= 0) - ? rates_total - : (rates_total - prev_calculated) + 1; - - // - // Buffers Copy ... - - // - // AC ... - int copiedACs = CopyBuffer(acHandler, MAIN_LINE, 0, limit, acBuffer); - - // - // AD ... - int copiedADs = CopyBuffer(adHandler, MAIN_LINE, 0, limit, adBuffer); - - // - // ADX ... - int copiedADXs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer); - - // - // ADX Plus ... - int copiedADXPs = CopyBuffer(adxHandler, PLUSDI_LINE, 0, limit, adxpBuffer); - - // - // ADX Negative ... - int copiedADXNs = CopyBuffer(adxHandler, MINUSDI_LINE, 0, limit, adxnBuffer); - - // - // ATR ... - int copiedATRs = CopyBuffer(atrHandler, MAIN_LINE, 0, limit, atrBuffer); - - // - // CCI ... - int copiedCCIs = CopyBuffer(cciHandler, MAIN_LINE, 0, limit, cciBuffer); - - // - // RSI ... - int copiedRSIs = CopyBuffer(rsiHandler, MAIN_LINE, 0, limit, rsiBuffer); - - // - // MFI ... - int copiedMFIs = CopyBuffer(mfiHandler, MAIN_LINE, 0, limit, mfiBuffer); - - // - // RVI ... - int copiedRVIs = CopyBuffer(rviHandler, MAIN_LINE, 0, limit, rviBuffer); - - // - // RVI ... - int copiedRVISignals = CopyBuffer(rviHandler, SIGNAL_LINE, 0, limit, rviSignalBuffer); - - // - // MACD ... - int copiedMACDs = CopyBuffer(macdHandler, MAIN_LINE, 0, limit, macdBuffer); - - // - // MACD Signal ... - int copiedMACDSignals = CopyBuffer(macdHandler, SIGNAL_LINE, 0, limit, macdSignalBuffer); - - // - // Momentum ... - int copiedMomentums = CopyBuffer(cciHandler, MAIN_LINE, 0, limit, momentumBuffer); - - // - // Stochastic ... - int copiedStochastics = CopyBuffer(stochasticHandler, MAIN_LINE, 0, limit, stochasticBuffer); - - // - // Stochastic Signal ... - int copiedStochasticSignals = CopyBuffer(stochasticHandler, SIGNAL_LINE, 0, limit, stochasticSignalBuffer); - - // - // Validate Copied Items ... - bool isPassedRequiredCopiedItems = - // - // AC ... - copiedACs > 0 && - // - // AD ... - copiedADs > 0 && - // - // ADX ... - copiedADXs > 0 && - // - // ADX Plus ... - copiedADXPs > 0 && - // - // ADX Negative ... - copiedADXNs > 0 && - // - // ATR ... - copiedATRs > 0 && - // - // CCI ... - copiedCCIs > 0 && - // - // RSI ... - copiedRSIs > 0 && - // - // MFI ... - copiedMFIs > 0 && - // - // RVI ... - copiedRVIs > 0 && - // - // RVI Signal ... - copiedRVISignals > 0 && - // - // MACD ... - copiedMACDs > 0 && - // - // MACD Signal ... - copiedMACDSignals > 0 && - // - // Momentum ... - copiedMomentums > 0 && - // - // Stochastic ... - copiedStochastics > 0 && - // - // Stochastic Signal ... - copiedStochasticSignals > 0 - // - ; - 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 = - // - adxLength > 0 && - atrLength > 0 && - cciLength > 0 && - rsiLength > 0 && - mfiLength > 0 && - rviLength > 0 && - // - macdFastLength > 0 && - macdSlowLength > 0 && - macdSignalLength > 0 && - macdFastLength < macdSlowLength && - // - stochasticKLength > 0 && - stochasticDLength > 0 && - stochasticSmoothingLength > 0 && - // - momentumLength > 0 - // - ; - - // - return result; -} - -/** - * Initialize All Indicators Handlers ... - * - * @return ( bool ) - */ -bool InitializeHandlres() -{ - // - bool result = false; - - // - // AC ... - acHandler = iAC(_Symbol, _Period); - result = acHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // AD ... - adHandler = iAD( - _Symbol, - _Period, - adAppliedTo // - ); - result = adHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // ADX ... - adxHandler = iADX( - _Symbol, - _Period, - adxLength // - ); - result = adxHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // ATR ... - atrHandler = iATR( - _Symbol, - _Period, - atrLength // - ); - result = atrHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // CCI ... - cciHandler = iCCI( - _Symbol, - _Period, - cciLength, - cciAppliedTo // - ); - result = cciHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // RSI ... - rsiHandler = iRSI( - _Symbol, - _Period, - rsiLength, - rsiAppliedTo // - ); - result = rsiHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // MFI ... - mfiHandler = iMFI( - _Symbol, - _Period, - mfiLength, - mfiAppliedTo // - ); - result = mfiHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // RVI ... - rviHandler = iRVI( - _Symbol, - _Period, - rviLength // - ); - result = rviHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // MACD ... - macdHandler = iMACD( - _Symbol, - _Period, - macdFastLength, - macdSlowLength, - macdSignalLength, - macdAppliedTo // - ); - result = macdHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // Momentum ... - momentumHandler = iMomentum( - _Symbol, - _Period, - momentumLength, - momentumAppliedTo // - ); - result = momentumHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - // Stochastic ... - stochasticHandler = iStochastic( - _Symbol, - _Period, - stochasticKLength, - stochasticDLength, - stochasticSmoothingLength, - stochasticSmoothingMethod, - stochasticAppliedTo // - ); - result = stochasticHandler != INVALID_HANDLE; - if (!result) - { - return result; - } - - // - return result; -} - -/** - * Release All Indicators ... - */ -void DeInitializeHandlres() -{ - // - IndicatorRelease(acHandler); - IndicatorRelease(adHandler); - IndicatorRelease(adxHandler); - IndicatorRelease(atrHandler); - IndicatorRelease(cciHandler); - IndicatorRelease(rsiHandler); - IndicatorRelease(mfiHandler); - IndicatorRelease(rviHandler); - IndicatorRelease(macdHandler); - IndicatorRelease(momentumHandler); - IndicatorRelease(stochasticHandler); -} - -/** - * Extract Max Length of Inputs ... - * - * @return ( int ) - */ -int ExtractMaxLengthOfInputs() -{ - // - int result = 0; - - // - result = MathMax(adxLength, atrLength); - result = MathMax(result, cciLength); - result = MathMax(result, rsiLength); - result = MathMax(result, mfiLength); - result = MathMax(result, rviLength); - result = MathMax(result, momentumLength); - result = MathMax(result, macdFastLength); - result = MathMax(result, macdSlowLength); - result = MathMax(result, macdSignalLength); - result = MathMax(result, stochasticKLength); - result = MathMax(result, stochasticDLength); - result = MathMax(result, stochasticSmoothingLength); - - // - return result; -} - -/** - * Set Indicator Short Name and also we can define Buffers Labels ... - */ -void SetIndicatorName() -{ - // - IndicatorSetInteger(INDICATOR_DIGITS, _Digits); - IndicatorSetString(INDICATOR_SHORTNAME, ShortName); -} - -/** - * Define Required Buffers ... - */ -void DefineBuffers() -{ - // - // Plot Buffers ... - - // - // Data Buffers ... - - // - // AC ... - ArraySetAsSeries(acBuffer, true); - SetIndexBuffer(acBufferIndex, acBuffer, INDICATOR_CALCULATIONS); - - // - // AD ... - ArraySetAsSeries(adBuffer, true); - SetIndexBuffer(adBufferIndex, adBuffer, INDICATOR_CALCULATIONS); - - // - // ADX ... - ArraySetAsSeries(adxBuffer, true); - SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS); - - // - // ADX Plus ... - ArraySetAsSeries(adxpBuffer, true); - SetIndexBuffer(adxpBufferIndex, adxpBuffer, INDICATOR_CALCULATIONS); - - // - // ADX Negative ... - ArraySetAsSeries(adxnBuffer, true); - SetIndexBuffer(adxnBufferIndex, adxnBuffer, INDICATOR_CALCULATIONS); - - // - // ATR ... - ArraySetAsSeries(atrBuffer, true); - SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS); - - // - // CCI ... - ArraySetAsSeries(cciBuffer, true); - SetIndexBuffer(cciBufferIndex, cciBuffer, INDICATOR_CALCULATIONS); - - // - // RSI ... - ArraySetAsSeries(rsiBuffer, true); - SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS); - - // - // MFI ... - ArraySetAsSeries(mfiBuffer, true); - SetIndexBuffer(mfiBufferIndex, mfiBuffer, INDICATOR_CALCULATIONS); - - // - // RVI ... - ArraySetAsSeries(rviBuffer, true); - SetIndexBuffer(rviBufferIndex, rviBuffer, INDICATOR_CALCULATIONS); - - // - // RVI Signal ... - ArraySetAsSeries(rviSignalBuffer, true); - SetIndexBuffer(rviSignalBufferIndex, rviSignalBuffer, INDICATOR_CALCULATIONS); - - // - // MACD ... - ArraySetAsSeries(macdBuffer, true); - SetIndexBuffer(macdBufferIndex, macdBuffer, INDICATOR_CALCULATIONS); - - // - // MACD Signal ... - ArraySetAsSeries(macdSignalBuffer, true); - SetIndexBuffer(macdSignalBufferIndex, macdSignalBuffer, INDICATOR_CALCULATIONS); - - // - // Momentum ... - ArraySetAsSeries(momentumBuffer, true); - SetIndexBuffer(momentumBufferIndex, momentumBuffer, INDICATOR_CALCULATIONS); - - // - // Stochastics ... - ArraySetAsSeries(stochasticBuffer, true); - SetIndexBuffer(stochasticBufferIndex, stochasticBuffer, INDICATOR_CALCULATIONS); - - // - // Stochastics Signal ... - ArraySetAsSeries(stochasticSignalBuffer, true); - SetIndexBuffer(stochasticSignalBufferIndex, stochasticSignalBuffer, INDICATOR_CALCULATIONS); -} - -/** - * 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) - { - // - 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) -{ - // - acBuffer[barIndex] = emptyValue; - adBuffer[barIndex] = emptyValue; - adxBuffer[barIndex] = emptyValue; - adxpBuffer[barIndex] = emptyValue; - adxnBuffer[barIndex] = emptyValue; - atrBuffer[barIndex] = emptyValue; - cciBuffer[barIndex] = emptyValue; - rsiBuffer[barIndex] = emptyValue; - mfiBuffer[barIndex] = emptyValue; - rviBuffer[barIndex] = emptyValue; - macdBuffer[barIndex] = emptyValue; - momentumBuffer[barIndex] = emptyValue; - rviSignalBuffer[barIndex] = emptyValue; - macdSignalBuffer[barIndex] = emptyValue; - stochasticBuffer[barIndex] = emptyValue; - stochasticSignalBuffer[barIndex] = emptyValue; -} - -/** - * Calculate Vales ... - * - * @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 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[] // -) -{ - // - // Implement Colorify Mechanism ... -} - -// diff --git a/XCATBEA/Classes/xcatbea.x-data.collector.class.mq5 b/XCATBEA/Classes/xcatbea.x-data.collector.class.mq5 new file mode 100644 index 00000000..57d02091 --- /dev/null +++ b/XCATBEA/Classes/xcatbea.x-data.collector.class.mq5 @@ -0,0 +1,167 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XCXCATBEADataCollector ... +// Description: Class for XCATBEA Data Collector ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm Class for XCATBEA Data Collector" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.base.class.mq5" + +// +// Definitions ... + +// +// Implementation ... +class XCXCATBEADataCollector : public XCBase +{ + // + // Public ... + public: + // + // Constructors ... + XCXCATBEADataCollector() + { + } + + // + // Deconstructor ... + ~XCXCATBEADataCollector() + { + } + + // + // Properties ... + + // + string Path() + { + return mPath; + } + + // + void Path(string value) + { + // + // Normalizing Collector Path ... + if (IsValid(value)) + { + mPath = value; + } + else + { + mPath = "XCXCATBEADataCollector"; + } + } + + // + // Tools ... + + // + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + mPath + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + int GetFileHandlerForWrite(string filePath) + { + // + int result = INVALID_HANDLE; + + // + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT // + ); + + // + return result; + } + + /** + * Save Specified Content into Specified File Name ... + * + * @param fileName: string, file name ... + * @param content: string, content ... + * + * @return ( bool ) + */ + bool Save( + string fileName, + string content // + ) + { + // + bool result = false; + + // + result = IsValid(content); + if (!result) + { + return result; + } + + // + // + int mHandler = GetFileHandlerForWrite(fileName); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileWrite(mHandler, content); + FileFlush(mHandler); + FileClose(mHandler); + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + + // + string mPath; // Base Collector Path ... +}; diff --git a/XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5 b/XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5 new file mode 100644 index 00000000..10451656 --- /dev/null +++ b/XCATBEA/Classes/xcatbea.x-trade.manager.class.mq5 @@ -0,0 +1,2297 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XCXCATBEATradeManager +// Description: provides all Requirements for Managing Trades ... +// +// +// 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-alert.class.mq5" +#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" +#include "../../Classes/x-saherelm.x-trade.class.mq5" +#include "../../Libraries/x-saherelm.x-poi.lib.mq5" +#include "../Classes/xcatbea.x-data.collector.class.mq5" +#include "../Libraries/xcatbea.lib.mq5" + +// +// Definitions ... + +// +enum ENUM_XCATBEA_TRADE_RESTRICTION_PERIOD +{ + XCATBEA_TRADE_RESTRICATION_NONE, // None + XCATBEA_TRADE_RESTRICATION_HOURLY, // Per Hour + XCATBEA_TRADE_RESTRICATION_DAILY, // Per Day + XCATBEA_TRADE_RESTRICATION_WEEKLY, // Per Week + XCATBEA_TRADE_RESTRICATION_MONTHLY, // Per Month +}; + +// +string ToString(ENUM_XCATBEA_TRADE_RESTRICTION_PERIOD value) +{ + // + string result = NULL; + + // + result = EnumToString(value); + + // + return result; +} + +// +enum ENUM_XCATBEA_TRADE_FINALIZATION +{ + XCATBEA_TRADE_FINAL_NONE, // None + XCATBEA_TRADE_FINAL_TP, // TP + XCATBEA_TRADE_FINAL_SL, // SL + XCATBEA_TRADE_FINAL_CLOSE_IN_PROFIT, // Profit + XCATBEA_TRADE_FINAL_CLOSE_IN_LOSE, // Lost +}; + +// +string ToString(ENUM_XCATBEA_TRADE_FINALIZATION value) +{ + // + string result = NULL; + + // + result = EnumToString(value); + + // + return result; +} + +// +struct XCATBEASymbolInfo +{ + // + // Properties ... + + // + string symbol; // Trading Symbol + + // + int longs; // All Long Trades + int shorts; // All Short Trades + + // + int trades; // All Trades + + // + int losses; // All Loosing Trades + int profits; // All Winning Trades + + // + int managedSLs; // Managed SL(s) + int managedTPs; // Managed TP(s) + int managedTrades; // Managed Trades + + // + // Constructor ... + XCATBEASymbolInfo() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + + // + longs = 0; + shorts = 0; + + // + trades = 0; + + // + losses = 0; + profits = 0; + + // + managedSLs = 0; + managedTPs = 0; + managedTrades = 0; + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValid(symbol); + + // + return result; + } + + // + bool IsSameAs(XCATBEASymbolInfo &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + symbol == item.symbol; + + // + return result; + } +}; + +// +struct XCATBEATradeSession +{ + // + // Properties ... + string start; // Session Start Time (hh:mm) + string end; // Session End Time (hh:mm) + string name; // Session Name + + // + // Constructor ... + XCATBEATradeSession() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + end = NULL; + name = NULL; + start = NULL; + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValid(start) && + IsValid(end); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Check Session is Active or Not ... + bool IsActive(datetime time = NULL) + { + // + bool result = false; + + // + time = NormalizeTime(time); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = IsTimeInRange( + time, + start, + end // + ); + + // + return result; + } +}; + +struct XCATBEASymbolSession +{ + // + // Propeties ... + + // + string symbol; // Trading Symbol + XCATBEATradeSession sessions[]; // Trading Sessions + + // + // Constructor ... + XCATBEASymbolSession() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + Clean(sessions); + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = IsValid(symbol); + + // + return result; + } + + // + // Check Allow Trade in Active Sessions ... + bool CanTrade(datetime time = NULL) + { + // + bool result = false; + + // + // Normalize Args ... + time = NormalizeTime(time); + + // + // Validating ... + result = IsValid(); + if (!result) + { + return result; + } + + // + // if there is not any defined sessions for Symbol ... + // it's allow Trading in all times ... + result = !HasChild(sessions); + if (result) + { + return result; + } + + // + // Detect an Active Session ... + int count = ArraySize(sessions); + for (int i = 0; i < count; i++) + { + // + result = sessions[i].IsActive(time); + if (result) + { + break; + } + } + + // + return result; + } + + // +}; + +// +struct XCATBEATrade +{ + // + // Props ... + double swap; + double profit; + XSignal signal; + ulong positionID; + double commission; + XCATBEAStrategyConditions conditions; + ENUM_XCATBEA_TRADE_FINALIZATION finalize; + + // + datetime signaledAt; + datetime executedAt; + datetime finalizedAt; + + // + // Constructor ... + XCATBEATrade() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleanup Model ... + */ + void Clean() + { + // + swap = 0; + profit = 0; + signal.Clean(); + commission = 0; + positionID = 0; + conditions.Clean(); + finalize = XCATBEA_TRADE_FINAL_NONE; + + // + signaledAt = NULL; + executedAt = NULL; + finalizedAt = NULL; + + // + ZeroMemory(this); + } + + /** + * Check Has Signal ... + * + * @return ( bool ) + */ + bool HasSignal() + { + // + bool result = false; + + // + result = signal.IsValid(); + + // + return result; + } + + /** + * Check Signal Executed or Not ... + * + * @return ( bool ) + */ + bool IsExecuted() + { + // + bool result = false; + + // + result = positionID > 0; + + // + return result; + } + + /** + * Check a Trade is Finalized or not ... + * + * @return ( bool ) + */ + bool IsFinalized() + { + // + bool result = false; + + // + result = HasSignal() && + IsExecuted() && + finalize != XCATBEA_TRADE_FINAL_NONE; + + // + return result; + } + + /** + * Generate Summary Info ... + * + * @return ( string ) + */ + string Summary() + { + // + string result = NULL; + + // + result = + // + ToString("Swap: ", swap) + + ToString("Profit: ", profit) + + ToString("Commission: ", commission) + + ToString("Finalize: ", ToString(finalize)) + + ToString("PositionID: ", positionID) + + ToString("----------------") + "\n" + + ToString("Signaled At: ", ToFormatString(signaledAt)) + + ToString("Executed At: ", ToFormatString(executedAt)) + + ToString("Finalized At: ", ToFormatString(finalizedAt)) + // + ; + + // + return result; + } + + /** + * Get Data Collection File Name ... + * + * @return ( string ) + */ + string GetFileName() + { + // + string result = NULL; + + // + bool hasSignal = HasSignal(); + bool isExecuted = IsExecuted(); + bool isFinalized = IsFinalized(); + if (!hasSignal && !isExecuted && !isFinalized) + { + return result; + } + + // + result = + // + signal.symbol + "\\" + + ToString(signal.type) + "\\" + + (profit >= 0 ? "Profit" : "Loss") + "\\" + + ToString(positionID) + "_" + + ToString(signal.period) + "_" + + ToFormatString(signaledAt) + // + ; + + // + return result; + } + + /** + * Converts Model to String Representation ... + * + * @param onlySignals: Boolean, Specified Represent Only Signal or not ... + * + * @return ( string ) + */ + string ToString( + bool includeSummary = true, + bool includeSignal = true, + bool includeConditions = true // + ) + { + // + string result = NULL; + + // + // Generating Model Summary ... + string summary = Summary(); + + // + // Generating Signal Summary ... + string signalSummary = signal.ToString(); + + // + // Generating Conditions Summary ... + string conditionsSummary = conditions + .conditions + .GenerateSummary( + true, + true, + true, + false // Ignore False Conditions ... + ); + + // + if (includeSummary) + { + // + result += + ToString("----------------") + "\n" + + ToString("Summary: ") + "\n" + + ToString("----------------") + "\n" + + summary + "\n"; + } + + // + if (includeSignal) + { + // + result += + ToString("----------------") + "\n" + + ToString("Signal: ") + "\n" + + ToString("----------------") + "\n" + + signalSummary + "\n"; + } + + // + if (includeConditions) + { + // + result += + ToString("----------------") + "\n" + + ToString("Conditions: ") + "\n" + + ToString("----------------") + "\n" + + conditionsSummary + "\n"; + } + + // + return result; + } +}; + +// +// Implementations ... +class XCXCATBEATradeManager : public XCBaseAlert +{ + // + // Public ... + public: + // + // Props ... + XCTrade *trader; + bool drawSignal; + XCPOIDrawer *drawer; + XTimeTracker timeTracker; + XCXCATBEADataCollector *collector; + + // + // Constructors ... + XCXCATBEATradeManager( + XCTrade *&_trader, + string _path = NULL // Base Path + ) + { + // + trader = _trader; + drawSignal = true; + drawer = new XCPOIDrawer(); + + // + allowTrade = true; + allowLongs = true; + allowShorts = true; + + // + forceCloseAt = NULL; + isForceCloseAtTime = false; + + // + maxAllowedTPs = 0; + maxAllowedSLs = 0; + maxAllowedTrades = 0; + restrictionsPeriod = XCATBEA_TRADE_RESTRICATION_NONE; + + // + reportTrades = true; + reportSignals = true; + reportProtector = true; + reportAfterTradesBalance = true; + + // + SaveTrades(false); + + // + // Normalizing Collector Path ... + if (!IsValid(_path)) + { + _path = "X121XCATBEATradeManager" + "\\" + trader.mAccount.GetCompany(); + } + + // + collector = new XCXCATBEADataCollector(); + collector.Path(_path); + } + + // + // De Constructors ... + ~XCXCATBEATradeManager() + { + // + Clean(trades); + + // + timeTracker.Clean(); + + // + ZeroMemory(trader); + ZeroMemory(drawer); + ZeroMemory(collector); + } + + // + // Properties ... + + // + bool SaveTrades() + { + return mSaveTrades; + } + + // + void SaveTrades(bool value) + { + mSaveTrades = value; + } + + // + void SetForceCloseTradesAt( + string _forceCloseAt // + ) + { + forceCloseAt = _forceCloseAt; + } + + // + void SetTradeSession( + string symbol, + string start, + string end, + string name = NULL // + ) + { + // + // Validate Args ... + bool has = IsValid(end) && + IsValid(start) && + IsValid(symbol); + if (!has) + { + return; + } + + // + // Create Session ... + + // + XCATBEATradeSession session; + + // + session.end = end; + session.name = name; + session.start = start; + + // + int sessionIDX = -1; + has = FindSymbolSession( + sessionIDX, + symbol // + ); + + // + if (!has) + { + // + // Add New Symbol Session ... + + // + XCATBEASymbolSession iSymbolSession; + iSymbolSession.symbol = symbol; + + // + AddTradingSession( + session, + iSymbolSession // + ); + + // + AddRef( + iSymbolSession, + sessions // + ); + + // + iSymbolSession.Clean(); + } + else + { + // + // Update Trading Sessions of Exists Symbol Session ... + AddTradingSession( + session, + sessions[sessionIDX] // + ); + } + + // + // Cleanup Resources ... + session.Clean(); + } + + // + void SetTradeReports( + bool _reportTrades, + bool _reportSignals, + bool _reportProtector, + bool _reportAfterTradesBalance // + ) + { + // + reportTrades = _reportTrades; + reportSignals = _reportSignals; + reportProtector = _reportProtector; + reportAfterTradesBalance = _reportAfterTradesBalance; + } + + // + void SetTradePermissions( + bool _allowTrade, + bool _allowLongs, + bool _allowShorts // + ) + { + // + allowTrade = _allowTrade; + allowLongs = _allowLongs; + allowShorts = _allowShorts; + } + + // + void SetTradeRestrictions( + ENUM_XCATBEA_TRADE_RESTRICTION_PERIOD _period, + int _maxAllowedTPs, + int _maxAllowedSLs, + int _maxAllowedTrades // + ) + { + // + // Normalizing Args ... + _maxAllowedTPs = NormalizeInt(_maxAllowedTPs, 0); + _maxAllowedSLs = NormalizeInt(_maxAllowedSLs, 0); + _maxAllowedTrades = NormalizeInt(_maxAllowedTrades, 0); + + // + restrictionsPeriod = _period; + maxAllowedTPs = _maxAllowedTPs; + maxAllowedSLs = _maxAllowedSLs; + maxAllowedTrades = _maxAllowedTrades; + } + + // + // Tools ... + + /** + * Do All Position Managing Senaros ... + */ + void Manage() + { + // + // Handle Restrictions ... + HandleRestrictions(); + + // + // Check Contains Trades for Managing ... + bool has = HasChild(trades); + if (!has) + { + return; + } + + // + // Update Required Infos of Trades ... + int count = ArraySize(trades); + for (int i = 0; i < count; i++) + { + // + has = trades[i].IsExecuted() && + !trades[i].IsFinalized(); + if (!has) + { + continue; + } + + // + XPosition iPosition; + has = trader.GetPosition( + trades[i].positionID, + iPosition // + ); + if (!has) + { + continue; + } + + // + // Update Trade Data ... + trades[i].swap = iPosition.swap; + trades[i].profit = iPosition.profit; + } + + // + // Do Trade Protection ... + Protect(); + } + + /** + * Do All Position Protection Here ... + */ + void Protect() + { + // + string prefix = "Protector: "; + int targetDistance = 5; + + // + bool has = HasChild(trades); + if (!has) + { + return; + } + + // + XPosition ownPosition[]; + XPosition ownLongPosition[]; + XPosition ownShortPosition[]; + + // + int count = ArraySize(trades); + for (int i = 0; i < count; i++) + { + // + has = + trades[i].IsExecuted() && + !trades[i].IsFinalized(); + if (!has) + { + continue; + } + + // + XPosition iPosition; + has = trader.GetPosition( + trades[i].positionID, + iPosition // + ); + if (!has) + { + continue; + } + + // + AddRef( + iPosition, + ownPosition // + ); + + // + if (IsLong(iPosition.type)) + { + // + AddRef( + iPosition, + ownLongPosition // + ); + } + else + { + // + AddRef( + iPosition, + ownShortPosition // + ); + } + } + + // + has = HasChild(ownPosition); + if (!has) + { + // + Clean(ownPosition); + Clean(ownLongPosition); + Clean(ownShortPosition); + + // + return; + } + + // + double swapSum = 0; + double profitSum = 0; + double commissionSum = 0; + + // + // Calculate Required Data On Collection ... + count = ArraySize(ownPosition); + for (int i = 0; i < count; i++) + { + // + XPosition iPosition = ownPosition[i]; + + // + swapSum += iPosition.swap; + profitSum += iPosition.profit; + commissionSum += iPosition.commission; + } + + // + // Do Collection Protectiong ... + + // + // Check Force Close ... + if (IsValid(forceCloseAt)) + { + // + datetime forceCloseTime = ParseDateTimeFromTimeString(forceCloseAt); + bool canForceClose = IsTimeInRange( + TimeCurrent(), + forceCloseTime // + ) && + !isForceCloseAtTime; + if (canForceClose) + { + // + isForceCloseAtTime = HandleForceCloseTrades(ownPosition); + + // + // Prevent Moving Forward ... + return; + } + } + + // + // Do Signle Protections ... + for (int i = 0; i < count; i++) + { + // + // Select Position ... + XPosition iPosition = ownPosition[i]; + int idx = -1; + has = HasTrade( + idx, + iPosition.ticket // + ); + if (!has) + { + continue; + } + + // + bool isLong = IsLong(iPosition.type); + double points = GetPoints(iPosition.symbol); + + // + // Handle RF On Targets ... + if (iPosition.profit > 0) + { + // + // Handle Risk Free On Targets ... + XTarget targets[]; + Copy( + trades[idx].signal.targets, + targets // + ); + int targetsCount = ArraySize(targets); + has = IsValidSize(targetsCount); + if (has) + { + // + for (int j = 0; j < targetsCount; j++) + { + // + XTarget jTarget = targets[j]; + + // + int appliedTargetIDX = -1; + + // + // Check Target is Applied Before or Not ... + has = + !trades[idx].signal.isTargetApplied + ? true + : trades[idx].signal.appliedTargetIDX < j; + if (!has) + { + continue; + } + + // + // Check Traget Validation ... + has = + iPosition.sl == 0 + ? true + : isLong + ? iPosition.sl < jTarget.target + : iPosition.sl > jTarget.target; + if (!has) + { + continue; + } + + // + double targetDelta = isLong + ? jTarget.target + (targetDistance * points) + : jTarget.target - (targetDistance * points); + + // + // Can Risk Free ... + bool canRF = + jTarget.doRF && + jTarget.target > 0 && + (isLong + ? jTarget.target > iPosition.entry + : jTarget.target < iPosition.entry) && + (isLong + ? iPosition.price > targetDelta + : iPosition.price < targetDelta); + + // + // Can Partial Close ... + bool canPC = + jTarget.volumeMultiplier > 0 && + jTarget.target > 0 && + (isLong + ? jTarget.target > iPosition.entry + : jTarget.target < iPosition.entry) && + (isLong + ? iPosition.price > targetDelta + : iPosition.price < targetDelta); + bool canRFPC = canRF || + canPC; + if (canRFPC) + { + // + // Handle Risk Free ... + bool isRFDone = false; + if (canRF) + { + // + double tp = iPosition.tp; + double sl = jTarget.target; + string comment = "RF On Target ..."; + isRFDone = trader.Modify( + iPosition.ticket, + sl, + tp, + comment // + ); + } + + // + // Handle Partail Close ... + bool isPCDone = false; + if (canPC) + { + // + double volume = jTarget.volumeMultiplier * iPosition.volume; + volume = NormalizeVolume(volume, iPosition.symbol); + string comment = "RF On Target ..."; + isPCDone = trader.ClosePartial( + iPosition.ticket, + volume, + comment // + ); + } + + // + // Handle Report Action ... + bool isRFPCDone = isRFDone || + isPCDone; + if (isRFPCDone) + { + // + trades[idx].signal.appliedTargetIDX = j; + trades[idx].signal.isTargetApplied = true; + + // + string message = prefix + + ToString(iPosition.type) + + " Position: " + + ToString(iPosition.ticket) + + (isRFDone ? " RF" : "") + + (isPCDone ? " PC" : "") + + " On Traget: " + ToString(jTarget.target) + + " Successfully ..."; + HandleReportProtector(message); + } + } + } + } + } + } + } + + /** + * Check Signal Execution Conditions ... + * + * @param signal: XSignal instance reference ... + * @param executionResult: ENUM_X_SIGNAL_EXECUTION_RESULT member reference ... + * + * @return ( bool ) + */ + bool CheckSignal( + XSignal &signal, + ENUM_X_SIGNAL_EXECUTION_RESULT &executionResult // + ) + { + // + bool result = false; + + // + // Cleanup ... + executionResult = X_SIGNAL_EXECUTION_UNKNOWN; + + // + // Validate Signal ... + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + // Reporting Signal ... + if (reportSignals) + { + // + string message = signal.GetMessage("Provided"); + SendAlert(message); + } + + // + // Check Trade Permission ... + if (!allowTrade) + { + // + result = false; + executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED; + + // + return result; + } + + // + bool isLong = IsLong(signal.type); + bool isShort = IsShort(signal.type); + + // + bool isLongAndAllowed = + isLong && + allowLongs; + + // + bool isShortAndAllowed = + isShort && + allowShorts; + + // + result = isLongAndAllowed || + isShortAndAllowed; + if (!result) + { + // + executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED; + + // + return result; + } + + // + // Check Symbol Info Exists or not ... + int symbolInfoIDX = -1; + bool isSymbolInfoExists = FindSymbolIndex( + symbolInfoIDX, + signal.symbol // + ); + + // + // Check Symbol Session Exists or not ... + int symbolSessionIDX = -1; + bool isSymbolSessionExists = FindSymbolSession( + symbolSessionIDX, + signal.symbol // + ); + + // + // Chack Trade Session Validating ... + if (isSymbolSessionExists) + { + // + result = sessions[symbolSessionIDX].CanTrade(); + if (!result) + { + // + executionResult = X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED; + + // + return result; + } + } + + // + // Check Trade Permissions Based on SL(s) Count ... + bool hasRestrictions = restrictionsPeriod != XCATBEA_TRADE_RESTRICATION_NONE; + if (hasRestrictions) + { + // + // Only Can Check Restrictions when + // Symbol Info Exists ... + if (isSymbolInfoExists) + { + // + bool isTPAllowed = maxAllowedTPs == 0 + ? true + : symbols[symbolInfoIDX].managedTPs < maxAllowedTPs; + bool isSLAllowed = maxAllowedSLs == 0 + ? true + : symbols[symbolInfoIDX].managedSLs < maxAllowedSLs; + bool isTradeAllowed = maxAllowedTrades == 0 + ? true + : symbols[symbolInfoIDX].managedTrades < maxAllowedTrades; + + // + result = isTPAllowed && + isSLAllowed && + isTradeAllowed; + } + + // + // Report Error ... + if (!result) + { + // + executionResult = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; + + // + return result; + } + } + + // + return result; + } + + /** + * Execute Specified Signal ... + * + * @param signal: XSignal instance reference ... + * @param conditions: XCATBEAStrategyConditions instance reference ... + * + * @return ( bool ) + */ + bool Execute( + XSignal &signal, + XCATBEAStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + int idx = -1; + bool isExists = HasTrade( + idx, + signal // + ); + result = !isExists; + if (!result) + { + return result; + } + + // + ENUM_X_SIGNAL_EXECUTION_RESULT executionResult; + + // + // Checking Signal For Execution ... + result = CheckSignal( + signal, + executionResult // + ); + if (result) + { + // + result = trader.ExecuteSignal( + signal, + executionResult // + ); + } + + // + // Alert Signal Execution ... + if (reportTrades) + { + // + string executionMessage = ToString(executionResult); + + // + string message = NULL; + if (result) + { + message = signal.GetMessage("Executed"); + } + else + { + message = signal.GetMessage("Failed due (" + executionMessage + ")"); + } + + // + SendAlert(message); + } + + // + if (result) + { + // + // Draw Signal ... + if (drawSignal) + { + // + XCSignalObject *iObj; + isExists = drawer.DrawSignal( + signal, + iObj // + ); + + // + if (isExists) + { + // + mObjects.Add(iObj); + ZeroMemory(iObj); + } + } + + // + // Create Symbol Info Struct ... + XCATBEASymbolInfo iSymbolInfo; + + // + iSymbolInfo.trades = 1; + iSymbolInfo.managedTrades = 1; + iSymbolInfo.symbol = signal.symbol; + + // + bool isLong = IsLong(signal.type); + if (isLong) + { + iSymbolInfo.longs = 1; + } + else + { + iSymbolInfo.shorts = 1; + } + + // + AddOrUpdateSymbolInfo(iSymbolInfo); + + // + // Create Trade Struct ... + XCATBEATrade iTrade; + + // + ulong positionID = trader.GetLastOpenPositionTicket(); + double commission = trader.GetPositionCommission(positionID); + + // + iTrade.signal = signal; + iTrade.conditions = conditions; + iTrade.positionID = positionID; + iTrade.commission = commission; + iTrade.signaledAt = signal.time; + iTrade.executedAt = TimeCurrent(); + + // + AddRef( + iTrade, + trades // + ); + } + + // + return result; + } + + /** + * Handle Position Take Profit ... + * + * @param deal: XDeal instance reference ... + */ + void HandleTP(const XDeal &deal) + { + // + // Check Ticket Exists or not ... + int idx = -1; + bool isExists = HasTrade( + idx, + deal.positionId // + ); + if (!isExists) + { + return; + } + + // + // Apply Required Data ... + trades[idx].swap = deal.swap; + trades[idx].profit = deal.profit; + trades[idx].finalizedAt = TimeCurrent(); + trades[idx].finalize = XCATBEA_TRADE_FINAL_TP; + + // + // Save Trade ... + Save(trades[idx]); + + // + // Handle Balance Reporting ... + string prefix = "TP: " + ToString(trades[idx].profit); + HandleReportBalance(prefix); + + // + // Handle Symbol Info ... + + // + XCATBEASymbolInfo iSymbolInfo; + + // + iSymbolInfo.profits = 1; + iSymbolInfo.managedTPs = 1; + iSymbolInfo.symbol = trades[idx].signal.symbol; + + // + AddOrUpdateSymbolInfo(iSymbolInfo); + + // + RemoveTrade(idx); + } + + /** + * Handle Position Stop Loss ... + * + * @param deal: XDeal instance reference ... + */ + void HandleSL(const XDeal &deal) + { + // + // Check Ticket Exists or not ... + int idx = -1; + bool isExists = HasTrade( + idx, + deal.positionId // + ); + if (!isExists) + { + return; + } + + // + // Apply Required Data ... + trades[idx].swap = deal.swap; + trades[idx].profit = deal.profit; + trades[idx].finalizedAt = TimeCurrent(); + trades[idx].finalize = XCATBEA_TRADE_FINAL_SL; + + // + // Save Trade ... + Save(trades[idx]); + + // + // Handle Balance Reporting ... + string prefix = "SL: " + ToString(trades[idx].profit); + HandleReportBalance(prefix); + + // + // Handle Symbol Info ... + + // + bool isInProfit = trades[idx].profit > 0; + + // + XCATBEASymbolInfo iSymbolInfo; + + // + if (isInProfit) + { + // + iSymbolInfo.profits = 1; + iSymbolInfo.managedTPs = 1; + } + else + { + // + iSymbolInfo.losses = 1; + iSymbolInfo.managedSLs = 1; + } + iSymbolInfo.symbol = trades[idx].signal.symbol; + + // + AddOrUpdateSymbolInfo(iSymbolInfo); + + // + RemoveTrade(idx); + } + + /** + * Handle Position Force Close ... + * + * @param deal: XDeal instance reference ... + */ + void HandleForceClose(const XPosition &position) + { + // + // Check Ticket Exists or not ... + int idx = -1; + bool isExists = HasTrade( + idx, + position.ticket // + ); + if (!isExists) + { + return; + } + + // + bool isInProfit = position.profit > 0; + + // + // Apply Required Data ... + trades[idx].swap = position.swap; + trades[idx].profit = position.profit; + trades[idx].finalizedAt = TimeCurrent(); + trades[idx].commission = position.commission; + trades[idx].finalize = isInProfit + ? XCATBEA_TRADE_FINAL_CLOSE_IN_PROFIT + : XCATBEA_TRADE_FINAL_CLOSE_IN_LOSE; + + // + // Save Trade ... + Save(trades[idx]); + + // + // Handle Balance Reporting ... + string prefix = "Force Close " + + (isInProfit + ? "Profit" + : "Loss") + + ": " + + ToString(trades[idx].profit); + HandleReportBalance(prefix); + + // + // Handle Symbol Info ... + + // + XCATBEASymbolInfo iSymbolInfo; + + // + if (isInProfit) + { + // + iSymbolInfo.profits = 1; + iSymbolInfo.managedTPs = 1; + } + else + { + // + iSymbolInfo.losses = 1; + iSymbolInfo.managedSLs = 1; + } + iSymbolInfo.symbol = trades[idx].signal.symbol; + + // + AddOrUpdateSymbolInfo(iSymbolInfo); + + // + RemoveTrade(idx); + } + + /** + * Handle Position Partially Closed Event ... + * + * @param ticket: ULONG ... + * @param profit: double ... + * @param comment: string ... + */ + void HandlePartiallyClosed( + const ulong ticket, + const double profit, + const string comment // + ) + { + // + // Handle Balance Reporting ... + string prefix = "Partially Closed: " + ToString(ticket); + + // + // Handle Balance Reporting ... + HandleReportBalance(prefix); + } + + /** + * Handle Force Close Trades ... + */ + bool HandleForceCloseTrades( + XPosition &positions[] // + ) + { + // + bool result = false; + + // + result = HasChild(positions); + if (!result) + { + return result; + } + + // + string prefix = "Protector: "; + string comment = "Force Close ..."; + + // + int closedsCount = trader.Close( + positions, + comment // + ); + result = IsValidSize(closedsCount); + if (result) + { + // + string message = prefix + "Force Close (" + ToString(closedsCount) + ") Trades at Specified Time ..."; + HandleReportProtector(message); + } + + // + return result; + } + + // + // TODO: Complete this ... + void HandleGuard() + { + } + + /** + * Find Executed Trade by Providing Position Ticket ... + * + * @param index: int reference, holding founded item index ... + * @param ticket: ulong, Specified Position Ticket ... + * + * @return ( bool ) + */ + bool HasTrade( + int &index, + ulong ticket // + ) + { + // + bool result = false; + + // + index = -1; + + // + result = + ticket > 0 && + HasChild(trades); + if (!result) + { + return result; + } + + // + int count = ArraySize(trades); + for (int i = 0; i < count; i++) + { + // + XCATBEATrade iTrade = trades[i]; + + // + result = + iTrade.HasSignal() && + iTrade.IsExecuted() && + iTrade.positionID == ticket; + if (result) + { + // + index = i; + + // + iTrade.Clean(); + break; + } + + // + iTrade.Clean(); + } + + // + result = IsValidIndex(index); + + // + return result; + } + + /** + * Find Trade Item By Signal ... + * + * @param index: int reference, holding founded item index ... + * + * @return ( bool ) + */ + bool HasTrade( + int &index, + XSignal &signal // + ) + { + // + bool result = false; + + // + index = -1; + + // + result = + signal.IsValid() && + HasChild(trades); + if (!result) + { + return result; + } + + // + int count = ArraySize(trades); + for (int i = 0; i < count; i++) + { + // + XCATBEATrade iTrade = trades[i]; + + // + result = + iTrade.HasSignal() && + iTrade.signal.IsSameAs(signal); + if (result) + { + // + index = i; + + // + iTrade.Clean(); + break; + } + + // + iTrade.Clean(); + } + + // + result = IsValidIndex(index); + + // + return result; + } + + /** + * Remove a Trade From List ... + * + * @param index: int ... + */ + void RemoveTrade(int index) + { + // + bool has = + HasChild(trades) && + IsValidIndex(index) && + index < ArraySize(trades); + if (!has) + { + return; + } + + // + ArrayRemove( + trades, + index, + 1 // + ); + } + + // + // Protected ... + protected: + // + // Tools ... + + // + string GetFilePath(XCATBEATrade &trade) + { + // + string fileName = trade.GetFileName(); + + // + return GetFilePath(fileName); + } + + // + string GetFilePath(string fileName) + { + // + string result = NULL; + + // + string mPath = collector.Path(); + + // + result = + // + mPath + "\\" + "Trades" + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + void HandleReportBalance(string prefix = NULL) + { + // + if (!reportAfterTradesBalance) + { + return; + } + + // + double balance = trader.mAccount.GetBalance(); + string currency = trader.mAccount.GetCurrency(); + + // + string message = + (IsValid(prefix) + ? prefix + "\n" + : "") + + "Account Balance: " + ToString(balance) + currency; + SendAlert(message); + } + + // + void HandleReportProtector(string message = NULL) + { + // + if (!reportProtector) + { + return; + } + + // + SendAlert(message); + } + + // + bool Save( + XCATBEATrade &trade, + bool includeSummary = true, + bool includeSignal = true, + bool includeConditions = true // + ) + { + // + bool result = false; + + // + if (!mSaveTrades) + { + return result; + } + + // + string filePath = GetFilePath(trade); + result = IsValid(filePath); + if (!result) + { + return result; + } + + // + string content = trade.ToString( + includeSummary, + includeSignal, + includeConditions // + ); + + // + result = collector.Save( + filePath, + content // + ); + + // + return result; + } + + // + // Symbol Info ... + + // + bool FindSymbolIndex( + int &index, + XCATBEASymbolInfo &item // + ) + { + // + bool result = false; + + // + index = -1; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + result = HasChild(symbols); + if (!result) + { + return result; + } + + // + index = FindIndex( + item, + symbols // + ); + + // + result = IsValidIndex(index); + + // + return result; + } + + // + bool FindSymbolIndex( + int &index, + string symbol // + ) + { + // + bool result = false; + + // + index = -1; + + // + result = IsValid(symbol) && + HasChild(symbols); + if (!result) + { + return result; + } + + // + int count = ArraySize(symbols); + for (int i = 0; i < count; i++) + { + // + result = symbols[i].symbol == symbol; + if (result) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + // + void AddOrUpdateSymbolInfo(XCATBEASymbolInfo &item) + { + // + bool has = item.IsValid(); + if (!has) + { + return; + } + + // + int index = -1; + bool isExists = FindSymbolIndex( + index, + item // + ); + if (!isExists) + { + // + AddRef( + item, + symbols // + ); + } + else + { + // + symbols[index].longs += item.longs; + symbols[index].shorts += item.shorts; + symbols[index].trades += item.trades; + symbols[index].losses += item.losses; + symbols[index].profits += item.profits; + symbols[index].managedSLs += item.managedSLs; + symbols[index].managedTPs += item.managedTPs; + symbols[index].managedTrades += item.managedTrades; + } + } + + // + void ResetSymbolsRestrictions() + { + // + bool has = HasChild(symbols); + if (has) + { + // + string prefix = "Protector: "; + + // + int count = ArraySize(symbols); + for (int i = 0; i < count; i++) + { + // + symbols[i].managedSLs = 0; + symbols[i].managedTPs = 0; + symbols[i].managedTrades = 0; + } + + // + string message = prefix + "Reset Symbols Restrictions"; + HandleReportProtector(message); + } + } + + // + void HandleRestrictions() + { + // + bool isNewDay = timeTracker.IsNewDay(); + bool isNewHour = timeTracker.IsNewHour(); + bool isNewWeek = timeTracker.IsNewWeek(); + bool isNewMonth = timeTracker.IsNewMonth(); + + // + // Reset Force Closed Flag on new Day Starts ... + if (isNewDay) + { + isForceCloseAtTime = false; + } + + // + bool canResetRestrictions = + ( + // + // Hourly ... + (isNewHour && + restrictionsPeriod == XCATBEA_TRADE_RESTRICATION_HOURLY) + // + || + // + // Daily ... + (isNewDay && + restrictionsPeriod == XCATBEA_TRADE_RESTRICATION_DAILY) + // + || + // + // Weekly ... + (isNewWeek && + restrictionsPeriod == XCATBEA_TRADE_RESTRICATION_WEEKLY) + // + || + // + // Monthly ... + (isNewMonth && + restrictionsPeriod == XCATBEA_TRADE_RESTRICATION_MONTHLY) + // + ) + // + ; + if (canResetRestrictions) + { + ResetSymbolsRestrictions(); + } + } + + // + // Symbol Session ... + + // + bool FindSymbolSession( + int &index, + string symbol // + ) + { + // + bool result = false; + + // + index = -1; + + // + result = IsValid(symbol) && + HasChild(sessions); + if (!result) + { + return result; + } + + // + int count = ArraySize(sessions); + for (int i = 0; i < count; i++) + { + // + result = sessions[i].symbol == symbol; + if (result) + { + // + index = i; + break; + } + } + + // + result = IsValidIndex(index); + + // + return result; + } + + // + void AddTradingSession( + XCATBEATradeSession &session, + XCATBEASymbolSession &symbolSession // + ) + { + // + bool has = session.IsValid() && + symbolSession.IsValid(); + if (!has) + { + return; + } + + // + // Check Session Exists in Symbol Session ... + bool isExists = false; + if (HasChild(symbolSession.sessions)) + { + // + int count = ArraySize(symbolSession.sessions); + for (int i = 0; i < count; i++) + { + // + isExists = symbolSession.sessions[i].end == session.end && + symbolSession.sessions[i].start == session.start; + if (isExists) + { + break; + } + } + } + + // + if (!isExists) + { + // + AddRef( + session, + symbolSession.sessions // + ); + } + } + + // + // Private ... + private: + // + // Props ... + + // + bool allowTrade; + bool allowLongs; + bool allowShorts; + + // + string forceCloseAt; + bool isForceCloseAtTime; + + // + int maxAllowedTPs; + int maxAllowedSLs; + int maxAllowedTrades; + ENUM_XCATBEA_TRADE_RESTRICTION_PERIOD restrictionsPeriod; + + // + bool mSaveTrades; + + // + bool reportTrades; + bool reportSignals; + bool reportProtector; + bool reportAfterTradesBalance; + + // + CArrayObj mObjects; + + // + XCATBEATrade trades[]; + XCATBEASymbolInfo symbols[]; + XCATBEASymbolSession sessions[]; +}; + +// diff --git a/XCATBEA/Libraries/xcatbea.lib.mq5 b/XCATBEA/Libraries/xcatbea.lib.mq5 new file mode 100644 index 00000000..6010865c --- /dev/null +++ b/XCATBEA/Libraries/xcatbea.lib.mq5 @@ -0,0 +1,293 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XCATBEA Lib +// Description: Library for XCATBEA ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm Library for XCATBEA Signaller" +#property strict + +// +// Imports ... +#include "../../Libraries/x-saherelm.common.lib.mq5" +#include "../../Libraries/x-saherelm.x-poi.lib.mq5" +#include "../../Libraries/x-saherelm.x-trade.lib.mq5" +#include "../../Helpers/x-saherelm.x121.xcatb.helper.mq5" + +// +// Enumeration ... + +// +// Guard Actions ... +enum ENUM_XCATBEA_GUARD_ACTIONS +{ + XCATBEA_GUARD_ACTION_NONE, // Nothing to Do + XCATBEA_GUARD_ACTION_CLOSE, // Close Specified Position + XCATBEA_GUARD_ACTION_CLOSE_ALL, // Close All Positions + XCATBEA_GUARD_ACTION_CLOSE_LONGS, // Close All Long Positions + XCATBEA_GUARD_ACTION_CLOSE_SHORTS, // Close All Short Position + XCATBEA_GUARD_ACTION_PARTIAL_CLOSE, // Partial Close Specified Position + XCATBEA_GUARD_ACTION_TRAIL_STOP, // Trail Stop of Specified Position + XCATBEA_GUARD_ACTION_TRAIL_TARGET, // Trail Target of Specified Position + XCATBEA_GUARD_ACTION_HEDGE, // Hedge Specified Positions +}; + +// +// Definitions ... + +// +// Conditions Struct ... +struct XCATBEAStrategyConditions +{ + // + // Props ... + + // + string symbol; + ENUM_TIMEFRAMES period; + + // + // Setup Props ... + + // + double sl; + double tp; + double pivot; + double point; + double entry; + double reward; + string provider; + + // + XTarget targets[]; + + // + datetime time; + datetime setupTime; + datetime triggerTime; + + // + ENUM_X_DIRECTION dir; + XBoxZone decisionZone; + ENUM_X_POSITION_TYPES type; + X121XCatbConditions conditions; + + // + // Constructor ... + XCATBEAStrategyConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + sl = 0; + tp = 0; + pivot = 0; + point = 0; + entry = 0; + reward = 0; + + // + symbol = NULL; + period = NULL; + provider = NULL; + + // + time = NULL; + setupTime = NULL; + triggerTime = NULL; + + // + Clean(targets); + + // + conditions.Clean(); + decisionZone.Clean(); + + // + dir = X_DIRECTION_NONE; + type = X_POSITION_TYPE_NONE; + + // + ZeroMemory(this); + } + + // + // Signalling ... + + /** + * Validate ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = IsSpecifiedValid(symbol) && + IsSpecifiedValid(period) && + IsSpecifiedValid(time); + + // + return result; + } + + /** + * Check Conditions Has Valid Bullish Signal ... + * + * @return ( bool ) + */ + bool HasBullishSignal() + { + // + bool result = false; + + // + result = + (sl > 0 || + tp > 0) && + IsValid() && + HasDirection(dir); + if (!result) + { + return result; + } + + // + result = + IsBullish(dir); + + // + return result; + } + + /** + * Check Conditions Has Valid Bearish Signal ... + * + * @return ( bool ) + */ + bool HasBearishSignal() + { + // + bool result = false; + + // + result = + (sl > 0 || + tp > 0) && + IsValid() && + HasDirection(dir); + if (!result) + { + return result; + } + + // + result = + IsBearish(dir); + + // + return result; + } + + // + // Setting Up and Triggering Up ... + + /** + * Check Condition is Setting Up ... + * + * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... + * + * @return ( bool ) + */ + bool IsSetuped() + { + // + bool result = false; + + // + result = IsValid(setupTime) && + HasDirection(dir); + if (!result) + { + return result; + } + + // + return result; + } + + /** + * Calculate Setup Age ... + * + * @return ( int ) + */ + int GetSetupAge() + { + // + int result = 0; + + // + if (!IsSetuped()) + { + return result; + } + + // + result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); + + // + return result; + } + + /** + * Detect How we Can Trigger Signal ... + * + * @return ( bool ) + */ + bool CanTrigger() + { + // + bool result = false; + + // + result = + // + sl > 0 && + IsValid(symbol) && + IsValid(period) && + IsValid(triggerTime) && + type != X_POSITION_TYPE_ALL && + type != X_POSITION_TYPE_NONE + // + ; + + // + return result; + } + + // +}; diff --git a/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 new file mode 100644 index 00000000..6275f2b9 --- /dev/null +++ b/XCATBEA/Libraries/xcatbea.signaller.lib.mq5 @@ -0,0 +1,2096 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Library +// --------------------------------------- +// Name: XCATBEASignallerLib +// Description: required Parsers for XCATBEA Signaller ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright `023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Libraries/xcatbea.lib.mq5" +#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5" +#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" + +// +// Definiions ... + +// +#define XLiquidityToken "XLQ"; +#define XTriggerBlockToken "XTRG"; + +// +struct XTriggerBlock +{ + // + // Props ... + XBoxZone ob; // Order Block + XBoxZone fvg; // Fair Value Gap + XOHCL swingBar; // Swing of Trigger + XBoxZone trigger; // Trigger Block + XBoxZone rLiquidity; // Reversal Liquidity + XBoxZone fLiquidity; // Following Liquidity + + // + XSignal signal; // Pepared Signal + + // + // Constructor ... + XTriggerBlock() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + ob.Clean(); + fvg.Clean(); + signal.Clean(); + trigger.Clean(); + swingBar.Clean(); + rLiquidity.Clean(); + fLiquidity.Clean(); + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = ob.IsValid() && + fvg.IsValid() && + trigger.IsValid(); + + // + return result; + } + + // + bool IsBullish() + { + return IsValid() && + ob.IsBullish(); + } + + // + bool IsBearish() + { + return IsValid() && + ob.IsBearish(); + } + + // + int ToIndex() + { + return trigger.ToIndex(); + } + + // + int FromIndex() + { + return trigger.FromIndex(); + } + + // + ENUM_X_DIRECTION GetDirection() + { + // + ENUM_X_DIRECTION result = X_DIRECTION_NONE; + + // + if (IsValid()) + { + result = ob.dir; + } + + // + return result; + } + + // +}; + +// +// Trigger Block Validation Rules ... +struct XTriggerBlockValidationRules +{ + // + // Props ... + bool forceHasSwing; // Force Block to Has Propper Swing ... + bool forceOBBarType; // Force Order Block to Has InDirectional Bars ... + int minRequiredOBBar; // Min Required OB Bar ... + bool forceFVGBarType; // Force Fair Value Gaps Bars Type ... + double maxAllowedRange; // Max Allowed Order Block Range ... + double minAllowedRange; // Min Allowed Order Block Range ... + bool forceHasFLiquidity; // Force Order Block To Has Reversal Liquidity ... + bool forceHasRLiquidity; // Force Order Block to Has Following Liquidity ... + int liquidityLoopback; // Liquidity Detection Loopback ... + bool validateGapSequence; // Validate Fair Value Gaps Bar Sequences ... + bool validateBlockEdgeBreakout; // Validate Order Block Edge Breakeout ... + + // + // Constructor(s) ... + XTriggerBlockValidationRules() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + maxAllowedRange = 0; + minAllowedRange = 0; + minRequiredOBBar = 0; + liquidityLoopback = 0; + forceHasSwing = false; + forceOBBarType = false; + forceFVGBarType = false; + forceHasFLiquidity = false; + forceHasRLiquidity = false; + validateGapSequence = false; + validateBlockEdgeBreakout = false; + + // + ZeroMemory(this); + } +}; + +// +// Trigger Block Filters ... +struct XTriggerBlockFilters +{ + // + // Props ... + bool filterBasedOnPV; // Filter Based On PV ... + bool filterBasedOnSar; // Filter Based On SAR ... + bool filterBasedOnRSI; // Filter Based On RSI ... + bool filterBasedOnADX; // Filter Based On ADX ... + bool filterBasedOnATR; // Filter Based On ATR ... + bool filterBasedOnTrend; // Filter Based On Trend ... + bool filterBasedOnDelta; // Filter Based On Delta ... + bool filterBasedOnVolume; // Filter Based On Volume ... + bool filterBasedOnSignalBar; // Filter Based on Signal Bar ... + bool filterBasedOnHKSignalBar; // Filter Based On HK Signal Bar ... + + // + int bosLoopback; // PV Based Filtering BOS Lookup ... + + // + // Constructor(s) ... + XTriggerBlockFilters() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + filterBasedOnPV = false; + filterBasedOnSar = false; + filterBasedOnRSI = false; + filterBasedOnADX = false; + filterBasedOnATR = false; + filterBasedOnTrend = false; + filterBasedOnDelta = false; + filterBasedOnVolume = false; + filterBasedOnSignalBar = false; + filterBasedOnHKSignalBar = false; + + // + bosLoopback = 0; + + // + ZeroMemory(this); + } +}; + +// +// Extensions ... + +/** + * Detect Trigger Block ... + * + * @param helper: XCX121XCatbHelper instance pointer ... + * @param barAnalyser: XCBarAnalyser instance pointer ... + * @param triggerBlock: XTriggerBlock Refrence, holds Detected Trigger Block ... + * @param conditions: X121XCatbConditions Refrence, holds Trigger Block Conditions ... + * @param validations: XTriggerBlockValidationRules Refrence, Provides Trigger Block Validation Rules ... + * @param filters: XTriggerBlockFilters Refrence, Provides Trigger Block Filters ... + * @param barIndex: int, Bar Index ... + * @param loopback: int, Loopback for Conditions reading ... + * + * @return ( bool ) + */ +bool DetectTriggerBlock1( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockValidationRules &validations, + XTriggerBlockFilters &filters, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Normalize Args ... + conditions.Clean(); + triggerBlock.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = + helper != NULL && + barAnalyser != NULL; + if (!result) + { + return result; + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + bool has = false; + string symbol = helper.GetSymbol(); + ENUM_TIMEFRAMES period = helper.GetPeriod(); + + // + // Initial Requirements ... + + // + // Required Bars ... + XOHCL zBar; + XOHCL cBar; + result = + result && + zBar.Init( + symbol, + period, + barIndex // + ); + result = + result && + zBar.GetPreviousBar(cBar); + + // + // Here we Must Detect Order Block ... + // then Detect FVG ... + // then Prepare Trigger Box ... + + // + // Select Application Bar ... + XOHCL iBar; + if (barIndex == 0) + { + iBar = cBar; + } + else if (barIndex > 0) + { + iBar = zBar; + } + iBar = cBar; + result = + result && + iBar.IsValid(); + + // + // Detect Order Block ... + result = + result && + barAnalyser + .IsOB( + iBar, + triggerBlock.ob, + false, + false // + ); + + // + // Detect Fair Value Gap ... + result = + result && + barAnalyser + .IsFVG( + iBar, + triggerBlock.fvg, + false // + ); + + // + // Check Result and Create Trigger Box based on it ... + if (result) + { + // + triggerBlock.trigger = triggerBlock.ob; + triggerBlock.trigger.type = XTriggerBlockToken; + + // + // Update Upper and Lower ... + int toIDX = triggerBlock.ob.ToIndex(); + int fromIDX = triggerBlock.ob.FromIndex(); + + // + iBar.Clean(); + result = iBar.Init( + symbol, + period, + toIDX // + ); + if (result) + { + // + double iLL = iBar.FindLowest(fromIDX - toIDX, MODE_LOW); + double iHH = iBar.FindHighest(fromIDX - toIDX, MODE_HIGH); + + // + triggerBlock.trigger.upper = MathMax(iHH, triggerBlock.trigger.upper); + triggerBlock.trigger.lower = MathMin(iLL, triggerBlock.trigger.lower); + } + + // + iBar.Clean(); + } + + // + // TODO: Remove this ... + // Temparory Testing Configs ... + // validations.maxAllowedRange = 200; + // validations.forceHasSwing = true; + // validations.forceFVGBarType = true; + // validations.forceOBBarType = true; + // validations.validateGapSequence = true; + // validations.validateBlockEdgeBreakout = true; + // validations.liquidityLoopback = 144; + // validations.forceHasFLiquidity = true; + // validations.forceHasRLiquidity = true; + + // + // Apply Validations ... + if (result) + { + // + result = ValidateTriggerBlock( + helper, + barAnalyser, + triggerBlock, + conditions, + validations, + barIndex, + loopback // + ); + + // + if (!result) + { + triggerBlock.Clean(); + } + } + + // + // TODO: Remove this ... + filters.bosLoopback = 30; + filters.filterBasedOnPV = true; + + // + // Apply Filtering ... + if (result) + { + // + result = FilterTriggerBlock( + helper, + barAnalyser, + triggerBlock, + conditions, + filters, + barIndex, + loopback // + ); + + // + if (!result) + { + triggerBlock.Clean(); + } + } + + // + // Summarizing Result ... + result = + result && + triggerBlock.IsValid(); + + // + // Preparing Signal ... + if (result) + { + // + } + + // + // Cleanup Resources ... + + // + iBar.Clean(); + zBar.Clean(); + cBar.Clean(); + + // + if (!result) + { + triggerBlock.Clean(); + } + + // + return result; +} + +/** + * Validate a Trigger Block ... + * + * @param helper: XCX121XCatbHelper instance pointer ... + * @param barAnalyser: XCBarAnalyser instance pointer ... + * @param triggerBlock: XTriggerBlock Refrence, Trigger Block ... + * @param conditions: X121XCatbConditions Refrence, Trigger Block Conditions ... + * @param validations: XTriggerBlockValidationRules Refrence, Provides Trigger Block Validation Rules ... + * @param barIndex: int, Bar Index ... + * @param loopback: int, Loopback for Conditions reading ... + * + * @return ( bool ) + */ +bool ValidateTriggerBlock( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockValidationRules &validations, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Checking Conditions ... + + // + // Normalize Args ... + conditions.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = + helper != NULL && + barAnalyser != NULL && + triggerBlock.IsValid(); + if (!result) + { + return result; + } + + // + // Reading Market Conditions ... + result = helper.GetConditions( + conditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + XOHCL iBar; + int count = 0; + int toIDX = -1; + int fromIDX = -1; + bool has = false; + bool isBullish = triggerBlock.IsBullish(); + bool isBearish = triggerBlock.IsBearish(); + double points = GetPoints(triggerBlock.ob.symbol); + ENUM_X_DIRECTION iDir = triggerBlock.GetDirection(); + + // + // Checking Conditions ... + + // + // Range Validation ... + + // + // Max Allowed OB Range ... + if (result && + validations.maxAllowedRange > 0) + { + // + double iRange = triggerBlock.ob.GetRange(); + result = iRange <= (validations.maxAllowedRange * points); + } + + // + // Min Allowed OB Range ... + if (result && + validations.minAllowedRange > 0) + { + // + double iRange = triggerBlock.ob.GetRange(); + result = iRange >= (validations.maxAllowedRange * points); + } + + // + // Has Swing ... + if (result && + validations.forceHasSwing) + { + // + bool isSwing = false; + toIDX = triggerBlock.ToIndex(); + fromIDX = triggerBlock.FromIndex(); + ENUM_X_DIRECTION swingDir = X_DIRECTION_NONE; + for (int i = toIDX; i <= fromIDX; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + isSwing = + has && + barAnalyser + .IsSimpleSwing( + iBar, + swingDir // + ); + if (isSwing && + swingDir == iDir) + { + break; + } + + // + iBar.Clean(); + } + + // + result = + isSwing && + iBar.IsValid() && + swingDir == iDir; + if (result) + { + // + // Initialize Swing Bar ... + result = triggerBlock + .swingBar + .Init( + iBar.symbol, + iBar.period, + iBar.Index() + 2 // + ); + } + + // + iBar.Clean(); + } + + // + // Force FVG Bar Types ... + if (result && + validations.forceFVGBarType) + { + // + toIDX = triggerBlock.fvg.ToIndex(); + fromIDX = triggerBlock.fvg.FromIndex(); + for (int i = toIDX; i < fromIDX; i++) + { + // + // Initialize iBar ... + result = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + result = + result && + iDir == iBar.GetDirection(); + + // + iBar.Clean(); + + // + if (!result) + { + break; + } + } + + // + iBar.Clean(); + } + + // + // Force OB Start By InDirectional Bars ... + if (result && + validations.forceOBBarType) + { + // + count = 0; + fromIDX = triggerBlock.fvg.FromIndex() + 1; + int sIDX = fromIDX; + has = true; + while (has) + { + // + // Initialize iBar .. + has = iBar.Init( + conditions.symbol, + conditions.period, + fromIDX // + ); + has = has && + iDir == Opposit(iBar.GetDirection()); + if (has) + { + count++; + } + + // + fromIDX++; + } + + // + int required = + validations.minRequiredOBBar > 0 + ? validations.minRequiredOBBar + : 1; + + // + result = count >= required; + + // + // Update Trigger Block Box based on OB Bar Types ... + if (result) + { + // + result = iBar.Init( + conditions.symbol, + conditions.period, + sIDX // + ); + if (result) + { + // + datetime iFrom = GetBarTime( + conditions.symbol, + conditions.period, + sIDX + count // + ); + double iLL = iBar.FindLowest(count, MODE_LOW); + double iHH = iBar.FindHighest(count, MODE_HIGH); + + // + triggerBlock.trigger.from = iFrom; + triggerBlock.trigger.upper = MathMax(iHH, triggerBlock.trigger.upper); + triggerBlock.trigger.lower = MathMin(iLL, triggerBlock.trigger.lower); + } + } + + // + iBar.Clean(); + } + + // + // Force Fair Value Gap to Following Sequence ... + if (result && + validations.validateGapSequence) + { + // + XOHCL iPBar; + toIDX = triggerBlock.fvg.ToIndex(); + fromIDX = triggerBlock.fvg.FromIndex() - 1; + for (int i = toIDX; i < fromIDX; i++) + { + // + result = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + result = + result && + iBar.GetPreviousBar(iPBar); + result = + result && + (isBullish + ? iBar.low > iPBar.low + : iBar.high < iPBar.high); + if (!result) + { + break; + } + + // + iBar.Clean(); + iPBar.Clean(); + } + + // + iBar.Clean(); + iPBar.Clean(); + } + + // + // Validate OB Edge Breakeout Using Gaps End Bar ... + if (result && + validations.validateBlockEdgeBreakout) + { + // + // Initialize Gap End Bar ... + toIDX = triggerBlock.fvg.ToIndex(); + result = iBar.Init( + conditions.symbol, + conditions.period, + toIDX // + ); + + // + result = + result && + (isBullish + ? iBar.open < triggerBlock.ob.upper && + iBar.close > triggerBlock.ob.upper + : iBar.open > triggerBlock.ob.lower && + iBar.close < triggerBlock.ob.lower); + + // + // Here we Can Apply Edge Breakout Using Fibo ... + + // + iBar.Clean(); + } + + // + // Force Block to Has Liquidity ... + if (result && + validations.liquidityLoopback > 0 && + (validations.forceHasFLiquidity || + validations.forceHasRLiquidity)) + { + // + toIDX = triggerBlock.ToIndex(); + fromIDX = triggerBlock.FromIndex(); + ENUM_X_DIRECTION iLiqDir = X_DIRECTION_NONE; + for (int i = toIDX; i < fromIDX + validations.liquidityLoopback; i++) + { + // + // Initialize iBar ... + has = iBar.Init( + conditions.symbol, + conditions.period, + i // + ); + has = + has && + barAnalyser + .IsRejected( + iBar, + iLiqDir, + false, // Force Bar Type ... + true // Force Fibo Pressure ... + ); + + // + bool isFLiq = + has && + iLiqDir == iDir; + if (isFLiq && + validations.forceHasFLiquidity && + !triggerBlock.fLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iLiqDir, + triggerBlock.fLiquidity, + triggerBlock.trigger.to // + ); + } + + // + bool isRLiq = + has && + iLiqDir == Opposit(iDir); + if (isRLiq && + validations.forceHasRLiquidity && + !triggerBlock.rLiquidity.IsValid()) + { + // + FillLiquidity( + iBar, + iLiqDir, + triggerBlock.rLiquidity, + triggerBlock.trigger.to // + ); + } + + // + // Here We Can Apply Liquidity Validations ... + ValidateTriggerBlockLiquidities( + helper, + barAnalyser, + triggerBlock, + conditions, + validations // + ); + + // + // Check Liquidities ... + has = (!validations.forceHasFLiquidity + ? true + : triggerBlock.fLiquidity.IsValid()) && + (!validations.forceHasRLiquidity + ? true + : triggerBlock.rLiquidity.IsValid()); + + // + iBar.Clean(); + + // + if (has) + { + break; + } + } + + // + // Check Result ... + result = (!validations.forceHasFLiquidity + ? true + : triggerBlock.fLiquidity.IsValid()) && + (!validations.forceHasRLiquidity + ? true + : triggerBlock.rLiquidity.IsValid()); + + // + iBar.Clean(); + } + + // + if (!result) + { + triggerBlock.Clean(); + } + + // + // Summarize result ... + result = triggerBlock.IsValid(); + + // + // Cleanup Resources ... + + // + iBar.Clean(); + + // + if (!result) + { + // + conditions.Clean(); + triggerBlock.Clean(); + } + + // + return result; +} + +/** + * Filter a Trigger Block ... + * + * @param helper: XCX121XCatbHelper instance pointer ... + * @param barAnalyser: XCBarAnalyser instance pointer ... + * @param triggerBlock: XTriggerBlock Refrence, Trigger Block ... + * @param conditions: X121XCatbConditions Refrence, Trigger Block Conditions ... + * @param filters: XTriggerBlockFilters Refrence, Provides Trigger Block Filters ... + * @param barIndex: int, Bar Index ... + * @param loopback: int, Loopback for Conditions reading ... + * + * @return ( bool ) + */ +bool FilterTriggerBlock( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockFilters &filters, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Checking Conditions ... + + // + // Normalize Args ... + conditions.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = + helper != NULL && + barAnalyser != NULL && + triggerBlock.IsValid(); + if (!result) + { + return result; + } + + // + // Reading Market Conditions ... + result = helper.GetConditions( + conditions, + barIndex, + loopback // + ); + if (!result) + { + // + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + XOHCL iBar; + int toIDX = -1; + int fromIDX = -1; + bool has = false; + bool isBullish = triggerBlock.IsBullish(); + bool isBearish = triggerBlock.IsBearish(); + double points = GetPoints(triggerBlock.ob.symbol); + ENUM_X_DIRECTION iDir = triggerBlock.GetDirection(); + + // + // Checking Conditions ... + + // + // Filter Based On PV ... + if (result && + filters.filterBasedOnPV) + { + // + // For PV Filtering ... + + // + // Detect Bos ... + if (filters.bosLoopback > 0) + { + // + has = true; + bool isBOS = false; + bool isPeakOverLast = false; + bool isValeUnderLast = false; + toIDX = triggerBlock.ob.ToIndex(); + fromIDX = triggerBlock.ob.FromIndex(); + int sIDX = fromIDX; + while (has) + { + // + double iPeak = helper.GetPeak(sIDX); + double iPPeak = helper.GetPeak(sIDX + 1); + + // + double iVale = helper.GetVale(sIDX); + double iPVale = helper.GetVale(sIDX + 1); + + // + isPeakOverLast = + iPeak > 0 && + iPeak > iPPeak; + + // + isValeUnderLast = + iVale > 0 && + iVale < iPVale; + + // + isBOS = + (isBullish && + isPeakOverLast) || + (isBearish && + isValeUnderLast); + if (isBOS) + { + break; + } + + // + sIDX++; + has = !isBOS && + sIDX < fromIDX + filters.bosLoopback; + } + + // + result = isBOS; + } + } + + // + if (!result) + { + triggerBlock.Clean(); + } + + // + // Summarize result ... + result = triggerBlock.IsValid(); + + // + // Cleanup Resources ... + + // + iBar.Clean(); + + // + if (!result) + { + // + conditions.Clean(); + triggerBlock.Clean(); + } + + // + return result; +} + +// +void ValidateTriggerBlockLiquidities( + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XTriggerBlock &triggerBlock, + X121XCatbConditions &conditions, + XTriggerBlockValidationRules &validations // +) +{ + // + bool has = false; + + // + has = + helper != NULL && + barAnalyser != NULL && + triggerBlock.IsValid() && + (triggerBlock.fLiquidity.IsValid() || + triggerBlock.rLiquidity.IsValid()); + if (!has) + { + return; + } + + // + bool hasFLiq = triggerBlock.fLiquidity.IsValid(); + bool hasRLiq = triggerBlock.rLiquidity.IsValid(); + + // + // TODO: Implement Liquidity Validation ... +} + +// +bool DetectSignalZone( + XCPOIDrawer *&drawer, + XCX121XCatbHelper *helper, + XCBarAnalyser *barAnalyser, + XBoxZone &signalZone, + X121XCatbConditions &conditions, + int barIndex = 0, + int loopback = 10 // +) +{ + // + bool result = false; + + // + // Checking Conditions ... + + // + // Normalize Args ... + signalZone.Clean(); + conditions.Clean(); + barIndex = NormalizeInt(barIndex, 0); + loopback = NormalizeInt(loopback, 0); + + // + // Validate Args ... + result = helper != NULL && + barAnalyser != NULL; + if (!result) + { + return result; + } + + // + // Reading Market Conditions ... + result = helper.GetConditions( + conditions, + barIndex, + loopback // + ); + if (!result) + { + // + signalZone.Clean(); + conditions.Clean(); + + // + return result; + } + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + int p3IDX = p2IDX + 1; + int p4IDX = p3IDX + 1; + + // + double sl = 0; + double tp = 0; + double upper = 0; + double lower = 0; + datetime to = NULL; + datetime from = NULL; + string signalProvider = NULL; + + // + // Checking Conditions ... + + // + // Detect Bar Verifications ... + + // + ENUM_X_DIRECTION iDir; + + // + // Rejected ... + bool isRejected = + barAnalyser + .IsRejected( + conditions.bars[cIDX], + iDir // + ); + bool isBullishRejected = + isRejected && + IsBullish(iDir); + bool isBearishRejected = + isRejected && + IsBearish(iDir); + + // + // Engulfed ... + bool isEngulfed = + barAnalyser + .IsEngulfed( + conditions.bars[cIDX], + iDir // + ); + bool isBullishEngulfed = + isEngulfed && + IsBullish(iDir); + bool isBearishEngulfed = + isEngulfed && + IsBearish(iDir); + + // + // Momentum ... + bool isMomentum = + barAnalyser + .IsMomentum( + conditions.bars[cIDX], + iDir // + ); + bool isBullishMomentum = + isMomentum && + IsBullish(iDir); + bool isBearishMomentum = + isMomentum && + IsBearish(iDir); + + // + bool isBarBullishPressured = + isBullishRejected || + isBullishEngulfed || + isBullishMomentum; + + // + bool isBarBearishPressured = + isBearishRejected || + isBearishEngulfed || + isBearishMomentum; + + // + // Detect Indicator Base Start Directional Movement ... + + // + // SAR ... + + // + bool isSarBullishStart = + // + ( + // + // Current SAR is Directional ... + conditions.isSarBullish && + // + // Previous InDirectional Sar Exists ... + helper.lastSarBearish.IsValid() && + // + // Current Close is Over previous Sar ... + conditions.bars[cIDX].close > helper.lastSarBearish.after && + // + // Before Close is not Over previous Sar ... + conditions.bars[pIDX].close <= helper.lastSarBearish.after + // + ) + // + ; + + // + bool isSarBearishStart = + // + ( + // + // Current SAR is Directional ... + conditions.isSarBearish && + // + // Previous InDirectional Sar Exists ... + helper.lastSarBullish.IsValid() && + // + // Current Close is Under previous ... + conditions.bars[cIDX].close < helper.lastSarBullish.after && + // + // Before Close is not Under previous ... + conditions.bars[pIDX].close >= helper.lastSarBullish.after + // + ) + // + ; + + // + // TREND ... + + // + bool isTrendBullishStart = + // + ( + // + // Current Trend is Directional ... + conditions.isTrendBullish && + // + // Previous InDirectiona; Trend Exists ... + helper.lastTrendBearish.IsValid() && + // + // Current Close is Over previous ... + conditions.bars[cIDX].close > helper.lastTrendBearish.after && + // + // Before close is not Over previous ... + conditions.bars[pIDX].close <= helper.lastTrendBearish.after + // + ) + // + ; + + // + bool isTrendBearishStart = + // + ( + // + // Current Trend is Directional ... + conditions.isTrendBearish && + // + // Previous InDirectiona; Trend Exists ... + helper.lastTrendBullish.IsValid() && + // + // Current Close is Under previous ... + conditions.bars[cIDX].close < helper.lastTrendBullish.after && + // + // Before close is not Under previous ... + conditions.bars[pIDX].close >= helper.lastTrendBullish.after + // + ) + // + ; + + // + // ADX ... + + // + bool isADXBullishStart = + // + ( + // + // ADX Value is Switched to Strong ... + conditions.adxBuffer[cIDX] > conditions.adxThreshold && + conditions.adxBuffer[pIDX] <= conditions.adxThreshold && + // + // ADX must Up ... + conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] && + // + // ADX +DI is Bigger than -DI ... + conditions.adxpBuffer[cIDX] > conditions.adxnBuffer[cIDX] && + // + // ADX +DI is Up ... + conditions.adxpBuffer[cIDX] > conditions.adxpBuffer[pIDX] + // + ) + // + ; + + // + bool isADXBearishStart = + // + ( + // + // ADX Value is Switched to Strong ... + conditions.adxBuffer[cIDX] > conditions.adxThreshold && + conditions.adxBuffer[pIDX] <= conditions.adxThreshold && + // + // ADX must Up ... + conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] && + // + // ADX -DI is Bigger than +DI ... + conditions.adxnBuffer[cIDX] > conditions.adxpBuffer[cIDX] && + // + // ADX -DI is Up ... + conditions.adxnBuffer[cIDX] > conditions.adxnBuffer[pIDX] + // + ) + // + ; + + // + // DELTA ... + + // + bool isDeltaBullishStart = + // + // Check State ... + ( + // + // Delta is Up ... + conditions.deltaBuffer[cIDX] > conditions.deltaBuffer[pIDX] && + // + // Delta Signal is Up ... + conditions.deltaSignalBuffer[cIDX] > conditions.deltaSignalBuffer[pIDX] && + // + // Delta Crossed Over Delta Signal ... + conditions.deltaBuffer[cIDX] > conditions.deltaSignalBuffer[cIDX] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastDeltaBearish.IsValid() && + // + // Current Close is Over last ... + conditions.bars[cIDX].close > helper.lastDeltaBearish.after && + // + // Before Close is not Over last ... + conditions.bars[pIDX].close <= helper.lastDeltaBearish.after + // + ; + + // + bool isDeltaBearishStart = + // + // Check State ... + ( + // + // Delta is Down ... + conditions.deltaBuffer[cIDX] < conditions.deltaBuffer[pIDX] && + // + // Delta Signal is Down ... + conditions.deltaSignalBuffer[cIDX] < conditions.deltaSignalBuffer[pIDX] && + // + // Delta Crossed Under Delta Signal ... + conditions.deltaBuffer[cIDX] < conditions.deltaSignalBuffer[cIDX] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastDeltaBullish.IsValid() && + // + // Current Close is Under last ... + conditions.bars[cIDX].close < helper.lastDeltaBullish.after && + // + // Before Close is not Under last ... + conditions.bars[pIDX].close >= helper.lastDeltaBullish.after + // + ; + + // + // VOLUME ... + + // + bool isVolumeBullishStart = + // + ( + // + // + // Volume is Up ... + conditions.bullishVolumeBuffer[1] > conditions.bullishVolumeBuffer[2] && + // + // Volume Signal is Up ... + conditions.bullishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[2] && + // + // Volume Signals Crossed Over ... + conditions.bullishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[1] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastVolumeBearish.IsValid() && + // + // Current Close is Over last ... + conditions.bars[cIDX].close > helper.lastVolumeBearish.after && + // + // Before Close is not Over last ... + conditions.bars[pIDX].close <= helper.lastVolumeBearish.after + // + ; + + // + bool isVolumeBearishStart = + // + ( + // + // + // Volume is Up ... + conditions.bearishVolumeBuffer[1] > conditions.bearishVolumeBuffer[2] && + // + // Volume Signal is Up ... + conditions.bearishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[2] && + // + // Volume Signals Crossed Over ... + conditions.bearishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[1] + // + ) + // + && + // + // Check Last InDirectional Exists ... + helper.lastVolumeBullish.IsValid() && + // + // Current Close is Over last ... + conditions.bars[cIDX].close < helper.lastVolumeBullish.after && + // + // Before Close is not Over last ... + conditions.bars[pIDX].close >= helper.lastVolumeBullish.after + // + ; + + // + // SIGNAL Bar ... + + // + bool isSBarBullishStart = + // + ( + // + // Check Direction ... + conditions.isSBarBullish && + // + // Previous InDirectional Exists ... + helper.lastSignalBarBearish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.sBarCloseBuffer[cIDX] > helper.lastSignalBarBearish.after && + // + // Prev Signal Bar not close over prev ... + conditions.sBarCloseBuffer[pIDX] <= helper.lastSignalBarBearish.after + // + ) + // + ; + + // + bool isSBarBearishStart = + // + ( + // + // Check Direction ... + conditions.isSBarBearish && + // + // Previous InDirectional Exists ... + helper.lastSignalBarBullish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.sBarCloseBuffer[cIDX] < helper.lastSignalBarBullish.after && + // + // Prev Signal Bar not close over prev ... + conditions.sBarCloseBuffer[pIDX] >= helper.lastSignalBarBullish.after + // + ) + // + ; + + // + // HKSIGNAL Bar ... + + // + bool isHKSBarBullishStart = + // + ( + // + // Check Direction ... + conditions.isHKSBarBullish && + // + // Previous InDirectional Exists ... + helper.lastHKSignalBarBearish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.hkSBarCloseBuffer[cIDX] > helper.lastHKSignalBarBearish.after && + // + // Prev Signal Bar not close over prev ... + conditions.hkSBarCloseBuffer[pIDX] <= helper.lastHKSignalBarBearish.after + // + ) + // + ; + + // + bool isHKSBarBearishStart = + // + ( + // + // Check Direction ... + conditions.isHKSBarBearish && + // + // Previous InDirectional Exists ... + helper.lastHKSignalBarBullish.IsValid() && + // + // Current Signal Bar close over prev ... + conditions.hkSBarCloseBuffer[cIDX] < helper.lastHKSignalBarBullish.after && + // + // Prev Signal Bar not close over prev ... + conditions.hkSBarCloseBuffer[pIDX] >= helper.lastHKSignalBarBullish.after + // + ) + // + ; + + // + // Check for Vale and Peak ... + + // + bool isPeakOverLast = + // + (conditions.peakBuffer[cIDX] > conditions.peakBuffer[pIDX] && + conditions.peakBuffer[pIDX] <= conditions.peakBuffer[p2IDX] && + conditions.bars[cIDX].close > conditions.peakBuffer[pIDX]) + // + ; + + // + bool isValeUnderLast = + // + (conditions.valeBuffer[cIDX] < conditions.valeBuffer[pIDX] && + conditions.valeBuffer[pIDX] >= conditions.valeBuffer[p2IDX] && + conditions.bars[cIDX].close < conditions.valeBuffer[pIDX]) + // + ; + + // + // Start Different Conditions Implemntation ... + + // + // Condition 1: + // --------------------------- + // Descriptions: + // + // + // --------------------------- + + // + // Bullish ... + bool isCond1Bullish = false; + + // + // Bearish ... + bool isCond1Bearish = false; + + // + bool isCond1 = + isCond1Bullish || + isCond1Bearish; + if (isCond1) + { + // + // Prepare Cond1 Based Requirements ... + + // + to = NULL; + upper = 0; + lower = 0; + from = NULL; + + // + // Provider Definition ... + signalProvider = "Cond1"; + } + + // + // Try to Summarize Conditions ... + + // + bool isBullish = + // + isCond1Bullish + // + ; + + // + bool isBearish = + // + isCond1Bearish + // + ; + + // + // Summarize Result ... + result = + isBullish || + isBearish; + if (result) + { + // + // Prepare Signal Zone ... + + // + signalZone.to = to; + signalZone.from = from; + signalZone.upper = upper; + signalZone.lower = lower; + signalZone.type = signalProvider; + signalZone.symbol = conditions.symbol; + signalZone.period = conditions.period; + + // + signalZone.dir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Validate Signal Zone ... + result = signalZone.IsValid(); + } + + // + // Cleanup Resources ... + + // + if (!result) + { + // + signalZone.Clean(); + conditions.Clean(); + } + + // + return result; +} + +// +// Draw Specific Trigger Block ... +bool DrawTriggerBlock( + XTriggerBlock &trigger, + XCPOIDrawer *drawer, + CArrayObj &objects, + datetime to = NULL, + // + bool _drawSignals = false, + int rrZoneLength = 10, + // Styles ... + // + // Trigger Block ... + int tbWidth = 1, // Trigger Block Width + color tbBullishColor = clrAqua, // Trigger Block Bullish Color + color tbBearishColor = clrMagenta, // Trigger Block Bearish Color + ENUM_LINE_STYLE tbStyle = STYLE_DASHDOTDOT, // Trigger Block Style + // + // OB ... + int obWidth = 1, // OB Width + color obBullishColor = clrLime, // OB Bullish Color + color obBearishColor = clrRed, // OB Bearish Color + ENUM_LINE_STYLE obStyle = STYLE_DOT, // OB Style + // + // FVG ... + int fvgWidth = 2, // FVG Width + color fvgBullishColor = clrLime, // FVG Bullish Color + color fvgBearishColor = clrRed, // FVG Bearish Color + ENUM_LINE_STYLE fvgStyle = STYLE_SOLID // FVG Style +) +{ + // + bool result = false; + + // + // Validate Args ... + result = trigger.IsValid() && + drawer != NULL; + if (!result) + { + return result; + } + + // + // Update To ... + bool canUpdateTo = IsValid(to); + if (canUpdateTo) + { + // + trigger.trigger.to = to; + trigger.rLiquidity.to = to; + trigger.fLiquidity.to = to; + } + + // + bool isBullish = trigger.IsBullish(); + + // + // Draw OB ... + if (trigger.ob.IsValid()) + { + // + XCBoxObject *iOBObj; + result = drawer.DrawBox( + trigger.ob, + iOBObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? obBullishColor + : obBearishColor; + + // + iOBObj.BoxColor(iClr); + iOBObj.BoxWidth(obWidth); + iOBObj.BoxStyle(obStyle); + + // + // Store Object ... + objects.Add(iOBObj); + } + ZeroMemory(iOBObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw FVG ... + if (trigger.fvg.IsValid()) + { + // + XCBoxObject *iFVGObj; + result = drawer.DrawBox( + trigger.fvg, + iFVGObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? fvgBullishColor + : fvgBearishColor; + + // + iFVGObj.BoxColor(iClr); + iFVGObj.BoxWidth(fvgWidth); + iFVGObj.BoxStyle(fvgStyle); + + // + // Store Object ... + objects.Add(iFVGObj); + } + ZeroMemory(iFVGObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Trigger ... + if (trigger.trigger.IsValid()) + { + // + XCBoxObject *iTriggerObj; + result = drawer.DrawBox( + trigger.trigger, + iTriggerObj // + ); + if (result) + { + // + // Style Object ... + + // + color iClr = + isBullish + ? tbBullishColor + : tbBearishColor; + + // + iTriggerObj.BoxColor(iClr); + iTriggerObj.BoxWidth(tbWidth); + iTriggerObj.BoxStyle(tbStyle); + + // + // Store Object ... + objects.Add(iTriggerObj); + } + ZeroMemory(iTriggerObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Liquidities ... + + // + // Reversla Liquidity ... + if (trigger.rLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = drawer.DrawBox( + trigger.rLiquidity, + iLiqObj // + ); + if (result) + { + objects.Add(iLiqObj); + } + ZeroMemory(iLiqObj); + + // + if (!result) + { + return result; + } + } + + // + // Following Liquidity ... + if (trigger.fLiquidity.IsValid()) + { + // + XCBoxObject *iLiqObj; + result = drawer.DrawBox( + trigger.fLiquidity, + iLiqObj // + ); + if (result) + { + objects.Add(iLiqObj); + } + ZeroMemory(iLiqObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw Swing Bar ... + if (trigger.swingBar.IsValid()) + { + // + color swingColor = + trigger.fvg.IsBullish() + ? clrAqua + : clrMagenta; + ENUM_X_PRICE swingPType = + trigger.fvg.IsBullish() + ? X_PRICE_LOW + : X_PRICE_HIGH; + + // + XCBarArrowObject *swingObj; + result = drawer.CreateBarArrow( + trigger.swingBar, + swingObj, + swingPType, + 159, + swingColor // + ); + if (result) + { + objects.Add(swingObj); + } + ZeroMemory(swingObj); + + // + if (!result) + { + return result; + } + } + + // + // Draw RR of Signal ... + if (_drawSignals && + trigger.signal.IsValid() && + rrZoneLength > 0) + { + // + XCRRObject *iRRObj; + iRRObj = new XCRRObject(); + result = iRRObj.Create( + drawer.ChartIdentification(), + drawer.SubWindowIdentification(), + trigger.signal, + rrZoneLength // + ); + if (result) + { + // + int iWidth = 2; + ENUM_LINE_STYLE iStyle = STYLE_SOLID; + + // + iRRObj.TPWidth(iWidth); + iRRObj.SLWidth(iWidth); + iRRObj.EntryWidth(iWidth); + iRRObj.TargetWidth(iWidth); + + // + iRRObj.TPStyle(iStyle); + iRRObj.SLStyle(iStyle); + iRRObj.EntryStyle(iStyle); + iRRObj.TargetStyle(iStyle); + + // + iRRObj.TPColor(clrLime); + iRRObj.SLColor(clrRed); + iRRObj.EntryColor(clrYellow); + iRRObj.TargetColor(clrLightBlue); + + // + objects.Add(iRRObj); + } + ZeroMemory(iRRObj); + + // + if (result) + { + return result; + } + } + + // + return result; +} diff --git a/cleanupEX.js b/cleanupEX.js index 483ac260..e4c0e5f2 100644 --- a/cleanupEX.js +++ b/cleanupEX.js @@ -17,8 +17,7 @@ async function handleCleanup() { "Libraries", // Required Libraries "Parsers", // Strategies Filters based on Conditions "Strategies", // Strategies Classes which Provides Signals - "X121SMCEA", // X121SMC EA Projects ... - "XCAEA", // XCAEA Projects ... + "XCATBEA", // XCATBEA Projects ... ]; // diff --git a/compileEA.js b/compileEA.js index bf89a7a0..0859e3d6 100644 --- a/compileEA.js +++ b/compileEA.js @@ -17,6 +17,7 @@ async function handleCompile() { "Parsers", // Strategies Filters based on Conditions "Strategies", // Strategies Classes which Provides Signals "Experts", // Expert Advisers + "XCATBEA", // XCATBEA Projects ... ]; //