From 218dda0a728406addaec19129d88122686b6791c Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 13 Jan 2025 09:33:02 +0330 Subject: [PATCH] add xche to supports list ... --- Experts/x-saherelm.x-121.smc.ea.mq5 | 26 +- Helpers/x-saherelm.x121.helper.mq5 | 856 ++++++++++-- Helpers/x-saherelm.x121.xche.helper.mq5 | 1235 +++++++++++++++++ Helpers/x-saherelm.x121.xpv.helper.mq5 | 61 +- Indicators/x-saherelm.x121.xatr.mq5 | 2 - Indicators/x-saherelm.x121.xche.mq5 | 624 +++++++++ Indicators/x-saherelm.x121.xstr.mq5 | 2 - Libraries/x-saherelm.common.lib.mq5 | 50 +- .../x-121.smc.market.cycle.helper.class.mq5 | 196 ++- X121SMCEA/Libraries/x-121.smc.lib.mq5 | 11 + .../Signals/x-121.smc.xobgpv.signal.lib.mq5 | 12 +- .../Signals/x-121.smc.xobspv.signal.lib.mq5 | 20 +- .../Signals/x-121.smc.xstrpv.signal.lib.mq5 | 1054 ++++++++++---- .../Strategy/x-121.smc.strategy.class.mq5 | 286 +++- 14 files changed, 4021 insertions(+), 414 deletions(-) create mode 100644 Helpers/x-saherelm.x121.xche.helper.mq5 create mode 100644 Indicators/x-saherelm.x121.xche.mq5 diff --git a/Experts/x-saherelm.x-121.smc.ea.mq5 b/Experts/x-saherelm.x-121.smc.ea.mq5 index 83f3a2b6..a1a53b97 100644 --- a/Experts/x-saherelm.x-121.smc.ea.mq5 +++ b/Experts/x-saherelm.x-121.smc.ea.mq5 @@ -58,23 +58,23 @@ input int eaMinRequiredVerificationForSpreadPass = 20; // Minimum Spread Ve // Trade ... input group "Trade"; input bool eaAllowTrade = true; // Allow Open Trade On Signals -input string eaStartTradeAt = ""; // Enable Trade on Signals on Time -input string eaStopTradeAt = ""; // Enable Trade on Signals on Time -input string eaCloseAllTradesAt = ""; // Enable Close All Trades on Signals on Time +input string eaStartTradeAt = "2:00"; // Enable Trade on Signals on Time +input string eaStopTradeAt = "21:00"; // Enable Trade on Signals on Time +input string eaCloseAllTradesAt = "23:55"; // Enable Close All Trades on Signals on Time // // Risk Management ... input group "Risk Management"; -input double eaR2R = 3; // Signallers Risk to Reward Ratio -input double eaVolume = 0.05; // Static Volume -input double eaRiskPercentPerBalance = 0.1; // Risk Percent Per Balance in Each Trade -input bool eaDynamicRiskManagement = false; // Dynamic Risk Management -input bool eaUseDynamicVolume = false; // Use Dynamic Volume -input double eaDynamicVolumeStep = 0.01; // Increase Volume Step -input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume -input double eaMaxAllowedDrawdownToOpenTrades = 3; // Max Allowed Drawdown for Open Trades -input int eaMaxAllowedSLToPauseSignallingPerSymbol = 0; // Max Allowed SL for Pause Signalling Per Symbol -input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 14400; // Pause Signalling Per Symbol afte Max Allowed SL Reached In Seconds +input double eaR2R = 3; // Signallers Risk to Reward Ratio +input double eaVolume = 0.05; // Static Volume +input double eaRiskPercentPerBalance = 1.0; // Risk Percent Per Balance in Each Trade +input bool eaDynamicRiskManagement = false; // Dynamic Risk Management +input bool eaUseDynamicVolume = false; // Use Dynamic Volume +input double eaDynamicVolumeStep = 0.01; // Increase Volume Step +input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume +input double eaMaxAllowedDrawdownToOpenTrades = 3; // Max Allowed Drawdown for Open Trades +input int eaMaxAllowedSLToPauseSignallingPerSymbol = 2; // Max Allowed SL for Pause Signalling Per Symbol +input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 7200; // Pause Signalling Per Symbol afte Max Allowed SL Reached In Seconds // // Protection ... diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index 15c4c538..4083bce5 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -23,6 +23,7 @@ // // Imports ... #include "../Helpers/x-saherelm.x121.xatr.helper.mq5" +#include "../Helpers/x-saherelm.x121.xche.helper.mq5" #include "../Helpers/x-saherelm.x121.xdon.helper.mq5" #include "../Helpers/x-saherelm.x121.xpv.helper.mq5" #include "../Helpers/x-saherelm.x121.xstr.helper.mq5" @@ -38,6 +39,7 @@ struct X121Inputs X121XPVInputs xpvInputs; X121XATRInputs xatrInputs; X121XSTRInputs xstrInputs; + X121XCHEInputs xcheInputs; X121XDONInputs xdonInputs; X121XVWAPInputs xvwapInputs; @@ -60,6 +62,7 @@ struct X121Inputs xpvInputs.Clean(); xatrInputs.Clean(); xstrInputs.Clean(); + xcheInputs.Clean(); xdonInputs.Clean(); xvwapInputs.Clean(); } @@ -73,6 +76,7 @@ struct X121Inputs xpvInputs.Default(); xatrInputs.Default(); xstrInputs.Default(); + xcheInputs.Default(); xdonInputs.Default(); xvwapInputs.Default(); } @@ -93,6 +97,7 @@ struct X121Inputs xpvInputs.IsValid() && xatrInputs.IsValid() && xstrInputs.IsValid() && + xcheInputs.IsValid() && xdonInputs.IsValid() && xvwapInputs.IsValid() // @@ -116,12 +121,14 @@ struct X121Inputs int xpvMax = xpvInputs.Max(); int xatrMax = xatrInputs.Max(); int xstrMax = xstrInputs.Max(); + int xcheMax = xcheInputs.Max(); int xdonMax = xdonInputs.Max(); int xvwapMax = xvwapInputs.Max(); // result = MathMax(xpvMax, xatrMax); result = MathMax(result, xstrMax); + result = MathMax(result, xcheMax); result = MathMax(result, xdonMax); result = MathMax(result, xvwapMax); @@ -142,27 +149,13 @@ struct X121Conditions // // Buffers ... - double atrUpperBuffer[]; - double atrLowerBuffer[]; - double atrUpperRawBuffer[]; - double atrLowerRawBuffer[]; double rsiBuffer[]; double atrBuffer[]; double strBuffer[]; - double strPriceBuffer[]; - double strUpBuffer[]; - double strDownBuffer[]; - double strStateBuffer[]; - double donOpenUpperBuffer[]; - double donOpenLowerBuffer[]; - double donHighUpperBuffer[]; - double donHighLowerBuffer[]; - double donLowUpperBuffer[]; - double donLowLowerBuffer[]; - double donCloseUpperBuffer[]; - double donCloseLowerBuffer[]; - double peaksBuffer[]; - double valesBuffer[]; + double le1Buffer[]; + double se1Buffer[]; + double le2Buffer[]; + double se2Buffer[]; double sarBuffer[]; double cHHBuffer[]; double cLLBuffer[]; @@ -174,18 +167,68 @@ struct X121Conditions double lLLBuffer[]; double hHHBuffer[]; double hLLBuffer[]; - double vwapFastBuffer[]; + double peaksBuffer[]; + double valesBuffer[]; + double strUpBuffer[]; + double strDownBuffer[]; double vwapMidBuffer[]; + double le1StartBuffer[]; + double se1StartBuffer[]; + double le2StartBuffer[]; + double se2StartBuffer[]; + double strPriceBuffer[]; + double atrUpperBuffer[]; + double atrLowerBuffer[]; + double strStateBuffer[]; + double vwapFastBuffer[]; double vwapSlowBuffer[]; - double vwapVolumeBuffer[]; double vwapPriceBuffer[]; - double vwapFastStateBuffer[]; + double vwapVolumeBuffer[]; + double atrUpperRawBuffer[]; + double atrLowerRawBuffer[]; + double donLowUpperBuffer[]; + double donLowLowerBuffer[]; double vwapMidStateBuffer[]; + double donOpenUpperBuffer[]; + double donOpenLowerBuffer[]; + double donHighUpperBuffer[]; + double donHighLowerBuffer[]; + double vwapFastStateBuffer[]; double vwapSlowStateBuffer[]; + double donCloseUpperBuffer[]; + double donCloseLowerBuffer[]; + + // + double rsiSlope; + double strSlope; + double atrUpperSlope; + double atrLowerSlope; + double vwapFastSlope; + double vwapMidSlope; + double vwapSlowSlope; // // Conditions ... + // + bool isRsiSlopeBullish; + bool isStrSlopeBullish; + bool isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish; + bool isStrSlopeBearish; + bool isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish; + + // bool isRsiOverBought; bool isRsiCrossedOverOverBought; bool isRsiCrossedUnderOverBought; @@ -262,17 +305,35 @@ struct X121Conditions bool isStrSwitchedToBearish; // - bool isVWapFastBullish; - bool isVWapFastBearish; - bool isVWapFastNeutural; + bool isCHE1Bullish; + bool isCHE1Bearish; + bool isCHE1SwitchedToBullish; + bool isCHE1SwitchedToBearish; + + // + bool isCHE2Bullish; + bool isCHE2Bearish; + bool isCHE2SwitchedToBullish; + bool isCHE2SwitchedToBearish; + + // + bool isCHEBullish; + bool isCHEBearish; + bool isCHESwitchedToBullish; + bool isCHESwitchedToBearish; + + // bool isVWapMidBullish; bool isVWapMidBearish; + bool isVWapFastBullish; + bool isVWapFastBearish; bool isVWapMidNeutural; bool isVWapSlowBullish; bool isVWapSlowBearish; - bool isVWapSlowNeutural; bool isVWapFastOverMid; bool isVWapMidOverSlow; + bool isVWapFastNeutural; + bool isVWapSlowNeutural; bool isVWapFastUnderMid; bool isVWapMidUnderSlow; bool isVWapBullishState; @@ -280,14 +341,60 @@ struct X121Conditions bool isVWapNeuturalState; bool isVWapBullishOrdered; bool isVWapBearishOrdered; - bool isVWapSwitchedToBullishOrdered; - bool isVWapSwitchedToBearishOrdered; bool isVWapSwitchedToBullishState; bool isVWapSwitchedToBearishState; bool isVWapSwitchedToNeuturalState; + bool isVWapSwitchedToBullishOrdered; + bool isVWapSwitchedToBearishOrdered; // // Complex Conditions ... + double vwapMin; + double vwapMax; + + // + bool isSarIncreased; + bool isSarDecreased; + + // + bool isVWapMinBreakedUp; + bool isVWapMaxBreakedUp; + + // + bool isVWapMinBreakedDown; + bool isVWapMaxBreakedDown; + + // + bool isClosedOverVWapMin; + bool isClosedUnderVWapMin; + + // + bool isClosedOverVWapMax; + bool isClosedUnderVWapMax; + + // + bool isVWapFastCrossedOverMid; + bool isVWapFastCrossedUnderMid; + + // + bool isVWapFastCrossedOverSlow; + bool isVWapFastCrossedUnderSlow; + + // + bool isBreakedUpPrevSar; + bool isBreakedDownPrevSar; + + // + bool isBreakedUpPrevStr; + bool isBreakedDownPrevStr; + + // + bool isBreakedUpPrevAtrUpper; + bool isBreakedDownPrevAtrUpper; + + // + bool isBreakedUpPrevAtrLower; + bool isBreakedDownPrevAtrLower; // bool isSarEqualsToPeak; @@ -365,6 +472,16 @@ struct X121Conditions bool isStrLowerCrossedOverDonLowLower; bool isStrLowerCrossedUnderDonLowLower; + // + bool isAtrUpperEqualsToPeak; + bool isAtrUpperCrossedUpPeak; + bool isAtrUpperCrossedDownPeak; + + // + bool isAtrLowerEqualsToVale; + bool isAtrLowerCrossedUpVale; + bool isAtrLowerCrossedDownVale; + // // Constructor ... X121Conditions() @@ -390,27 +507,13 @@ struct X121Conditions // Buffers ... // - Clean(atrUpperBuffer); - Clean(atrLowerBuffer); - Clean(atrUpperRawBuffer); - Clean(atrLowerRawBuffer); Clean(rsiBuffer); Clean(atrBuffer); Clean(strBuffer); - Clean(strPriceBuffer); - Clean(strUpBuffer); - Clean(strDownBuffer); - Clean(strStateBuffer); - Clean(donOpenUpperBuffer); - Clean(donOpenLowerBuffer); - Clean(donHighUpperBuffer); - Clean(donHighLowerBuffer); - Clean(donLowUpperBuffer); - Clean(donLowLowerBuffer); - Clean(donCloseUpperBuffer); - Clean(donCloseLowerBuffer); - Clean(peaksBuffer); - Clean(valesBuffer); + Clean(le1Buffer); + Clean(se1Buffer); + Clean(le2Buffer); + Clean(se2Buffer); Clean(sarBuffer); Clean(cHHBuffer); Clean(cLLBuffer); @@ -422,37 +525,45 @@ struct X121Conditions Clean(lLLBuffer); Clean(hHHBuffer); Clean(hLLBuffer); - Clean(vwapFastBuffer); + Clean(peaksBuffer); + Clean(valesBuffer); + Clean(strUpBuffer); + Clean(strDownBuffer); Clean(vwapMidBuffer); + Clean(le1StartBuffer); + Clean(se1StartBuffer); + Clean(le2StartBuffer); + Clean(se2StartBuffer); + Clean(strPriceBuffer); + Clean(atrUpperBuffer); + Clean(atrLowerBuffer); + Clean(strStateBuffer); + Clean(vwapFastBuffer); Clean(vwapSlowBuffer); - Clean(vwapVolumeBuffer); Clean(vwapPriceBuffer); - Clean(vwapFastStateBuffer); + Clean(vwapVolumeBuffer); + Clean(atrUpperRawBuffer); + Clean(atrLowerRawBuffer); + Clean(donLowUpperBuffer); + Clean(donLowLowerBuffer); Clean(vwapMidStateBuffer); + Clean(donOpenUpperBuffer); + Clean(donOpenLowerBuffer); + Clean(donHighUpperBuffer); + Clean(donHighLowerBuffer); + Clean(vwapFastStateBuffer); Clean(vwapSlowStateBuffer); + Clean(donCloseUpperBuffer); + Clean(donCloseLowerBuffer); // - ArraySetAsSeries(atrUpperBuffer, true); - ArraySetAsSeries(atrLowerBuffer, true); - ArraySetAsSeries(atrUpperRawBuffer, true); - ArraySetAsSeries(atrLowerRawBuffer, true); ArraySetAsSeries(rsiBuffer, true); ArraySetAsSeries(atrBuffer, true); ArraySetAsSeries(strBuffer, true); - ArraySetAsSeries(strPriceBuffer, true); - ArraySetAsSeries(strUpBuffer, true); - ArraySetAsSeries(strDownBuffer, true); - ArraySetAsSeries(strStateBuffer, true); - ArraySetAsSeries(donOpenUpperBuffer, true); - ArraySetAsSeries(donOpenLowerBuffer, true); - ArraySetAsSeries(donHighUpperBuffer, true); - ArraySetAsSeries(donHighLowerBuffer, true); - ArraySetAsSeries(donLowUpperBuffer, true); - ArraySetAsSeries(donLowLowerBuffer, true); - ArraySetAsSeries(donCloseUpperBuffer, true); - ArraySetAsSeries(donCloseLowerBuffer, true); - ArraySetAsSeries(peaksBuffer, true); - ArraySetAsSeries(valesBuffer, true); + ArraySetAsSeries(le1Buffer, true); + ArraySetAsSeries(se1Buffer, true); + ArraySetAsSeries(le2Buffer, true); + ArraySetAsSeries(se2Buffer, true); ArraySetAsSeries(sarBuffer, true); ArraySetAsSeries(cHHBuffer, true); ArraySetAsSeries(cLLBuffer, true); @@ -464,18 +575,73 @@ struct X121Conditions ArraySetAsSeries(lLLBuffer, true); ArraySetAsSeries(hHHBuffer, true); ArraySetAsSeries(hLLBuffer, true); - ArraySetAsSeries(vwapFastBuffer, true); + ArraySetAsSeries(peaksBuffer, true); + ArraySetAsSeries(valesBuffer, true); + ArraySetAsSeries(strUpBuffer, true); + ArraySetAsSeries(strDownBuffer, true); ArraySetAsSeries(vwapMidBuffer, true); + ArraySetAsSeries(le1StartBuffer, true); + ArraySetAsSeries(se1StartBuffer, true); + ArraySetAsSeries(le2StartBuffer, true); + ArraySetAsSeries(se2StartBuffer, true); + ArraySetAsSeries(strPriceBuffer, true); + ArraySetAsSeries(atrUpperBuffer, true); + ArraySetAsSeries(atrLowerBuffer, true); + ArraySetAsSeries(strStateBuffer, true); + ArraySetAsSeries(vwapFastBuffer, true); ArraySetAsSeries(vwapSlowBuffer, true); - ArraySetAsSeries(vwapVolumeBuffer, true); ArraySetAsSeries(vwapPriceBuffer, true); - ArraySetAsSeries(vwapFastStateBuffer, true); + ArraySetAsSeries(vwapVolumeBuffer, true); + ArraySetAsSeries(atrUpperRawBuffer, true); + ArraySetAsSeries(atrLowerRawBuffer, true); + ArraySetAsSeries(donLowUpperBuffer, true); + ArraySetAsSeries(donLowLowerBuffer, true); ArraySetAsSeries(vwapMidStateBuffer, true); + ArraySetAsSeries(donOpenUpperBuffer, true); + ArraySetAsSeries(donOpenLowerBuffer, true); + ArraySetAsSeries(donHighUpperBuffer, true); + ArraySetAsSeries(donHighLowerBuffer, true); + ArraySetAsSeries(vwapFastStateBuffer, true); ArraySetAsSeries(vwapSlowStateBuffer, true); + ArraySetAsSeries(donCloseUpperBuffer, true); + ArraySetAsSeries(donCloseLowerBuffer, true); + + // + vwapMin = 0; + vwapMax = 0; + + // + // Slopes ... + + rsiSlope = 0; + strSlope = 0; + atrUpperSlope = 0; + atrLowerSlope = 0; + vwapFastSlope = 0; + vwapMidSlope = 0; + vwapSlowSlope = 0; // // Conditions ... + // + isRsiSlopeBullish = false; + isStrSlopeBullish = false; + isAtrUpperSlopeBullish = false; + isAtrLowerSlopeBullish = false; + isVwapFastSlopeBullish = false; + isVwapMidSlopeBullish = false; + isVwapSlowSlopeBullish = false; + + // + isRsiSlopeBearish = false; + isStrSlopeBearish = false; + isAtrUpperSlopeBearish = false; + isAtrLowerSlopeBearish = false; + isVwapFastSlopeBearish = false; + isVwapMidSlopeBearish = false; + isVwapSlowSlopeBearish = false; + // // RSI ... @@ -622,9 +788,80 @@ struct X121Conditions isVWapSwitchedToBullishOrdered = false; isVWapSwitchedToBearishOrdered = false; + // + // CHE ... + + // + isCHE1Bullish = false; + isCHE1Bearish = false; + + // + isCHE1SwitchedToBullish = false; + isCHE1SwitchedToBearish = false; + + // + isCHE2Bullish = false; + isCHE2Bearish = false; + + // + isCHE2SwitchedToBullish = false; + isCHE2SwitchedToBearish = false; + + // + isCHEBullish = false; + isCHEBearish = false; + + // + isCHESwitchedToBullish = false; + isCHESwitchedToBearish = false; + // // Complex Conditions ... + // + isVWapMinBreakedUp = false; + isVWapMaxBreakedUp = false; + + // + isVWapMinBreakedDown = false; + isVWapMaxBreakedDown = false; + + // + isClosedOverVWapMin = false; + isClosedUnderVWapMin = false; + + // + isClosedOverVWapMax = false; + isClosedUnderVWapMax = false; + + // + isVWapFastCrossedOverMid = false; + isVWapFastCrossedUnderMid = false; + + // + isVWapFastCrossedOverSlow = false; + isVWapFastCrossedUnderSlow = false; + + // + isBreakedUpPrevSar = false; + isBreakedDownPrevSar = false; + + // + isBreakedUpPrevStr = false; + isBreakedDownPrevStr = false; + + // + isBreakedUpPrevAtrUpper = false; + isBreakedDownPrevAtrUpper = false; + + // + isBreakedUpPrevAtrLower = false; + isBreakedDownPrevAtrLower = false; + + // + isSarIncreased = false; + isSarDecreased = false; + // isSarEqualsToPeak = false; isSarEqualsToVale = false; @@ -661,6 +898,16 @@ struct X121Conditions isStrLowerOverVale = false; isStrLowerUnderVale = false; + // + isAtrUpperEqualsToPeak = false; + isAtrUpperCrossedUpPeak = false; + isAtrUpperCrossedDownPeak = false; + + // + isAtrLowerEqualsToVale = false; + isAtrLowerCrossedUpVale = false; + isAtrLowerCrossedDownVale = false; + // isStrLowerCrossedOverVale = false; isStrLowerCrossedUnderVale = false; @@ -869,46 +1116,108 @@ struct X121Conditions ToString("isVWapSwitchedToNeuturalState", isVWapSwitchedToNeuturalState, ignoreFalseConditions, separator) + // "-----------------------" + separator + + "CHE ..." + separator + + "-----------------------" + separator + + ToString("isCHE1Bullish", isCHE1Bullish, ignoreFalseConditions, separator) + + ToString("isCHE1Bearish", isCHE1Bearish, ignoreFalseConditions, separator) + + ToString("isCHE1SwitchedToBullish", isCHE1SwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCHE1SwitchedToBearish", isCHE1SwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCHE2Bullish", isCHE2Bullish, ignoreFalseConditions, separator) + + ToString("isCHE2Bearish", isCHE2Bearish, ignoreFalseConditions, separator) + + ToString("isCHE2SwitchedToBullish", isCHE2SwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCHE2SwitchedToBearish", isCHE2SwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCHEBullish", isCHEBullish, ignoreFalseConditions, separator) + + ToString("isCHEBearish", isCHEBearish, ignoreFalseConditions, separator) + + ToString("isCHESwitchedToBullish", isCHESwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCHESwitchedToBearish", isCHESwitchedToBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + + "Slopes ..." + separator + + "-----------------------" + separator + + ToString("isRsiSlopeBullish", isRsiSlopeBullish, ignoreFalseConditions, separator) + + ToString("isStrSlopeBullish", isStrSlopeBullish, ignoreFalseConditions, separator) + + ToString("isAtrUpperSlopeBullish", isAtrUpperSlopeBullish, ignoreFalseConditions, separator) + + ToString("isAtrLowerSlopeBullish", isAtrLowerSlopeBullish, ignoreFalseConditions, separator) + + ToString("isVwapFastSlopeBullish", isVwapFastSlopeBullish, ignoreFalseConditions, separator) + + ToString("isVwapMidSlopeBullish", isVwapMidSlopeBullish, ignoreFalseConditions, separator) + + ToString("isVwapSlowSlopeBullish", isVwapSlowSlopeBullish, ignoreFalseConditions, separator) + + ToString("isRsiSlopeBearish", isRsiSlopeBearish, ignoreFalseConditions, separator) + + ToString("isStrSlopeBearish", isStrSlopeBearish, ignoreFalseConditions, separator) + + ToString("isAtrUpperSlopeBearish", isAtrUpperSlopeBearish, ignoreFalseConditions, separator) + + ToString("isAtrLowerSlopeBearish", isAtrLowerSlopeBearish, ignoreFalseConditions, separator) + + ToString("isVwapFastSlopeBearish", isVwapFastSlopeBearish, ignoreFalseConditions, separator) + + ToString("isVwapMidSlopeBearish", isVwapMidSlopeBearish, ignoreFalseConditions, separator) + + ToString("isVwapSlowSlopeBearish", isVwapSlowSlopeBearish, ignoreFalseConditions, separator) + + // + "-----------------------" + separator + "Coplex ..." + separator + "-----------------------" + separator + + ToString("isSarIncreased", isSarIncreased, ignoreFalseConditions, separator) + + ToString("isSarDecreased", isSarDecreased, ignoreFalseConditions, separator) + ToString("isSarEqualsToPeak", isSarEqualsToPeak, ignoreFalseConditions, separator) + ToString("isSarEqualsToVale", isSarEqualsToVale, ignoreFalseConditions, separator) + - ToString("isSarCrossedUnderPeak", isSarCrossedUnderPeak, ignoreFalseConditions, separator) + - ToString("isSarCrossedOverVale", isSarCrossedOverVale, ignoreFalseConditions, separator) + ToString("isStrEqualsToPeak", isStrEqualsToPeak, ignoreFalseConditions, separator) + ToString("isStrEqualsToVale", isStrEqualsToVale, ignoreFalseConditions, separator) + - ToString("isStrCrossedUnderPeak", isStrCrossedUnderPeak, ignoreFalseConditions, separator) + - ToString("isStrCrossedOverVale", isStrCrossedOverVale, ignoreFalseConditions, separator) + ToString("isPeakOverAtrUpper", isPeakOverAtrUpper, ignoreFalseConditions, separator) + + ToString("isBreakedUpPrevSar", isBreakedUpPrevSar, ignoreFalseConditions, separator) + + ToString("isBreakedUpPrevStr", isBreakedUpPrevStr, ignoreFalseConditions, separator) + + ToString("isVWapMinBreakedUp", isVWapMinBreakedUp, ignoreFalseConditions, separator) + + ToString("isVWapMaxBreakedUp", isVWapMaxBreakedUp, ignoreFalseConditions, separator) + + ToString("isStrUpperOverPeak", isStrUpperOverPeak, ignoreFalseConditions, separator) + + ToString("isStrLowerOverVale", isStrLowerOverVale, ignoreFalseConditions, separator) + + ToString("isClosedOverVWapMin", isClosedOverVWapMin, ignoreFalseConditions, separator) + + ToString("isClosedOverVWapMax", isClosedOverVWapMax, ignoreFalseConditions, separator) + + ToString("isStrUpperUnderPeak", isStrUpperUnderPeak, ignoreFalseConditions, separator) + ToString("isValeUnderAtrLower", isValeUnderAtrLower, ignoreFalseConditions, separator) + + ToString("isStrLowerUnderVale", isStrLowerUnderVale, ignoreFalseConditions, separator) + + ToString("isVWapMinBreakedDown", isVWapMinBreakedDown, ignoreFalseConditions, separator) + + ToString("isVWapMaxBreakedDown", isVWapMaxBreakedDown, ignoreFalseConditions, separator) + + ToString("isClosedUnderVWapMin", isClosedUnderVWapMin, ignoreFalseConditions, separator) + + ToString("isClosedUnderVWapMax", isClosedUnderVWapMax, ignoreFalseConditions, separator) + + ToString("isBreakedDownPrevSar", isBreakedDownPrevSar, ignoreFalseConditions, separator) + + ToString("isBreakedDownPrevStr", isBreakedDownPrevStr, ignoreFalseConditions, separator) + + ToString("isSarCrossedOverVale", isSarCrossedOverVale, ignoreFalseConditions, separator) + + ToString("isStrCrossedOverVale", isStrCrossedOverVale, ignoreFalseConditions, separator) + + ToString("isSarCrossedUnderPeak", isSarCrossedUnderPeak, ignoreFalseConditions, separator) + + ToString("isStrCrossedUnderPeak", isStrCrossedUnderPeak, ignoreFalseConditions, separator) + ToString("isNewPeakOverAtrUpper", isNewPeakOverAtrUpper, ignoreFalseConditions, separator) + ToString("isNewValeUnderAtrLower", isNewValeUnderAtrLower, ignoreFalseConditions, separator) + - ToString("isStrUpperOverPeak", isStrUpperOverPeak, ignoreFalseConditions, separator) + - ToString("isStrUpperUnderPeak", isStrUpperUnderPeak, ignoreFalseConditions, separator) + + ToString("isStrUpperOverAtrUpper", isStrUpperOverAtrUpper, ignoreFalseConditions, separator) + + ToString("isStrLowerOverAtrLower", isStrLowerOverAtrLower, ignoreFalseConditions, separator) + + ToString("isAtrUpperEqualsToPeak", isAtrUpperEqualsToPeak, ignoreFalseConditions, separator) + + ToString("isAtrLowerEqualsToVale", isAtrLowerEqualsToVale, ignoreFalseConditions, separator) + + ToString("isAtrUpperCrossedUpPeak", isAtrUpperCrossedUpPeak, ignoreFalseConditions, separator) + + ToString("isAtrLowerCrossedUpVale", isAtrLowerCrossedUpVale, ignoreFalseConditions, separator) + + ToString("isStrUpperUnderAtrUpper", isStrUpperUnderAtrUpper, ignoreFalseConditions, separator) + + ToString("isStrLowerUnderAtrLower", isStrLowerUnderAtrLower, ignoreFalseConditions, separator) + + ToString("isBreakedUpPrevAtrUpper", isBreakedUpPrevAtrUpper, ignoreFalseConditions, separator) + + ToString("isBreakedUpPrevAtrLower", isBreakedUpPrevAtrLower, ignoreFalseConditions, separator) + + ToString("isVWapFastCrossedOverMid", isVWapFastCrossedOverMid, ignoreFalseConditions, separator) + + ToString("isAtrUpperCrossedDownPeak", isAtrUpperCrossedDownPeak, ignoreFalseConditions, separator) + + ToString("isAtrLowerCrossedDownVale", isAtrLowerCrossedDownVale, ignoreFalseConditions, separator) + + ToString("isBreakedDownPrevAtrUpper", isBreakedDownPrevAtrUpper, ignoreFalseConditions, separator) + + ToString("isBreakedDownPrevAtrLower", isBreakedDownPrevAtrLower, ignoreFalseConditions, separator) + + ToString("isVWapFastCrossedUnderMid", isVWapFastCrossedUnderMid, ignoreFalseConditions, separator) + + ToString("isVWapFastCrossedOverSlow", isVWapFastCrossedOverSlow, ignoreFalseConditions, separator) + ToString("isStrUpperCrossedOverPeak", isStrUpperCrossedOverPeak, ignoreFalseConditions, separator) + - ToString("isStrUpperCrossedUnderPeak", isStrUpperCrossedUnderPeak, ignoreFalseConditions, separator) + - ToString("isStrLowerOverVale", isStrLowerOverVale, ignoreFalseConditions, separator) + - ToString("isStrLowerUnderVale", isStrLowerUnderVale, ignoreFalseConditions, separator) + + ToString("isStrLowerOverDonLowLower", isStrLowerOverDonLowLower, ignoreFalseConditions, separator) + ToString("isStrLowerCrossedOverVale", isStrLowerCrossedOverVale, ignoreFalseConditions, separator) + + ToString("isDonLowLowerEqualsToVale", isDonLowLowerEqualsToVale, ignoreFalseConditions, separator) + + ToString("isVWapFastCrossedUnderSlow", isVWapFastCrossedUnderSlow, ignoreFalseConditions, separator) + + ToString("isStrUpperCrossedUnderPeak", isStrUpperCrossedUnderPeak, ignoreFalseConditions, separator) + ToString("isStrLowerCrossedUnderVale", isStrLowerCrossedUnderVale, ignoreFalseConditions, separator) + ToString("isDonHighUpperEqualsToPeak", isDonHighUpperEqualsToPeak, ignoreFalseConditions, separator) + - ToString("isDonLowLowerEqualsToVale", isDonLowLowerEqualsToVale, ignoreFalseConditions, separator) + - ToString("isStrUpperOverAtrUpper", isStrUpperOverAtrUpper, ignoreFalseConditions, separator) + - ToString("isStrUpperUnderAtrUpper", isStrUpperUnderAtrUpper, ignoreFalseConditions, separator) + - ToString("isStrLowerOverAtrLower", isStrLowerOverAtrLower, ignoreFalseConditions, separator) + - ToString("isStrLowerUnderAtrLower", isStrLowerUnderAtrLower, ignoreFalseConditions, separator) + - ToString("isStrUpperCrossedOverAtrUpper", isStrUpperCrossedOverAtrUpper, ignoreFalseConditions, separator) + - ToString("isStrUpperCrossedUnderAtrUpper", isStrUpperCrossedUnderAtrUpper, ignoreFalseConditions, separator) + - ToString("isStrLowerCrossedOverAtrLower", isStrLowerCrossedOverAtrLower, ignoreFalseConditions, separator) + - ToString("isStrLowerCrossedUnderAtrLower", isStrLowerCrossedUnderAtrLower, ignoreFalseConditions, separator) + ToString("isStrUpperOverDonHighUpper", isStrUpperOverDonHighUpper, ignoreFalseConditions, separator) + - ToString("isStrUpperUnderDonHighUpper", isStrUpperUnderDonHighUpper, ignoreFalseConditions, separator) + - ToString("isStrLowerOverDonLowLower", isStrLowerOverDonLowLower, ignoreFalseConditions, separator) + ToString("isStrLowerUnderDonLowLower", isStrLowerUnderDonLowLower, ignoreFalseConditions, separator) + - ToString("isStrUpperCrossedOverDonHighUpper", isStrUpperCrossedOverDonHighUpper, ignoreFalseConditions, separator) + - ToString("isStrUpperCrossedUnderDonHighUpper", isStrUpperCrossedUnderDonHighUpper, ignoreFalseConditions, separator) + + ToString("isStrUpperUnderDonHighUpper", isStrUpperUnderDonHighUpper, ignoreFalseConditions, separator) + + ToString("isStrUpperCrossedOverAtrUpper", isStrUpperCrossedOverAtrUpper, ignoreFalseConditions, separator) + + ToString("isStrLowerCrossedOverAtrLower", isStrLowerCrossedOverAtrLower, ignoreFalseConditions, separator) + + ToString("isStrUpperCrossedUnderAtrUpper", isStrUpperCrossedUnderAtrUpper, ignoreFalseConditions, separator) + + ToString("isStrLowerCrossedUnderAtrLower", isStrLowerCrossedUnderAtrLower, ignoreFalseConditions, separator) + ToString("isStrLowerCrossedOverDonLowLower", isStrLowerCrossedOverDonLowLower, ignoreFalseConditions, separator) + + ToString("isStrUpperCrossedOverDonHighUpper", isStrUpperCrossedOverDonHighUpper, ignoreFalseConditions, separator) + ToString("isStrLowerCrossedUnderDonLowLower", isStrLowerCrossedUnderDonLowLower, ignoreFalseConditions, separator) + + ToString("isStrUpperCrossedUnderDonHighUpper", isStrUpperCrossedUnderDonHighUpper, ignoreFalseConditions, separator) + // "" // @@ -962,6 +1271,7 @@ class XCX121Helper : public XCBase XCX121XPVHelper *xpvHelper; XCX121XATRHelper *xatrHelper; XCX121XSTRHelper *xstrHelper; + XCX121XCHEHelper *xcheHelper; XCX121XDONHelper *xdonHelper; XCX121XVWAPHelper *xvwapHelper; @@ -979,6 +1289,7 @@ class XCX121Helper : public XCBase delete xpvHelper; delete xatrHelper; delete xstrHelper; + delete xcheHelper; delete xdonHelper; delete xvwapHelper; } @@ -1038,6 +1349,7 @@ class XCX121Helper : public XCBase xpvInputs = inputs.xpvInputs; xatrInputs = inputs.xatrInputs; xstrInputs = inputs.xstrInputs; + xcheInputs = inputs.xcheInputs; xdonInputs = inputs.xdonInputs; xvwapInputs = inputs.xvwapInputs; @@ -1083,6 +1395,19 @@ class XCX121Helper : public XCBase return result; } + // + // XCHE ... + xcheHelper = new XCX121XCHEHelper(); + result = xcheHelper.Init( + symbol, + period, + xcheInputs // + ); + if (!result) + { + return result; + } + // // XDON ... xdonHelper = new XCX121XDONHelper(); @@ -1201,6 +1526,28 @@ class XCX121Helper : public XCBase return result; } + // + // XCHE ... + bool GetCHEConditions( + X121XCHEConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = false; + + // + result = xcheHelper.GetConditions( + conditions, + barIndex, + loopback // + ); + + // + return result; + } + // // XDON ... bool GetDONConditions( @@ -1350,6 +1697,19 @@ class XCX121Helper : public XCBase return result; } + // + // XCHE ... + X121XCHEConditions xcheConditions; + result = GetCHEConditions( + xcheConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + // // XDON ... X121XDONConditions xdonConditions; @@ -1380,6 +1740,10 @@ class XCX121Helper : public XCBase // Fill X121 Conditions Reference by Using // Retrieved Conditions ... + // + int cIDX = 1; + int pIDX = cIDX + 1; + // // XPV ... @@ -1589,6 +1953,76 @@ class XCX121Helper : public XCBase conditions.isStrSwitchedToBullish = xstrConditions.isStrSwitchedToBullish; conditions.isStrSwitchedToBearish = xstrConditions.isStrSwitchedToBearish; + // + // XCHE ... + + // + // Buffers ... + + // + Copy( + xcheConditions.le1Buffer, + conditions.le1Buffer // + ); + + // + Copy( + xcheConditions.se1Buffer, + conditions.se1Buffer // + ); + + // + Copy( + xcheConditions.le2Buffer, + conditions.le2Buffer // + ); + + // + Copy( + xcheConditions.se2Buffer, + conditions.se2Buffer // + ); + + // + Copy( + xcheConditions.le1StartBuffer, + conditions.le1StartBuffer // + ); + + // + Copy( + xcheConditions.se1StartBuffer, + conditions.se1StartBuffer // + ); + + // + Copy( + xcheConditions.le2StartBuffer, + conditions.le2StartBuffer // + ); + + // + Copy( + xcheConditions.se2StartBuffer, + conditions.se2StartBuffer // + ); + + // + // Conditions ... + + conditions.isCHEBullish = xcheConditions.isCHEBullish; + conditions.isCHEBearish = xcheConditions.isCHEBearish; + conditions.isCHE1Bullish = xcheConditions.isCHE1Bullish; + conditions.isCHE1Bearish = xcheConditions.isCHE1Bearish; + conditions.isCHE2Bullish = xcheConditions.isCHE2Bullish; + conditions.isCHE2Bearish = xcheConditions.isCHE2Bearish; + conditions.isCHESwitchedToBullish = xcheConditions.isCHESwitchedToBullish; + conditions.isCHESwitchedToBearish = xcheConditions.isCHESwitchedToBearish; + conditions.isCHE1SwitchedToBullish = xcheConditions.isCHE1SwitchedToBullish; + conditions.isCHE1SwitchedToBearish = xcheConditions.isCHE1SwitchedToBearish; + conditions.isCHE2SwitchedToBullish = xcheConditions.isCHE2SwitchedToBullish; + conditions.isCHE2SwitchedToBearish = xcheConditions.isCHE2SwitchedToBearish; + // // XDON ... @@ -1746,12 +2180,137 @@ class XCX121Helper : public XCBase conditions.isVWapSwitchedToBullishOrdered = xvwapConditions.isVWapSwitchedToBullishOrdered; conditions.isVWapSwitchedToBearishOrdered = xvwapConditions.isVWapSwitchedToBearishOrdered; + // + // Slopes ... + + // + double rsiSlope = GetSlope(conditions.rsiBuffer, pIDX, cIDX); + double strSlope = GetSlope(conditions.strBuffer, pIDX, cIDX); + double atrUpperSlope = GetSlope(conditions.atrUpperBuffer, pIDX, cIDX); + double atrLowerSlope = GetSlope(conditions.atrLowerBuffer, pIDX, cIDX); + double vwapFastSlope = GetSlope(conditions.vwapFastBuffer, pIDX, cIDX); + double vwapMidSlope = GetSlope(conditions.vwapMidBuffer, pIDX, cIDX); + double vwapSlowSlope = GetSlope(conditions.vwapSlowBuffer, pIDX, cIDX); + + // + bool isRsiSlopeBullish = rsiSlope > 0; + bool isStrSlopeBullish = strSlope > 0; + bool isAtrUpperSlopeBullish = atrUpperSlope > 0; + bool isAtrLowerSlopeBullish = atrLowerSlope > 0; + bool isVwapFastSlopeBullish = vwapFastSlope > 0; + bool isVwapMidSlopeBullish = vwapMidSlope > 0; + bool isVwapSlowSlopeBullish = vwapSlowSlope > 0; + + // + bool isRsiSlopeBearish = rsiSlope < 0; + bool isStrSlopeBearish = strSlope < 0; + bool isAtrUpperSlopeBearish = atrUpperSlope < 0; + bool isAtrLowerSlopeBearish = atrLowerSlope < 0; + bool isVwapFastSlopeBearish = vwapFastSlope < 0; + bool isVwapMidSlopeBearish = vwapMidSlope < 0; + bool isVwapSlowSlopeBearish = vwapSlowSlope < 0; + + // + conditions.rsiSlope = rsiSlope; + conditions.strSlope = strSlope; + conditions.vwapMidSlope = vwapMidSlope; + conditions.vwapSlowSlope = vwapSlowSlope; + conditions.atrUpperSlope = atrUpperSlope; + conditions.atrLowerSlope = atrLowerSlope; + conditions.vwapFastSlope = vwapFastSlope; + conditions.isRsiSlopeBearish = isRsiSlopeBearish; + conditions.isStrSlopeBearish = isStrSlopeBearish; + conditions.isRsiSlopeBullish = isRsiSlopeBullish; + conditions.isStrSlopeBullish = isStrSlopeBullish; + conditions.isVwapMidSlopeBearish = isVwapMidSlopeBearish; + conditions.isVwapMidSlopeBullish = isVwapMidSlopeBullish; + conditions.isAtrUpperSlopeBearish = isAtrUpperSlopeBearish; + conditions.isAtrLowerSlopeBearish = isAtrLowerSlopeBearish; + conditions.isVwapFastSlopeBearish = isVwapFastSlopeBearish; + conditions.isVwapSlowSlopeBearish = isVwapSlowSlopeBearish; + conditions.isAtrUpperSlopeBullish = isAtrUpperSlopeBullish; + conditions.isAtrLowerSlopeBullish = isAtrLowerSlopeBullish; + conditions.isVwapFastSlopeBullish = isVwapFastSlopeBullish; + conditions.isVwapSlowSlopeBullish = isVwapSlowSlopeBullish; + // // Complex Conditions ... // - int cIDX = 1; - int pIDX = cIDX + 1; + double vwapFast = conditions.vwapFastBuffer[cIDX]; + double vwapMid = conditions.vwapMidBuffer[cIDX]; + double vwapSlow = conditions.vwapSlowBuffer[cIDX]; + + // + double vwaps[3] = { + vwapFast, + vwapMid, + vwapSlow // + }; + + // + double vwapMin = GetMin(vwaps); + double vwapMax = GetMax(vwaps); + + // + bool isVWapMinBreakedUp = IsBarBreak( + vwapMin, + X_DIRECTION_BULLISH, + cBar // + ); + bool isVWapMinBreakedDown = IsBarBreak( + vwapMin, + X_DIRECTION_BEARISH, + cBar // + ); + + // + bool isVWapMaxBreakedUp = IsBarBreak( + vwapMax, + X_DIRECTION_BULLISH, + cBar // + ); + bool isVWapMaxBreakedDown = IsBarBreak( + vwapMax, + X_DIRECTION_BEARISH, + cBar // + ); + + // + bool isVWapFatsOverMid = conditions.vwapFastBuffer[cIDX] > conditions.vwapMidBuffer[cIDX]; + bool isVWapFatsOverMidPrev = conditions.vwapFastBuffer[pIDX] > conditions.vwapMidBuffer[pIDX]; + + // + bool isVWapFatsUnderMid = conditions.vwapFastBuffer[cIDX] < conditions.vwapMidBuffer[cIDX]; + bool isVWapFatsUnderMidPrev = conditions.vwapFastBuffer[pIDX] < conditions.vwapMidBuffer[pIDX]; + + // + bool isVWapFatsOverSlow = conditions.vwapFastBuffer[cIDX] > conditions.vwapSlowBuffer[cIDX]; + bool isVWapFatsOverSlowPrev = conditions.vwapFastBuffer[pIDX] > conditions.vwapSlowBuffer[pIDX]; + + // + bool isVWapFatsUnderSlow = conditions.vwapFastBuffer[cIDX] < conditions.vwapSlowBuffer[cIDX]; + bool isVWapFatsUnderSlowPrev = conditions.vwapFastBuffer[pIDX] < conditions.vwapSlowBuffer[pIDX]; + + // + bool isVWapFastCrossedOverMid = isVWapFatsOverMid && + !isVWapFatsOverMidPrev; + bool isVWapFastCrossedUnderMid = isVWapFatsUnderMid && + !isVWapFatsUnderMidPrev; + + // + bool isVWapFastCrossedOverSlow = isVWapFatsOverSlow && + !isVWapFatsOverSlowPrev; + bool isVWapFastCrossedUnderSlow = isVWapFatsUnderSlow && + !isVWapFatsUnderSlowPrev; + + // + bool isClosedOverVWapMin = cBar.close > vwapMin; + bool isClosedUnderVWapMin = cBar.close < vwapMin; + + // + bool isClosedOverVWapMax = cBar.close > vwapMax; + bool isClosedUnderVWapMax = cBar.close < vwapMax; // bool isSarEqualsToPeak = @@ -1759,6 +2318,64 @@ class XCX121Helper : public XCBase bool isSarEqualsToVale = conditions.sarBuffer[cIDX] == conditions.valesBuffer[cIDX]; + // + bool isSarIncreased = conditions.sarBuffer[cIDX] > conditions.sarBuffer[pIDX]; + bool isSarDecreased = conditions.sarBuffer[cIDX] < conditions.sarBuffer[pIDX]; + + // + double prevSar = conditions.sarBuffer[pIDX]; + double prevStr = conditions.strBuffer[pIDX]; + double prevAtrUpper = conditions.atrUpperBuffer[pIDX]; + double prevAtrLower = conditions.atrLowerBuffer[pIDX]; + + // + bool isBreakedUpPrevSar = IsBarBreak( + prevSar, + X_DIRECTION_BULLISH, + cBar // + ); + bool isBreakedDownPrevSar = IsBarBreak( + prevSar, + X_DIRECTION_BEARISH, + cBar // + ); + + // + bool isBreakedUpPrevStr = IsBarBreak( + prevStr, + X_DIRECTION_BULLISH, + cBar // + ); + bool isBreakedDownPrevStr = IsBarBreak( + prevStr, + X_DIRECTION_BEARISH, + cBar // + ); + + // + bool isBreakedUpPrevAtrUpper = IsBarBreak( + prevAtrUpper, + X_DIRECTION_BULLISH, + cBar // + ); + bool isBreakedDownPrevAtrUpper = IsBarBreak( + prevAtrUpper, + X_DIRECTION_BEARISH, + cBar // + ); + + // + bool isBreakedUpPrevAtrLower = IsBarBreak( + prevAtrLower, + X_DIRECTION_BULLISH, + cBar // + ); + bool isBreakedDownPrevAtrLower = IsBarBreak( + prevAtrLower, + X_DIRECTION_BEARISH, + cBar // + ); + // bool isSarCrossedUnderPeak = conditions.sarBuffer[cIDX] < conditions.peaksBuffer[cIDX] && @@ -1859,7 +2476,7 @@ class XCX121Helper : public XCBase bool isStrLowerOverAtrLowerPrev = conditions.strDownBuffer[pIDX] > conditions.atrLowerBuffer[pIDX]; bool isStrLowerCrossedOverAtrLower = isStrLowerOverAtrLower && - !isStrLowerOverAtrLowerPrev; + !isStrLowerOverAtrLowerPrev; // bool isStrLowerUnderAtrLower = @@ -1902,6 +2519,30 @@ class XCX121Helper : public XCBase !isStrLowerUnderDonLowLowerPrev; // + bool isAtrUpperEqualsToPeak = conditions.atrUpperBuffer[cIDX] == conditions.peaksBuffer[cIDX]; + + // + bool isAtrUpperCrossedUpPeak = conditions.atrUpperBuffer[cIDX] > conditions.peaksBuffer[cIDX] && + !(conditions.atrUpperBuffer[cIDX] > conditions.peaksBuffer[cIDX]); + bool isAtrUpperCrossedDownPeak = conditions.atrUpperBuffer[cIDX] < conditions.peaksBuffer[cIDX] && + !(conditions.atrUpperBuffer[cIDX] < conditions.peaksBuffer[cIDX]); + + // + bool isAtrLowerEqualsToVale = conditions.atrUpperBuffer[cIDX] == conditions.valesBuffer[cIDX]; + + // + bool isAtrLowerCrossedUpVale = conditions.atrUpperBuffer[cIDX] > conditions.valesBuffer[cIDX] && + !(conditions.atrUpperBuffer[cIDX] > conditions.valesBuffer[cIDX]); + bool isAtrLowerCrossedDownVale = conditions.atrUpperBuffer[cIDX] < conditions.valesBuffer[cIDX] && + !(conditions.atrUpperBuffer[cIDX] < conditions.valesBuffer[cIDX]); + + // + conditions.vwapMin = vwapMin; + conditions.vwapMax = vwapMax; + + // + conditions.isSarIncreased = isSarIncreased; + conditions.isSarDecreased = isSarDecreased; conditions.isSarEqualsToPeak = isSarEqualsToPeak; conditions.isSarEqualsToVale = isSarEqualsToVale; conditions.isStrEqualsToPeak = isStrEqualsToPeak; @@ -1909,23 +2550,49 @@ class XCX121Helper : public XCBase conditions.isStrUpperOverPeak = isStrUpperOverPeak; conditions.isPeakOverAtrUpper = isPeakOverAtrUpper; conditions.isStrLowerOverVale = isStrLowerOverVale; + conditions.isVWapMinBreakedUp = isVWapMinBreakedUp; + conditions.isVWapMaxBreakedUp = isVWapMaxBreakedUp; + conditions.isBreakedUpPrevSar = isBreakedUpPrevSar; + conditions.isBreakedUpPrevStr = isBreakedUpPrevStr; conditions.isStrLowerUnderVale = isStrLowerUnderVale; conditions.isStrUpperUnderPeak = isStrUpperUnderPeak; conditions.isValeUnderAtrLower = isValeUnderAtrLower; + conditions.isClosedOverVWapMin = isClosedOverVWapMin; + conditions.isClosedOverVWapMax = isClosedOverVWapMax; + conditions.isClosedUnderVWapMin = isClosedUnderVWapMin; + conditions.isClosedUnderVWapMax = isClosedUnderVWapMax; + conditions.isVWapMinBreakedDown = isVWapMinBreakedDown; + conditions.isVWapMaxBreakedDown = isVWapMaxBreakedDown; conditions.isSarCrossedOverVale = isSarCrossedOverVale; conditions.isStrCrossedOverVale = isStrCrossedOverVale; + conditions.isBreakedDownPrevStr = isBreakedDownPrevStr; + conditions.isBreakedDownPrevSar = isBreakedDownPrevSar; conditions.isSarCrossedUnderPeak = isSarCrossedUnderPeak; conditions.isStrCrossedUnderPeak = isStrCrossedUnderPeak; conditions.isNewPeakOverAtrUpper = isNewPeakOverAtrUpper; + conditions.isAtrUpperEqualsToPeak = isAtrUpperEqualsToPeak; + conditions.isAtrLowerEqualsToVale = isAtrLowerEqualsToVale; conditions.isNewValeUnderAtrLower = isNewValeUnderAtrLower; conditions.isStrUpperOverAtrUpper = isStrUpperOverAtrUpper; conditions.isStrLowerOverAtrLower = isStrLowerOverAtrLower; conditions.isStrUpperUnderAtrUpper = isStrUpperUnderAtrUpper; conditions.isStrLowerUnderAtrLower = isStrLowerUnderAtrLower; + conditions.isBreakedUpPrevAtrUpper = isBreakedUpPrevAtrUpper; + conditions.isBreakedUpPrevAtrLower = isBreakedUpPrevAtrLower; + conditions.isAtrUpperCrossedUpPeak = isAtrUpperCrossedUpPeak; + conditions.isAtrLowerCrossedUpVale = isAtrLowerCrossedUpVale; + conditions.isVWapFastCrossedOverMid = isVWapFastCrossedOverMid; + conditions.isAtrUpperCrossedDownPeak = isAtrUpperCrossedDownPeak; + conditions.isAtrLowerCrossedDownVale = isAtrLowerCrossedDownVale; + conditions.isBreakedDownPrevAtrUpper = isBreakedDownPrevAtrUpper; + conditions.isBreakedDownPrevAtrLower = isBreakedDownPrevAtrLower; + conditions.isVWapFastCrossedUnderMid = isVWapFastCrossedUnderMid; conditions.isDonLowLowerEqualsToVale = isDonLowLowerEqualsToVale; conditions.isStrUpperCrossedOverPeak = isStrUpperCrossedOverPeak; conditions.isStrLowerCrossedOverVale = isStrLowerCrossedOverVale; conditions.isStrLowerOverDonLowLower = isStrLowerOverDonLowLower; + conditions.isVWapFastCrossedOverSlow = isVWapFastCrossedOverSlow; + conditions.isVWapFastCrossedUnderSlow = isVWapFastCrossedUnderSlow; conditions.isStrUpperOverDonHighUpper = isStrUpperOverDonHighUpper; conditions.isStrLowerUnderDonLowLower = isStrLowerUnderDonLowLower; conditions.isDonHighUpperEqualsToPeak = isDonHighUpperEqualsToPeak; @@ -1964,6 +2631,7 @@ class XCX121Helper : public XCBase X121XATRInputs xatrInputs; X121XDONInputs xdonInputs; X121XSTRInputs xstrInputs; + X121XCHEInputs xcheInputs; X121XVWAPInputs xvwapInputs; // diff --git a/Helpers/x-saherelm.x121.xche.helper.mq5 b/Helpers/x-saherelm.x121.xche.helper.mq5 new file mode 100644 index 00000000..428d5a84 --- /dev/null +++ b/Helpers/x-saherelm.x121.xche.helper.mq5 @@ -0,0 +1,1235 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XCX121XCHEHelper +// 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 ... + +// +// Definitions ... +enum ENUM_X121_XCHE_BUFFERS +{ + // + X121_XCHE_LE_1_LINE = 0, + X121_XCHE_SE_1_LINE = 1, + X121_XCHE_LE_2_LINE = 2, + X121_XCHE_SE_2_LINE = 3, + X121_XCHE_LE_1_S_LINE = 4, + X121_XCHE_SE_1_S_LINE = 5, + X121_XCHE_LE_2_S_LINE = 6, + X121_XCHE_SE_2_S_LINE = 7, +}; + +// +// Input Models ... +struct X121XCHEInputs +{ + // + // Props ... + + int cheLength; // Length + int cheLoopback; // Loopback + double cheMultiplier1; // 1st Multiplier + double cheMultiplier2; // 2nd Multiplier + ENUM_APPLIED_PRICE cheUpperAppliedTo; // Upper Zone Applied to + ENUM_APPLIED_PRICE cheLowerAppliedTo; // Lower Zone Applied to + + // + int cheArrowCode; // CHE Arrow Code + + // + bool showLE1; // Show 1st Long Exit + bool showSE1; // Show 1st Short Exit + bool showLE2; // Show 2st Long Exit + bool showSE2; // Show 2st Short Exit + + // + // Constructor(s) ... + X121XCHEInputs() + { + // + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + // + cheLength = 0; + cheLoopback = 0; + cheMultiplier1 = 0; + cheMultiplier2 = 0; + cheUpperAppliedTo = PRICE_HIGH; + cheLowerAppliedTo = PRICE_LOW; + + // + cheArrowCode = 0; + + // + showLE1 = false; + showSE1 = false; + showLE2 = false; + showSE2 = false; + } + + // + // Default ... + void Default() + { + // + cheLength = 35; + cheLoopback = 26; + cheMultiplier1 = 3.0; + cheMultiplier2 = 3.5; + cheUpperAppliedTo = PRICE_HIGH; + cheLowerAppliedTo = PRICE_LOW; + + // + cheArrowCode = 159; + + // + showLE1 = true; + showSE1 = true; + showLE2 = true; + showSE2 = true; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = true; + + // + result = + cheLength >= 9 && + cheLoopback >= 0; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = MathMax(cheLength, cheLoopback); + + // + return result; + } +}; + +// +// Conditions ... +struct X121XCHEConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + double le1Buffer[]; + double se1Buffer[]; + double le2Buffer[]; + double se2Buffer[]; + double le1StartBuffer[]; + double se1StartBuffer[]; + double le2StartBuffer[]; + double se2StartBuffer[]; + + // + // Conditions ... + + // + bool isCHE1Bullish; + bool isCHE1Bearish; + + // + bool isCHE1SwitchedToBullish; + bool isCHE1SwitchedToBearish; + + // + bool isCHE2Bullish; + bool isCHE2Bearish; + + // + bool isCHE2SwitchedToBullish; + bool isCHE2SwitchedToBearish; + + // + bool isCHEBullish; + bool isCHEBearish; + + // + bool isCHESwitchedToBullish; + bool isCHESwitchedToBearish; + + // + // bool isCloseLower + + // + // Constructor ... + X121XCHEConditions() + { + Clean(); + } + + // + // Tools ... + + /** + * Cleaning Up ... + */ + void Clean() + { + // + // Commons ... + symbol = NULL; + period = NULL; + time = NULL; + + // + // Buffers ... + + // + Clean(le1Buffer); + Clean(se1Buffer); + Clean(le2Buffer); + Clean(se2Buffer); + Clean(le1StartBuffer); + Clean(se1StartBuffer); + Clean(le2StartBuffer); + Clean(se2StartBuffer); + + // + ArraySetAsSeries(le1Buffer, true); + ArraySetAsSeries(se1Buffer, true); + ArraySetAsSeries(le2Buffer, true); + ArraySetAsSeries(se2Buffer, true); + ArraySetAsSeries(le1StartBuffer, true); + ArraySetAsSeries(se1StartBuffer, true); + ArraySetAsSeries(le2StartBuffer, true); + ArraySetAsSeries(se2StartBuffer, true); + + // + // Conditions ... + + // + isCHE1Bullish = false; + isCHE1Bearish = false; + + // + isCHE1SwitchedToBullish = false; + isCHE1SwitchedToBearish = false; + + // + isCHE2Bullish = false; + isCHE2Bearish = false; + + // + isCHE2SwitchedToBullish = false; + isCHE2SwitchedToBearish = false; + + // + isCHEBullish = false; + isCHEBearish = false; + + // + isCHESwitchedToBullish = false; + isCHESwitchedToBearish = false; + + // + // XDON ... + } + + /** + * 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; + + // + // TODO: Implement if Required ... + } + + /** + * 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 = + // + ToString("isCHE1Bullish", isCHE1Bullish, ignoreFalseConditions, separator) + + ToString("isCHE1Bearish", isCHE1Bearish, ignoreFalseConditions, separator) + + ToString("isCHE1SwitchedToBullish", isCHE1SwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCHE1SwitchedToBearish", isCHE1SwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCHE2Bullish", isCHE2Bullish, ignoreFalseConditions, separator) + + ToString("isCHE2Bearish", isCHE2Bearish, ignoreFalseConditions, separator) + + ToString("isCHE2SwitchedToBullish", isCHE2SwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCHE2SwitchedToBearish", isCHE2SwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isCHEBullish", isCHEBullish, ignoreFalseConditions, separator) + + ToString("isCHEBearish", isCHEBearish, ignoreFalseConditions, separator) + + ToString("isCHESwitchedToBullish", isCHESwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isCHESwitchedToBearish", isCHESwitchedToBearish, 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 XCX121XCHEHelper : public XCBaseHelper +{ + // + // Public ... + public: + // + // Props ... + + // + // Constructors ... + XCX121XCHEHelper() + : XCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XCX121XCHEHelper() + { + } + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + X121XCHEInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + ArraySetAsSeries(le1Buffer, true); + ArraySetAsSeries(se1Buffer, true); + ArraySetAsSeries(le2Buffer, true); + ArraySetAsSeries(se2Buffer, true); + ArraySetAsSeries(le1StartBuffer, true); + ArraySetAsSeries(se1StartBuffer, true); + ArraySetAsSeries(le2StartBuffer, true); + ArraySetAsSeries(se2StartBuffer, true); + + // + mInputs = inputs; + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.x121.xche", + // + // Inputs ... + // + // Market ... + "", + mInputs.cheLength, + mInputs.cheLoopback, + mInputs.cheMultiplier1, + mInputs.cheMultiplier2, + mInputs.cheUpperAppliedTo, + mInputs.cheLowerAppliedTo, + // + // Presentation ... + "", + mInputs.cheArrowCode, + mInputs.showLE1, + mInputs.showSE1, + mInputs.showLE2, + mInputs.showSE2 + // + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + X121XCHEInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + X121XCHEInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs + // + ); + } + + // + // Readers ... + + // + double GetLE1( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(le1Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return le1Buffer[barIndex]; + } + + // + int CopyLE1( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + le1Buffer, + buffer, + forceClean + // + ); + } + + // + double GetLE1Start( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(le1StartBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return le1StartBuffer[barIndex]; + } + + // + int CopyLE1Start( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + le1StartBuffer, + buffer, + forceClean + // + ); + } + + // + double GetLE2( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(le2Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return le2Buffer[barIndex]; + } + + // + int CopyLE2( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + le2Buffer, + buffer, + forceClean + // + ); + } + + // + double GetLE2Start( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(le2StartBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return le2StartBuffer[barIndex]; + } + + // + int CopyLE2Start( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + le2StartBuffer, + buffer, + forceClean + // + ); + } + + // + double GetSE1( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(se1Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return se1Buffer[barIndex]; + } + + // + int CopySE1( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceCsean = true // Force To Csean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + se1Buffer, + buffer, + forceCsean + // + ); + } + + // + double GetSE1Start( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(se1StartBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return se1StartBuffer[barIndex]; + } + + // + int CopySE1Start( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceCsean = true // Force To Csean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + se1StartBuffer, + buffer, + forceCsean + // + ); + } + + // + double GetSE2( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(se2Buffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return se2Buffer[barIndex]; + } + + // + int CopySE2( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceCsean = true // Force To Csean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + se2Buffer, + buffer, + forceCsean + // + ); + } + + // + double GetSE2Start( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + int count = ArraySize(se2StartBuffer); + if (barIndex >= count) + { + barIndex = count - 1; + } + + // + return se2StartBuffer[barIndex]; + } + + // + int CopySE2Start( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceCsean = true // Force To Csean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + se2StartBuffer, + buffer, + forceCsean + // + ); + } + + // + bool GetConditions( + X121XCHEConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + if (loopback < 5) + { + loopback = 5; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + XOHCL zBar; + result = zBar.Init( + mSymbol, + mPeriod, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + mSymbol, + mPeriod, + pIndex // + ); + if (!result) + { + return result; + } + + // + // Buffers ... + + // + CopyLE1( + zIndex, + loopback, + conditions.le1Buffer // + ); + + // + CopySE1( + zIndex, + loopback, + conditions.se1Buffer // + ); + + // + CopyLE2( + zIndex, + loopback, + conditions.le2Buffer // + ); + + // + CopySE2( + zIndex, + loopback, + conditions.se2Buffer // + ); + + // + CopyLE1Start( + zIndex, + loopback, + conditions.le1StartBuffer // + ); + + // + CopySE1Start( + zIndex, + loopback, + conditions.se1StartBuffer // + ); + + // + CopyLE2Start( + zIndex, + loopback, + conditions.le2StartBuffer // + ); + + // + CopySE2Start( + zIndex, + loopback, + conditions.se2StartBuffer // + ); + + // + // Conditions ... + + // + int cIDX = 1; + int pIDX = cIDX + 1; + + // + bool isCHE1Bullish = le1Buffer[cIDX] != EMPTY_VALUE && + se1Buffer[cIDX] == EMPTY_VALUE; + bool isCHE1BullishPrev = le1Buffer[cIDX] != EMPTY_VALUE && + se1Buffer[pIDX] == EMPTY_VALUE; + + // + bool isCHE1Bearish = se1Buffer[cIDX] != EMPTY_VALUE && + le1Buffer[cIDX] == EMPTY_VALUE; + bool isCHE1BearishPrev = se1Buffer[pIDX] != EMPTY_VALUE && + le1Buffer[pIDX] == EMPTY_VALUE; + + // + bool isCHE1SwitchedToBullish = isCHE1Bullish && + !isCHE1BullishPrev; + bool isCHE1SwitchedToBearish = isCHE1Bearish && + !isCHE1BearishPrev; + + // + bool isCHE2Bullish = le2Buffer[cIDX] != EMPTY_VALUE && + se2Buffer[cIDX] == EMPTY_VALUE; + bool isCHE2BullishPrev = le2Buffer[pIDX] != EMPTY_VALUE && + se2Buffer[pIDX] == EMPTY_VALUE; + + // + bool isCHE2Bearish = se2Buffer[cIDX] != EMPTY_VALUE && + le2Buffer[cIDX] == EMPTY_VALUE; + bool isCHE2BearishPrev = se2Buffer[pIDX] != EMPTY_VALUE && + le2Buffer[pIDX] == EMPTY_VALUE; + + // + bool isCHE2SwitchedToBullish = isCHE2Bullish && + !isCHE2BullishPrev; + bool isCHE2SwitchedToBearish = isCHE2Bearish && + !isCHE2BearishPrev; + + // + bool isCHEBullish = isCHE1Bullish && + isCHE2Bullish; + bool isCHEBullishPrev = isCHE1BullishPrev && + isCHE2BullishPrev; + + // + bool isCHEBearish = isCHE1Bearish && + isCHE2Bearish; + bool isCHEBearishPrev = isCHE1BearishPrev && + isCHE2BearishPrev; + + // + bool isCHESwitchedToBullish = isCHEBullish && + !isCHEBullishPrev; + bool isCHESwitchedToBearish = isCHEBearish && + !isCHEBearishPrev; + + // + conditions.isCHE1Bullish = isCHE1Bullish; + conditions.isCHE1Bearish = isCHE1Bearish; + conditions.isCHE1SwitchedToBullish = isCHE1SwitchedToBullish; + conditions.isCHE1SwitchedToBearish = isCHE1SwitchedToBearish; + conditions.isCHE2Bullish = isCHE2Bullish; + conditions.isCHE2Bearish = isCHE2Bearish; + conditions.isCHE2SwitchedToBullish = isCHE2SwitchedToBullish; + conditions.isCHE2SwitchedToBearish = isCHE2SwitchedToBearish; + conditions.isCHEBullish = isCHEBullish; + conditions.isCHEBearish = isCHEBearish; + conditions.isCHESwitchedToBullish = isCHESwitchedToBullish; + conditions.isCHESwitchedToBearish = isCHESwitchedToBearish; + + // + return result; + } + + // + // Protected ... + protected: + // + // Private ... + private: + // + // Props ... + X121XCHEInputs mInputs; // Inputs ... + + // + // Buffers ... + double le1Buffer[]; + double se1Buffer[]; + double le2Buffer[]; + double se2Buffer[]; + double le1StartBuffer[]; + double se1StartBuffer[]; + double le2StartBuffer[]; + double se2StartBuffer[]; + + // + void Calculate() + { + // + int totalBars = CountBars(); + if (totalBars > 1000) + { + totalBars = 1000; + } + + // + // Buffers ... + + // + // LE1 Start ... + CopyBuffer( + mHandler, + X121_XCHE_LE_1_S_LINE, + 0, + totalBars, + le1StartBuffer // + ); + + // + // LE1 ... + CopyBuffer( + mHandler, + X121_XCHE_LE_1_LINE, + 0, + totalBars, + le1Buffer // + ); + + // + // LE2 Start ... + CopyBuffer( + mHandler, + X121_XCHE_LE_2_S_LINE, + 0, + totalBars, + le2StartBuffer // + ); + + // + // LE2 ... + CopyBuffer( + mHandler, + X121_XCHE_LE_2_LINE, + 0, + totalBars, + le2Buffer // + ); + + // + // SE1 Start ... + CopyBuffer( + mHandler, + X121_XCHE_SE_1_S_LINE, + 0, + totalBars, + se1StartBuffer // + ); + + // + // SE1 ... + CopyBuffer( + mHandler, + X121_XCHE_SE_1_LINE, + 0, + totalBars, + se1Buffer // + ); + + // + // SE2 Start ... + CopyBuffer( + mHandler, + X121_XCHE_SE_2_S_LINE, + 0, + totalBars, + se2StartBuffer // + ); + + // + // SE2 ... + CopyBuffer( + mHandler, + X121_XCHE_SE_2_LINE, + 0, + totalBars, + se2Buffer // + ); + } +}; + +// +// Tools ... \ No newline at end of file diff --git a/Helpers/x-saherelm.x121.xpv.helper.mq5 b/Helpers/x-saherelm.x121.xpv.helper.mq5 index b40bb770..135e7f67 100644 --- a/Helpers/x-saherelm.x121.xpv.helper.mq5 +++ b/Helpers/x-saherelm.x121.xpv.helper.mq5 @@ -521,7 +521,7 @@ class XCX121XPVHelper : public XCBaseHelper bool Init( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Period - X121XPVInputs &inputs // Inputs + X121XPVInputs &inputs // Inputs ) { // @@ -811,6 +811,7 @@ class XCX121XPVHelper : public XCBaseHelper // double GetHigherPeak( + int &index, // Bar Index double peak, // Peak Source int barIndex = 0, // Bar Index int loopback = 576 // Max Allowed Loopback @@ -819,6 +820,9 @@ class XCX121XPVHelper : public XCBaseHelper // double result = 0; + // + index = -1; + // if (barIndex < 0) { @@ -839,22 +843,23 @@ class XCX121XPVHelper : public XCBaseHelper // double iValue = 0; - int index = barIndex; + int sIndex = barIndex; bool canContinue = true; while (canContinue) { // - iValue = GetPeak(index); + iValue = GetPeak(sIndex); if (iValue > peak) { // + index = sIndex; result = iValue; break; } // - canContinue = index < barIndex + loopback; - index++; + canContinue = sIndex < barIndex + loopback; + sIndex++; } // @@ -863,6 +868,7 @@ class XCX121XPVHelper : public XCBaseHelper // double GetLowerPeak( + int &index, // Bar Index double peak, // Peak Source int barIndex = 0, // Bar Index int loopback = 576 // Max Allowed Loopback @@ -871,6 +877,9 @@ class XCX121XPVHelper : public XCBaseHelper // double result = 0; + // + index = -1; + // if (barIndex < 0) { @@ -891,22 +900,23 @@ class XCX121XPVHelper : public XCBaseHelper // double iValue = 0; - int index = barIndex; + int sIndex = barIndex; bool canContinue = true; while (canContinue) { // - iValue = GetPeak(index); + iValue = GetPeak(sIndex); if (iValue < peak) { // + index = sIndex; result = iValue; break; } // - canContinue = index < barIndex + loopback; - index++; + canContinue = sIndex < barIndex + loopback; + sIndex++; } // @@ -915,6 +925,7 @@ class XCX121XPVHelper : public XCBaseHelper // double GetHigherVale( + int &index, // Bar Index double vale, // Vale Source int barIndex = 0, // Bar Index int loopback = 576 // Max Allowed Loopback @@ -923,6 +934,9 @@ class XCX121XPVHelper : public XCBaseHelper // double result = 0; + // + index = -1; + // if (barIndex < 0) { @@ -943,22 +957,23 @@ class XCX121XPVHelper : public XCBaseHelper // double iValue = 0; - int index = barIndex; + int sIndex = barIndex; bool canContinue = true; while (canContinue) { // - iValue = GetVale(index); + iValue = GetVale(sIndex); if (iValue > vale) { // + index = sIndex; result = iValue; break; } // - canContinue = index < barIndex + loopback; - index++; + canContinue = sIndex < barIndex + loopback; + sIndex++; } // @@ -967,6 +982,7 @@ class XCX121XPVHelper : public XCBaseHelper // double GetLowerVale( + int &index, // Bar Index double vale, // Vale Source int barIndex = 0, // Bar Index int loopback = 576 // Max Allowed Loopback @@ -975,6 +991,9 @@ class XCX121XPVHelper : public XCBaseHelper // double result = 0; + // + index = -1; + // if (barIndex < 0) { @@ -995,22 +1014,23 @@ class XCX121XPVHelper : public XCBaseHelper // double iValue = 0; - int index = barIndex; + int sIndex = barIndex; bool canContinue = true; while (canContinue) { // - iValue = GetVale(index); + iValue = GetVale(sIndex); if (iValue < vale) { // + index = sIndex; result = iValue; break; } // - canContinue = index < barIndex + loopback; - index++; + canContinue = sIndex < barIndex + loopback; + sIndex++; } // @@ -1778,8 +1798,8 @@ class XCX121XPVHelper : public XCBaseHelper // bool GetConditions( X121XPVConditions &conditions, // - int barIndex = 0, // - int loopback = 5 // + int barIndex = 0, // + int loopback = 5 // ) { // @@ -1949,7 +1969,6 @@ class XCX121XPVHelper : public XCBaseHelper bool isSarBullish = conditions.sarBuffer[cIDX] < cBar.low; bool isSarBullishPrev = conditions.sarBuffer[pIDX] < pBar.low; - // bool isSarBearish = conditions.sarBuffer[cIDX] > cBar.high; bool isSarBearishPrev = conditions.sarBuffer[pIDX] > pBar.high; @@ -2028,7 +2047,7 @@ class XCX121XPVHelper : public XCBaseHelper { totalBars = 1000; } - + // // Buffers ... diff --git a/Indicators/x-saherelm.x121.xatr.mq5 b/Indicators/x-saherelm.x121.xatr.mq5 index a506624b..d44a578d 100644 --- a/Indicators/x-saherelm.x121.xatr.mq5 +++ b/Indicators/x-saherelm.x121.xatr.mq5 @@ -27,8 +27,6 @@ // // Includes Common Library ... -#include "../Classes/x-saherelm.x-poi.class.mq5" -#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // diff --git a/Indicators/x-saherelm.x121.xche.mq5 b/Indicators/x-saherelm.x121.xche.mq5 new file mode 100644 index 00000000..d8ed1040 --- /dev/null +++ b/Indicators/x-saherelm.x121.xche.mq5 @@ -0,0 +1,624 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: X121 XCHE +// Description: XCHE ... +// +// +// 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 XCHE Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "X121 XCHE" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +// Market ... +input group "Market"; +input int cheLength = 35; // Length +input int cheLoopback = 26; // Loopback +input double cheMultiplier1 = 3.0; // 1st Multiplier +input double cheMultiplier2 = 3.5; // 2nd Multiplier +input ENUM_APPLIED_PRICE cheUpperAppliedTo = PRICE_HIGH; // Upper Zone Applied to +input ENUM_APPLIED_PRICE cheLowerAppliedTo = PRICE_LOW; // Lower Zone Applied to + +// +input group "Presentation"; + +// +input int cheArrowCode = 159; // CHE Arrow Code + +// +input bool showLE1 = true; // Show 1st Long Exit +input bool showSE1 = true; // Show 1st Short Exit +input bool showLE2 = true; // Show 2st Long Exit +input bool showSE2 = true; // Show 2st Short Exit + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 +#define neuturalColorIDX 3 + +// +#property indicator_chart_window + +// +#property indicator_buffers 8 +#property indicator_plots 8 + +// +// Exit 1 ... + +// +// LONG ... + +// +#define le1BufferIndex 0 +double le1Buffer[]; + +#property indicator_label1 "X121 LE1" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// SHORT ... + +// +#define se1BufferIndex 1 +double se1Buffer[]; + +#property indicator_label2 "X121 SE1" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrMagenta +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Exit 2 ... + +// +// LONG ... + +// +#define le2BufferIndex 2 +double le2Buffer[]; + +#property indicator_label3 "X121 LE2" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAqua +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +// SHORT ... + +// +#define se2BufferIndex 3 +double se2Buffer[]; + +#property indicator_label4 "X121 SE2" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +// Start Buffers ... + +// +#define le1StartBufferIndex 4 +double le1StartBuffer[]; + +// +#property indicator_label5 "X121 LE1 S" +#property indicator_type5 DRAW_ARROW +#property indicator_color5 clrLime + +// +#define se1StartBufferIndex 5 +double se1StartBuffer[]; + +// +#property indicator_label6 "X121 SE1 S" +#property indicator_type6 DRAW_ARROW +#property indicator_color6 clrRed + +// +#define le2StartBufferIndex 6 +double le2StartBuffer[]; + +// +#property indicator_label7 "X121 LE2 S" +#property indicator_type7 DRAW_ARROW +#property indicator_color7 clrLime + +// +#define se2StartBufferIndex 7 +double se2StartBuffer[]; + +// +#property indicator_label8 "X121 SE2 S" +#property indicator_type8 DRAW_ARROW +#property indicator_color8 clrRed + +// +// Variables, Properties and etc ... + +// +// this counts Available Bars ... +int limit; + +// +int maxLength; + +// +// Working Array ... +double work[][6]; +#define hi1Idx 0 +#define lo1Idx 1 +#define hi2Idx 2 +#define lo2Idx 3 +#define trend1Idx 4 +#define trend2Idx 5 + +// +// Event Handlers ... + +/** + * Initialize Indicator ... + * + * @return ( int ) + */ +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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 cheLength, here we get max Input cheLength + // 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 +} + +/** + * 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[] // +) +{ + // + if (Bars(_Symbol, _Period) < rates_total) + { + return (prev_calculated); + } + + // + if (ArrayRange(work, 0) != rates_total) + { + ArrayResize(work, rates_total); + } + + // + // this counts Available Bars ... + + // + limit = prev_calculated - 1; + if (limit < 0) + { + limit = 0; + } + + // + // Main Loop ... + for (int i = limit; i < rates_total && !IsStopped(); i++) + { + CalculateBuffers( + i, + prev_calculated, + rates_total, + // + open, + high, + low, + close); + } + + // + return rates_total; +} + +// +// Functions ... + +/** + * Validate Input Args for Initialization ... + * + * @return ( bool ) + */ +bool ValidateInputs() +{ + // + bool result = true; + + // + result = + cheLength >= 9 && + cheLoopback >= 0; + + // + return result; +} + +/** + * Extract Max Length of Inputs ... + * + * @return ( int ) + */ +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(cheLength, cheLoopback); + + // + return result; +} + +/** + * Define Required Buffers ... + */ +void DefineBuffers() +{ + // + // LEVEL 1 ... + + // + // Long Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE le1DrawType = showLE1 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE le1StartDrawType = showLE1 ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(le1BufferIndex, le1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(le1BufferIndex, PLOT_SHOW_DATA, showLE1); + PlotIndexSetInteger(le1BufferIndex, PLOT_DRAW_TYPE, le1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(le1StartBufferIndex, le1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(le1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(le1StartBufferIndex, PLOT_DRAW_TYPE, le1StartDrawType); + PlotIndexSetInteger(le1StartBufferIndex, PLOT_ARROW, cheArrowCode); + + // + // Short Exit 1 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE se1DrawType = showSE1 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE se1StartDrawType = showSE1 ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(se1BufferIndex, se1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(se1BufferIndex, PLOT_SHOW_DATA, showSE1); + PlotIndexSetInteger(se1BufferIndex, PLOT_DRAW_TYPE, se1DrawType); + + // + // Start Buffer ... + SetIndexBuffer(se1StartBufferIndex, se1StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(se1StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(se1StartBufferIndex, PLOT_DRAW_TYPE, se1StartDrawType); + PlotIndexSetInteger(se1StartBufferIndex, PLOT_ARROW, cheArrowCode); + + // + // LEVEL 2 ... + + // + // Long Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE le2DrawType = showLE2 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE le2StartDrawType = showLE2 ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(le2BufferIndex, le2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(le2BufferIndex, PLOT_SHOW_DATA, showLE2); + PlotIndexSetInteger(le2BufferIndex, PLOT_DRAW_TYPE, le2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(le2StartBufferIndex, le2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(le2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(le2StartBufferIndex, PLOT_DRAW_TYPE, le2StartDrawType); + PlotIndexSetInteger(le2StartBufferIndex, PLOT_ARROW, cheArrowCode); + + // + // Short Exit 2 ... + + // + // Draw Type ... + ENUM_DRAW_TYPE se2DrawType = showSE2 ? DRAW_LINE : DRAW_NONE; + ENUM_DRAW_TYPE se2StartDrawType = showSE2 ? DRAW_ARROW : DRAW_NONE; + + // + // Buffer ... + SetIndexBuffer(se2BufferIndex, se2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(se2BufferIndex, PLOT_SHOW_DATA, showSE2); + PlotIndexSetInteger(se2BufferIndex, PLOT_DRAW_TYPE, se2DrawType); + + // + // Start Buffer ... + SetIndexBuffer(se2StartBufferIndex, se2StartBuffer, INDICATOR_DATA); + PlotIndexSetInteger(se2StartBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(se2StartBufferIndex, PLOT_DRAW_TYPE, se2StartDrawType); + PlotIndexSetInteger(se2StartBufferIndex, PLOT_ARROW, cheArrowCode); +} + +/** + * Set Indicator Short Name and also we can define Buffers Labels ... + */ +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +/** + * Calculate Buffers ... + */ +void CalculateBuffers( + int bar_index, // Selected Bar Index + int prevCalculated, // Previous Calculated + int ratesTotal, // Total Rates + const double &open[], // Rates Open ... + const double &high[], // Rates High ... + const double &low[], // Rates Low ... + const double &close[] // Rates Close ... +) +{ + // + // Cleanup Buffers ... + le1Buffer[bar_index] = le1StartBuffer[bar_index] = se1Buffer[bar_index] = se1StartBuffer[bar_index] = EMPTY_VALUE; + le2Buffer[bar_index] = le2StartBuffer[bar_index] = se2Buffer[bar_index] = se2StartBuffer[bar_index] = EMPTY_VALUE; + + // + int start = MathMax(bar_index - cheLoopback, 0); + + // + // Calculate ATR Value ... + double atrValue = 0; + for (int k = 1; k <= cheLength && (bar_index - k - 1) >= 0; k++) + { + // + atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) - + MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]); + } + atrValue /= (double)cheLength; + + // + // Retrieve Highest High and Lowest Lows ... + double cheLoopbackMax = high[ArrayMaximum(high, start, cheLoopback)]; + double cheLoopbackMin = low[ArrayMinimum(low, start, cheLoopback)]; + + // + // Fill Multi Dimesional Working Array ... + work[bar_index][hi1Idx] = cheLoopbackMax - cheMultiplier1 * atrValue; + work[bar_index][lo1Idx] = cheLoopbackMin + cheMultiplier1 * atrValue; + work[bar_index][hi2Idx] = cheLoopbackMax - cheMultiplier2 * atrValue; + work[bar_index][lo2Idx] = cheLoopbackMin + cheMultiplier2 * atrValue; + work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0; + work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0; + + // + if (bar_index > 0) + { + // + // Calculate Trends ... + if (close[bar_index] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][trend1Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][trend1Idx] = -1; + } + + // + if (close[bar_index] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][trend2Idx] = 1; + } + + // + if (close[bar_index] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][trend2Idx] = -1; + } + + // + // Calculate Exit Values ... + + // + // Exit 1 ... + + // + // Long ... + if (cheMultiplier1 > 0 && work[bar_index][trend1Idx] == 1) + { + // + if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx]) + { + work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx]; + } + + // + le1Buffer[bar_index] = work[bar_index][hi1Idx]; + + // + if (le1Buffer[bar_index - 1] == EMPTY_VALUE) + { + le1StartBuffer[bar_index] = le1Buffer[bar_index]; + } + } + + // + // Short ... + if (cheMultiplier1 > 0 && work[bar_index][trend1Idx] == -1) + { + // + if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx]) + { + work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx]; + } + + // + se1Buffer[bar_index] = work[bar_index][lo1Idx]; + + // + if (se1Buffer[bar_index - 1] == EMPTY_VALUE) + { + se1StartBuffer[bar_index] = se1Buffer[bar_index]; + } + } + + // + // Exit 2 ... + + // + // Long ... + if (cheMultiplier2 > 0 && work[bar_index][trend2Idx] == 1) + { + if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx]) + { + work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx]; + } + + // + le2Buffer[bar_index] = work[bar_index][hi2Idx]; + + // + if (le2Buffer[bar_index - 1] == EMPTY_VALUE) + { + le2StartBuffer[bar_index] = le2Buffer[bar_index]; + } + } + + // + // Short ... + if (cheMultiplier2 > 0 && work[bar_index][trend2Idx] == -1) + { + // + if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx]) + { + work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx]; + } + + // + se2Buffer[bar_index] = work[bar_index][lo2Idx]; + + // + if (se2Buffer[bar_index - 1] == EMPTY_VALUE) + { + se2StartBuffer[bar_index] = se2Buffer[bar_index]; + } + } + } +} + +// \ No newline at end of file diff --git a/Indicators/x-saherelm.x121.xstr.mq5 b/Indicators/x-saherelm.x121.xstr.mq5 index 96d8f695..cccce4fb 100644 --- a/Indicators/x-saherelm.x121.xstr.mq5 +++ b/Indicators/x-saherelm.x121.xstr.mq5 @@ -27,8 +27,6 @@ // // Includes Common Library ... -#include "../Classes/x-saherelm.x-poi.class.mq5" -#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index e35da6de..aef40602 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -6139,14 +6139,26 @@ bool IsUnder( // // Check if a Value Increasing in Loopback ... bool IsIncreasing( - const int from, // Last Time Index - const int to, // Fisrs Tima Index - const double &buffer[] // the Buffer which required to search + const double &buffer[], // the Buffer which required to search + int from = -1, // Last Time Index + int to = -1 // Fisrs Tima Index ) { // bool result = false; + // + if (from == -1) + { + from = ArraySize(buffer) - 1; + } + + // + if (to == -1) + { + to = 0; + } + // // Validate Args ... if ( @@ -6160,7 +6172,7 @@ bool IsIncreasing( // Loop through Items ... double toValue = buffer[to]; double fromValue = buffer[from]; - result = toValue > fromValue; + result = toValue >= fromValue; for (int i = to + 1; i <= from - 1; i++) { // @@ -6169,9 +6181,10 @@ bool IsIncreasing( // bool isIIncreasing = IsIncreasing( + buffer, from, - i, - buffer); + i // + ); // // Check Result ... @@ -6189,14 +6202,26 @@ bool IsIncreasing( // // Check if a Value Decreasing in Loopback ... bool IsDecreasing( - const int from, // Last Time Index - const int to, // Fisr Tima Index - const double &buffer[] // the Buffer which required to search + const double &buffer[], // the Buffer which required to search + int from = -1, // Last Time Index + int to = -1 // Fisrs Tima Index ) { // bool result = false; + // + if (from == -1) + { + from = ArraySize(buffer) - 1; + } + + // + if (to == -1) + { + to = 0; + } + // // Validate Args ... if ( @@ -6210,7 +6235,7 @@ bool IsDecreasing( // Loop through Items ... double toValue = buffer[to]; double fromValue = buffer[from]; - result = toValue < fromValue; + result = toValue <= fromValue; for (int i = to + 1; i <= from - 1; i++) { // @@ -6219,9 +6244,10 @@ bool IsDecreasing( // bool isIDecreasing = IsDecreasing( + buffer, from, - i, - buffer); + i // + ); // // Check Result ... diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index 94dcb39b..d55e6fd3 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -128,7 +128,8 @@ class XC121SMCCycleHelper : public XCBase bool result = false; // - if (requiredPOIS < 10) { + if (requiredPOIS < 10) + { requiredPOIS = 10; } @@ -882,6 +883,199 @@ class XC121SMCCycleHelper : public XCBase return result; } + /** + * Detect Market Structure Method 2 ... + * + * @param model: XMarketStructure instance Reference ... + * + * @return ( bool ) + */ + bool DetectMarketStructure( + ENUM_X_DIRECTION &dir, + int pivotsCount = 3 // + ) + { + // + bool result = false; + + // + int barIndex = 0; + + // + if (pivotsCount < 3) + { + pivotsCount = 3; + } + + // + dir = X_DIRECTION_NONE; + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int hpIndex = -1; + int hpIndexes[]; + double hpValues[]; + + // + int lvIndex = -1; + int lvIndexes[]; + double lvValues[]; + + // + for (int i = 0; i < pivotsCount; i++) + { + // + hpIndex = barIndex; + lvIndex = barIndex; + + // + double lastHP = 0; + double lastLV = 0; + + // + int hpCount = ArraySize(hpIndexes); + int lvCount = ArraySize(lvIndexes); + + // + if (IsValidSize(hpCount)) + { + // + lastHP = hpValues[hpCount - 1]; + hpIndex = hpIndexes[hpCount - 1]; + } + + // + if (IsValidSize(lvCount)) + { + // + lastLV = lvValues[lvCount - 1]; + lvIndex = lvIndexes[lvCount - 1]; + } + + // + if (lastHP == 0) + { + // + lastHP = mX121Helper + .xpvHelper + .GetPeak(hpIndex); + } + + // + if (lastLV == 0) + { + // + lastLV = mX121Helper + .xpvHelper + .GetVale(lvIndex); + } + + // + int highestPeakIndex = -1; + double highesrPeak = + mX121Helper + .xpvHelper + .GetHigherPeak( + highestPeakIndex, + lastHP, + hpIndex // + ); + if (IsValidIndex(highestPeakIndex)) + { + // + Add( + highestPeakIndex, + hpIndexes // + ); + + // + Add( + highesrPeak, + hpValues // + ); + } + + // + int lowestValeIndex = -1; + double lowestVale = + mX121Helper + .xpvHelper + .GetLowerVale( + lowestValeIndex, + lastLV, + lvIndex // + ); + if (IsValidIndex(lowestValeIndex)) + { + // + Add( + lowestValeIndex, + lvIndexes // + ); + + // + Add( + lowestVale, + lvValues // + ); + } + + // + bool canBreak = ArraySize(hpIndexes) >= pivotsCount || + ArraySize(lvIndexes) >= pivotsCount; + if (canBreak) + { + break; + } + } + + // + ArrayReverse(hpValues); + ArrayReverse(hpIndexes); + int countHPs = ArraySize(hpIndexes); + + // + ArrayReverse(lvValues); + ArrayReverse(lvIndexes); + int countLVs = ArraySize(lvIndexes); + + // + bool isValidHPs = countHPs >= pivotsCount; + bool isValidLVs = countLVs >= pivotsCount; + + // + result = isValidHPs || + isValidLVs; + if (!result) + { + return result; + } + + // + if (isValidHPs && isValidLVs) + { + // + hpIndex = hpIndexes[countHPs - 1]; + lvIndex = lvIndexes[countLVs - 1]; + } + + // + dir = + !isValidHPs && isValidLVs + ? X_DIRECTION_BULLISH + : !isValidLVs && isValidHPs + ? X_DIRECTION_BEARISH + : hpIndex < lvIndex + ? X_DIRECTION_BEARISH + : lvIndex < hpIndex + ? X_DIRECTION_BULLISH + : X_DIRECTION_ALL; + + // + return result; + } + // // Tools ... diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 58fddb57..15e9b306 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -38,6 +38,7 @@ const string X121SMCStrategyToken = "X121SMC"; const string X121SMCXTestToken = "X121XTest"; const string X121SMCXOBGPVToken = "X121XOBGPV"; const string X121SMCXOBSPVToken = "X121XOBSPV"; +const string X121SMCXSTRPVToken = "X121XSTRPV"; // // X121 SMC Providers ... @@ -48,6 +49,7 @@ enum ENUM_X_121_SMC_PROVIDERS X_121_SMC_PROVIDER_XTEST, X_121_SMC_PROVIDER_XOBGPV, X_121_SMC_PROVIDER_XOBSPV, + X_121_SMC_PROVIDER_XSTRPV, }; // @@ -684,6 +686,11 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) case X_121_SMC_PROVIDER_XOBSPV: result = X121SMCXOBSPVToken; break; + + // + case X_121_SMC_PROVIDER_XSTRPV: + result = X121SMCXSTRPVToken; + break; } // @@ -721,6 +728,10 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) { result = X_121_SMC_PROVIDER_XOBSPV; } + else if (Contains(X121SMCXSTRPVToken, value)) + { + result = X_121_SMC_PROVIDER_XSTRPV; + } // return result; diff --git a/X121SMCEA/Signals/x-121.smc.xobgpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xobgpv.signal.lib.mq5 index 5f501653..bc3329e7 100644 --- a/X121SMCEA/Signals/x-121.smc.xobgpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xobgpv.signal.lib.mq5 @@ -816,7 +816,11 @@ bool DetectX121SMCXOBGPVSiganlTrigger( if (isBullish) { // - double lowerVale = triggerCycleHelper.mX121Helper.xpvHelper.GetLowerVale(vale); + int idx = -1; + double lowerVale = triggerCycleHelper.mX121Helper.xpvHelper.GetLowerVale( + idx, + vale // + ); if (lowerVale > 0) { // @@ -835,7 +839,11 @@ bool DetectX121SMCXOBGPVSiganlTrigger( else if (isBearish) { // - double higherPeak = triggerCycleHelper.mX121Helper.xpvHelper.GetHigherPeak(peak); + int idx = -1; + double higherPeak = triggerCycleHelper.mX121Helper.xpvHelper.GetHigherPeak( + idx, + peak // + ); if (higherPeak > 0) { // diff --git a/X121SMCEA/Signals/x-121.smc.xobspv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xobspv.signal.lib.mq5 index da75d5bd..18316cd3 100644 --- a/X121SMCEA/Signals/x-121.smc.xobspv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xobspv.signal.lib.mq5 @@ -881,6 +881,7 @@ bool DetectX121SMCXOBSPVSiganlTrigger( isBullish = // isBullish && + cBar.IsBullish() && isDecisionLastBearishStrBreakedUp // ; @@ -890,6 +891,7 @@ bool DetectX121SMCXOBSPVSiganlTrigger( isBearish = // isBearish && + cBar.IsBearish() && isDecisionLastBullishStrBreakedDown // ; @@ -953,15 +955,19 @@ bool DetectX121SMCXOBSPVSiganlTrigger( double sls[]; // - double iAtr = triggerConditions.x121Conditions.atrBuffer[1]; - double iPeak = triggerConditions.x121Conditions.peaksBuffer[1]; - double iVale = triggerConditions.x121Conditions.valesBuffer[1]; + double iAtr = decisionConditions.x121Conditions.atrBuffer[1]; + double iPeak = decisionConditions.x121Conditions.peaksBuffer[1]; + double iVale = decisionConditions.x121Conditions.valesBuffer[1]; // if (isBullish) { // - double lowerVale = triggerCycleHelper.mX121Helper.xpvHelper.GetLowerVale(iVale); + int lowerValeIDX = -1; + double lowerVale = triggerCycleHelper.mX121Helper.xpvHelper.GetLowerVale( + lowerValeIDX, + iVale // + ); if (lowerVale > 0) { // @@ -980,7 +986,11 @@ bool DetectX121SMCXOBSPVSiganlTrigger( else if (isBearish) { // - double higherPeak = triggerCycleHelper.mX121Helper.xpvHelper.GetHigherPeak(iPeak); + int higherPeakIDX = -1; + double higherPeak = triggerCycleHelper.mX121Helper.xpvHelper.GetHigherPeak( + higherPeakIDX, + iPeak // + ); if (higherPeak > 0) { // diff --git a/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 b/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 index da75d5bd..5e1be58a 100644 --- a/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 +++ b/X121SMCEA/Signals/x-121.smc.xstrpv.signal.lib.mq5 @@ -2,7 +2,7 @@ // // SaherElm IT Center MQL5 X121 SMC Signal Class // ------------------------------------------------- -// Name: XOBSPV +// Name: XSTRPV // Description: provide all Signalling functions ... // // @@ -26,7 +26,7 @@ // // Definitions ... -struct X121SMCStrategyXOBSPVSignalConditions +struct X121SMCStrategyXSTRPVSignalConditions { // // Props ... @@ -50,11 +50,11 @@ struct X121SMCStrategyXOBSPVSignalConditions // double pivot; - XPriceZones priceZone; + double point; // // Constructor ... - X121SMCStrategyXOBSPVSignalConditions() + X121SMCStrategyXSTRPVSignalConditions() { Clean(); } @@ -168,9 +168,7 @@ struct X121SMCStrategyXOBSPVSignalConditions { // pivot = 0; - - // - priceZone.Clean(); + point = 0; } // @@ -178,19 +176,19 @@ struct X121SMCStrategyXOBSPVSignalConditions // // Signaller Data Sources ... -X121SMCStrategyXOBSPVSignalConditions mXOBSPVConditions; -X121SMCStrategyXOBSPVSignalConditions mXOBSPVConditionsCollection[]; +X121SMCStrategyXSTRPVSignalConditions mXSTRPVConditions; +X121SMCStrategyXSTRPVSignalConditions mXSTRPVConditionsCollection[]; // // Extension Functions ... // // Detect Setup Conditions ... -bool DetectX121SMCXOBSPVSiganlSetup( +bool DetectX121SMCXSTRPVSiganlSetup( string _symbol, ENUM_TIMEFRAMES _period, // - X121SMCStrategyXOBSPVSignalConditions &conditions, + X121SMCStrategyXSTRPVSignalConditions &conditions, // XC121SMCCycleHelper *triggerCycleHelper, XC121SMCCycleHelper *decisionCycleHelper, @@ -268,7 +266,7 @@ bool DetectX121SMCXOBSPVSiganlSetup( double points = GetPoints(symbol); // - int swingLoopback = 9; + int swingLoopback = 3; double ll = cBar.FindLowest(swingLoopback, MODE_LOW); double hh = cBar.FindHighest(swingLoopback, MODE_HIGH); double llDown = cBar.FindLowesttDown(swingLoopback); @@ -412,111 +410,588 @@ bool DetectX121SMCXOBSPVSiganlSetup( } // - double decisionPeak = decisionConditions.x121Conditions.peaksBuffer[1]; - double decisionVale = decisionConditions.x121Conditions.valesBuffer[1]; + // Setup Conditions ... // - // Find Price Inside Zone ... - XPriceZones priceZone = conditions.priceZone; - bool hasPriceZones = conditions.priceZone.IsValid(); - if (!hasPriceZones) + // Detect Trend ... + + // + ENUM_X_DIRECTION marketDir; + bool hasMarketDir = decisionCycleHelper.DetectMarketStructure(marketDir); + + // + bool hasBullishTrend = + hasMarketDir && + IsBullish(marketDir); + + // + bool hasBearishTrend = + hasMarketDir && + IsBearish(marketDir); + + // + // Reading Bar State ... + + // + // Engulf ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulfed = decisionCycleHelper + .mBarAnalyser + .IsEngulfBar( + cBar, + cBarEngulfDir, + 0 // Extended ... + ); + bool isCBarBullishEngulfed = + isCBarEngulfed && + IsBullish(cBarEngulfDir); + bool isCBarBearishEngulfed = + isCBarEngulfed && + IsBearish(cBarEngulfDir); + + // + // Momentum ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentum = decisionCycleHelper + .mBarAnalyser + .IsMomentumBar( + cBar, + cBarMomentumDir, + 0 // Extended ... + ); + bool isCBarBullishMomentum = + isCBarMomentum && + IsBullish(cBarMomentumDir); + bool isCBarBearishMomentum = + isCBarMomentum && + IsBearish(cBarMomentumDir); + + // + // Reject ... + ENUM_X_DIRECTION cBarRejectDir; + bool isCBarRejected = decisionCycleHelper + .mBarAnalyser + .IsRejectionBar( + cBar, + cBarRejectDir, + 0 // Extended ... + ); + bool isCBarBullishRejected = + isCBarRejected && + IsBullish(cBarRejectDir); + bool isCBarBearishRejected = + isCBarRejected && + IsBearish(cBarRejectDir); + + // + // HH/LL Break ... + + // + bool isCBarBreaksUpHH = IsBarBreak( + hh, + X_DIRECTION_BULLISH, + cBar // + ); + + // + bool isCBarBreaksDownLL = IsBarBreak( + hh, + X_DIRECTION_BEARISH, + cBar // + ); + + // + // Bar Checking Summary ... + + // + // Bullish ... + bool isCBarBullishFormed = + // + isCBarBreaksUpHH || + isCBarBullishEngulfed || + isCBarBullishMomentum || + isCBarBullishRejected + // + ; + + // + // Bearish ... + bool isCBarBearishFormed = + // + isCBarBreaksDownLL || + isCBarBearishEngulfed || + isCBarBearishMomentum || + isCBarBearishRejected + // + ; + + // + // Read Slopes ... + double rsiSlope = decisionConditions.x121Conditions.rsiSlope; + double strSlope = decisionConditions.x121Conditions.strSlope; + double atrUpperSlope = decisionConditions.x121Conditions.atrUpperSlope; + double atrLowerSlope = decisionConditions.x121Conditions.atrLowerSlope; + double vwapFastSlope = decisionConditions.x121Conditions.vwapFastSlope; + double vwapMidSlope = decisionConditions.x121Conditions.vwapMidSlope; + double vwapSlowSlope = decisionConditions.x121Conditions.vwapSlowSlope; + + // + bool isRsiSlopeBullish = decisionConditions.x121Conditions.isRsiSlopeBullish; + bool isStrSlopeBullish = decisionConditions.x121Conditions.isStrSlopeBullish; + bool isAtrUpperSlopeBullish = decisionConditions.x121Conditions.isAtrUpperSlopeBullish; + bool isAtrLowerSlopeBullish = decisionConditions.x121Conditions.isAtrLowerSlopeBullish; + bool isVwapFastSlopeBullish = decisionConditions.x121Conditions.isVwapFastSlopeBullish; + bool isVwapMidSlopeBullish = decisionConditions.x121Conditions.isVwapMidSlopeBullish; + bool isVwapSlowSlopeBullish = decisionConditions.x121Conditions.isVwapSlowSlopeBullish; + + // + bool isRsiSlopeBearish = decisionConditions.x121Conditions.isRsiSlopeBearish; + bool isStrSlopeBearish = decisionConditions.x121Conditions.isStrSlopeBearish; + bool isAtrUpperSlopeBearish = decisionConditions.x121Conditions.isAtrUpperSlopeBearish; + bool isAtrLowerSlopeBearish = decisionConditions.x121Conditions.isAtrLowerSlopeBearish; + bool isVwapFastSlopeBearish = decisionConditions.x121Conditions.isVwapFastSlopeBearish; + bool isVwapMidSlopeBearish = decisionConditions.x121Conditions.isVwapMidSlopeBearish; + bool isVwapSlowSlopeBearish = decisionConditions.x121Conditions.isVwapSlowSlopeBearish; + + // + bool isSlopesBullish = + isRsiSlopeBullish && + isVwapMidSlopeBullish && + isAtrUpperSlopeBullish && + isAtrLowerSlopeBullish && + isVwapFastSlopeBullish && + isVwapSlowSlopeBullish; + + // + bool isSlopesBearish = + isRsiSlopeBearish && + isVwapMidSlopeBearish && + isAtrUpperSlopeBearish && + isAtrLowerSlopeBearish && + isVwapFastSlopeBearish && + isVwapSlowSlopeBearish; + + // + // RSI ... + + // + double rsiMult1 = 2; + double rsiMult2 = 2; + + // + double rsi = decisionConditions.x121Conditions.rsiBuffer[1]; + + // + bool isRsiOverSold = decisionConditions.x121Conditions.isRsiOverSold; + bool isRsiOverBought = decisionConditions.x121Conditions.isRsiOverBought; + + // + bool isRsiCrossedOverOverSold = decisionConditions.x121Conditions.isRsiCrossedOverOverSold; + bool isRsiCrossedUnderOverBought = decisionConditions.x121Conditions.isRsiCrossedUnderOverBought; + + // + bool isRsiBullishFormed = + // + (rsiSlope > rsiMult2) + // + || + // + (rsiSlope > rsiMult1 && + isRsiCrossedOverOverSold) + // + ; + + // + bool isRsiBearishFormed = + // + (rsiSlope < (-1 * rsiMult2)) + // + || + // + (rsiSlope < (-1 * rsiMult1) && + isRsiCrossedUnderOverBought) + // + ; + + // + // SAR ... + + // + double sar = decisionConditions.x121Conditions.sarBuffer[1]; + double sarPrev = decisionConditions.x121Conditions.sarBuffer[2]; + + // + bool isSarBullish = decisionConditions.x121Conditions.isSarBullish; + bool isSarBearish = decisionConditions.x121Conditions.isSarBearish; + + // + bool isSarSwitchedToBullish = decisionConditions.x121Conditions.isSarSwitchedToBullish; + bool isSarSwitchedToBearish = decisionConditions.x121Conditions.isSarSwitchedToBearish; + + // + bool isPrevSarBreakedUp = IsBarBreak( + sarPrev, + X_DIRECTION_BULLISH, + cBar // + ); + bool isPrevSarBreakedDown = IsBarBreak( + sarPrev, + X_DIRECTION_BEARISH, + cBar // + ); + + // + // ATR ... + + // + double atr = decisionConditions.x121Conditions.atrBuffer[1]; + double atrUpper = decisionConditions.x121Conditions.atrUpperBuffer[1]; + double atrLower = decisionConditions.x121Conditions.atrLowerBuffer[1]; + + // + bool isAtrUpperBullishSlope = atrUpperSlope > 0; + bool isAtrLowerBullishSlope = atrLowerSlope > 0; + + // + bool isAtrUpperBearishSlope = atrUpperSlope < 0; + bool isAtrLowerBearishSlope = atrLowerSlope < 0; + + // + bool isAtrBullishSlope = isAtrUpperBullishSlope && + isAtrLowerBullishSlope; + bool isAtrBearishSlope = isAtrUpperBearishSlope && + isAtrLowerBearishSlope; + + // + // STR ... + + // + double str = decisionConditions.x121Conditions.strBuffer[1]; + + // + bool isStrBullish = decisionConditions.x121Conditions.isStrBullish; + bool isStrBearish = decisionConditions.x121Conditions.isStrBearish; + + // + bool isStrSwitchedToBullish = decisionConditions.x121Conditions.isStrSwitchedToBullish; + bool isStrSwitchedToBearish = decisionConditions.x121Conditions.isStrSwitchedToBearish; + + // + // PV ... + + // + double peak = decisionConditions.x121Conditions.peaksBuffer[1]; + double vale = decisionConditions.x121Conditions.valesBuffer[1]; + + // + bool isPeakIncreasing = IsIncreasing(decisionConditions.x121Conditions.peaksBuffer); + bool isPeakDecreasing = IsDecreasing(decisionConditions.x121Conditions.peaksBuffer); + + // + bool isValeIncreasing = IsIncreasing(decisionConditions.x121Conditions.valesBuffer); + bool isValeDecreasing = IsDecreasing(decisionConditions.x121Conditions.valesBuffer); + + // + bool isPVIncreasing = (isPeakIncreasing && + isValeIncreasing) && + !(isPeakDecreasing && + isValeDecreasing); + bool isPVDecreasing = (isPeakDecreasing && + isValeDecreasing) && + !(isPeakIncreasing && + isValeIncreasing); + + // + bool isNewPeak = decisionConditions.x121Conditions.isNewPeak; + bool isNewPeakOverLast = decisionConditions.x121Conditions.isNewPeakOverLast; + bool isNewPeakUnderLast = decisionConditions.x121Conditions.isNewPeakUnderLast; + + // + bool isNewVale = decisionConditions.x121Conditions.isNewVale; + bool isNewValeOverLast = decisionConditions.x121Conditions.isNewValeOverLast; + bool isNewValeUnderLast = decisionConditions.x121Conditions.isNewValeUnderLast; + + // + bool isPVBullishFormed = + isPVIncreasing || + isNewPeakOverLast || + isNewValeOverLast; + + // + bool isPVBearishFormed = + isPVDecreasing || + isNewPeakUnderLast || + isNewValeUnderLast; + + // + // VWAP ... + + // + bool isVWapFastOverMid = decisionConditions.x121Conditions.isVWapFastOverMid; + bool isVWapFastUnderMid = decisionConditions.x121Conditions.isVWapFastUnderMid; + + // + bool isVWapBullishState = decisionConditions.x121Conditions.isVWapBullishState; + bool isVWapBearishState = decisionConditions.x121Conditions.isVWapBearishState; + + // + bool isVWapSwitchedToBullishState = decisionConditions.x121Conditions.isVWapSwitchedToBullishState; + bool isVWapSwitchedToBearishState = decisionConditions.x121Conditions.isVWapSwitchedToBearishState; + + // + bool isVWapBullishOrdered = decisionConditions.x121Conditions.isVWapBullishOrdered; + bool isVWapBearishOrdered = decisionConditions.x121Conditions.isVWapBearishOrdered; + + // + bool isVWapSwitchedToBullishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBullishOrdered; + bool isVWapSwitchedToBearishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBearishOrdered; + + // + bool isVWapMinBreakedUp = decisionConditions.x121Conditions.isVWapMinBreakedUp; + bool isVWapMaxBreakedUp = decisionConditions.x121Conditions.isVWapMaxBreakedUp; + + // + bool isVWapMinBreakedDown = decisionConditions.x121Conditions.isVWapMinBreakedDown; + bool isVWapMaxBreakedDown = decisionConditions.x121Conditions.isVWapMaxBreakedDown; + + // + bool isVWapFastCrossedOverMid = decisionConditions.x121Conditions.isVWapFastCrossedOverMid; + bool isVWapFastCrossedUnderMid = decisionConditions.x121Conditions.isVWapFastCrossedUnderMid; + + // + bool isVWapFastCrossedOverSlow = decisionConditions.x121Conditions.isVWapFastCrossedOverSlow; + bool isVWapFastCrossedUnderSlow = decisionConditions.x121Conditions.isVWapFastCrossedUnderSlow; + + // + bool isClosedOverVWapMin = decisionConditions.x121Conditions.isClosedOverVWapMin; + bool isClosedUnderVWapMin = decisionConditions.x121Conditions.isClosedUnderVWapMin; + + // + bool isClosedOverVWapMax = decisionConditions.x121Conditions.isClosedOverVWapMax; + bool isClosedUnderVWapMax = decisionConditions.x121Conditions.isClosedUnderVWapMax; + + // + bool isVWapBullishSlope = + vwapFastSlope > 0 && + vwapMidSlope > 0 && + vwapSlowSlope > 0; + + // + bool isVWapBearishSlope = + vwapFastSlope < 0 && + vwapMidSlope < 0 && + vwapSlowSlope < 0; + + // + bool isVWapBullishFormed = + // + isVWapBullishSlope + // + && + // + ( + // + (isVWapBullishOrdered && + isVWapSwitchedToBullishState) + // + || + // + (isVWapBullishState && + isVWapSwitchedToBullishOrdered) + // + || + // + ((isVWapMaxBreakedUp || + isClosedOverVWapMax) && + (isVWapFastCrossedOverMid || + isVWapFastCrossedOverSlow)) + // + ) + // + ; + + // + bool isVWapBearishFormed = + // + isVWapBearishSlope + // + && + // + ( + // + (isVWapBearishOrdered && + isVWapSwitchedToBearishState) + // + || + // + (isVWapBearishState && + isVWapSwitchedToBearishOrdered) + // + || + // + ((isVWapMinBreakedDown || + isClosedUnderVWapMin) && + (isVWapFastCrossedUnderMid || + isVWapFastCrossedUnderSlow)) + // + ) + // + ; + + // + // Complext ... + + // + bool isSarIncreased = decisionConditions.x121Conditions.isSarIncreased; + bool isSarDecreased = decisionConditions.x121Conditions.isSarDecreased; + bool isSarEqualsToPeak = decisionConditions.x121Conditions.isSarEqualsToPeak; + bool isSarEqualsToVale = decisionConditions.x121Conditions.isSarEqualsToVale; + bool isStrEqualsToPeak = decisionConditions.x121Conditions.isStrEqualsToPeak; + bool isStrEqualsToVale = decisionConditions.x121Conditions.isStrEqualsToVale; + bool isStrUpperOverPeak = decisionConditions.x121Conditions.isStrUpperOverPeak; + bool isPeakOverAtrUpper = decisionConditions.x121Conditions.isPeakOverAtrUpper; + bool isStrLowerOverVale = decisionConditions.x121Conditions.isStrLowerOverVale; + bool isBreakedUpPrevSar = decisionConditions.x121Conditions.isBreakedUpPrevSar; + bool isBreakedUpPrevStr = decisionConditions.x121Conditions.isBreakedUpPrevStr; + bool isStrLowerUnderVale = decisionConditions.x121Conditions.isStrLowerUnderVale; + bool isStrUpperUnderPeak = decisionConditions.x121Conditions.isStrUpperUnderPeak; + bool isValeUnderAtrLower = decisionConditions.x121Conditions.isValeUnderAtrLower; + bool isSarCrossedOverVale = decisionConditions.x121Conditions.isSarCrossedOverVale; + bool isStrCrossedOverVale = decisionConditions.x121Conditions.isStrCrossedOverVale; + bool isBreakedDownPrevStr = decisionConditions.x121Conditions.isBreakedDownPrevStr; + bool isBreakedDownPrevSar = decisionConditions.x121Conditions.isBreakedDownPrevSar; + bool isSarCrossedUnderPeak = decisionConditions.x121Conditions.isSarCrossedUnderPeak; + bool isStrCrossedUnderPeak = decisionConditions.x121Conditions.isStrCrossedUnderPeak; + bool isNewPeakOverAtrUpper = decisionConditions.x121Conditions.isNewPeakOverAtrUpper; + bool isNewValeUnderAtrLower = decisionConditions.x121Conditions.isNewValeUnderAtrLower; + bool isStrUpperOverAtrUpper = decisionConditions.x121Conditions.isStrUpperOverAtrUpper; + bool isStrLowerOverAtrLower = decisionConditions.x121Conditions.isStrLowerOverAtrLower; + bool isStrUpperUnderAtrUpper = decisionConditions.x121Conditions.isStrUpperUnderAtrUpper; + bool isStrLowerUnderAtrLower = decisionConditions.x121Conditions.isStrLowerUnderAtrLower; + bool isBreakedUpPrevAtrUpper = decisionConditions.x121Conditions.isBreakedUpPrevAtrUpper; + bool isBreakedUpPrevAtrLower = decisionConditions.x121Conditions.isBreakedUpPrevAtrLower; + bool isBreakedDownPrevAtrUpper = decisionConditions.x121Conditions.isBreakedDownPrevAtrUpper; + bool isBreakedDownPrevAtrLower = decisionConditions.x121Conditions.isBreakedDownPrevAtrLower; + bool isDonLowLowerEqualsToVale = decisionConditions.x121Conditions.isDonLowLowerEqualsToVale; + bool isStrUpperCrossedOverPeak = decisionConditions.x121Conditions.isStrUpperCrossedOverPeak; + bool isStrLowerCrossedOverVale = decisionConditions.x121Conditions.isStrLowerCrossedOverVale; + bool isStrLowerOverDonLowLower = decisionConditions.x121Conditions.isStrLowerOverDonLowLower; + bool isStrUpperOverDonHighUpper = decisionConditions.x121Conditions.isStrUpperOverDonHighUpper; + bool isStrLowerUnderDonLowLower = decisionConditions.x121Conditions.isStrLowerUnderDonLowLower; + bool isDonHighUpperEqualsToPeak = decisionConditions.x121Conditions.isDonHighUpperEqualsToPeak; + bool isStrUpperCrossedUnderPeak = decisionConditions.x121Conditions.isStrUpperCrossedUnderPeak; + bool isStrLowerCrossedUnderVale = decisionConditions.x121Conditions.isStrLowerCrossedUnderVale; + bool isStrUpperUnderDonHighUpper = decisionConditions.x121Conditions.isStrUpperUnderDonHighUpper; + bool isStrLowerCrossedOverAtrLower = decisionConditions.x121Conditions.isStrLowerCrossedOverAtrLower; + bool isStrUpperCrossedOverAtrUpper = decisionConditions.x121Conditions.isStrUpperCrossedOverAtrUpper; + bool isStrUpperCrossedUnderAtrUpper = decisionConditions.x121Conditions.isStrUpperCrossedUnderAtrUpper; + bool isStrLowerCrossedUnderAtrLower = decisionConditions.x121Conditions.isStrLowerCrossedUnderAtrLower; + bool isStrLowerCrossedOverDonLowLower = decisionConditions.x121Conditions.isStrLowerCrossedOverDonLowLower; + bool isStrUpperCrossedOverDonHighUpper = decisionConditions.x121Conditions.isStrUpperCrossedOverDonHighUpper; + bool isStrLowerCrossedUnderDonLowLower = decisionConditions.x121Conditions.isStrLowerCrossedUnderDonLowLower; + bool isStrUpperCrossedUnderDonHighUpper = decisionConditions.x121Conditions.isStrUpperCrossedUnderDonHighUpper; + + // + XPriceZones priceZones; + bool hasPriceZones = CalculatePriceInsideZones( + priceZones, + analyseState, + cBar // + ); + double priceZonesUpper = 0; + double priceZonesLower = 0; + bool isPriceZoneValidForPeak = false; + bool isPriceZoneValidForVale = false; + if (hasPriceZones) { // - hasPriceZones = CalculatePriceInsideZones( - priceZone, - analyseState, - cBar // + bool hasBoundary = priceZones.GetBoundary( + X_DIRECTION_ALL, + priceZonesUpper, + priceZonesLower // ); // - if (hasPriceZones) - { - // - // Validate Price Zone ... - double upper = 0; - double lower = 0; - hasPriceZones = priceZone.GetBoundary( - X_DIRECTION_ALL, - upper, - lower // - ); - result = hasPriceZones; - if (!result) - { - return result; - } + isPriceZoneValidForPeak = + hasBoundary && + peak <= priceZonesUpper && + peak >= priceZonesLower; - // - bool isValid = decisionPeak <= upper || - decisionVale >= lower; - hasPriceZones = isValid; - result = hasPriceZones; - if (!result) - { - return result; - } - - // - conditions.priceZone = priceZone; - } + // + isPriceZoneValidForVale = + hasBoundary && + vale <= priceZonesUpper && + vale >= priceZonesLower; } // - // Detect Str Change Direction ... + // + // // - bool isDecisionSarBullish = decisionConditions.x121Conditions.isSarBullish; - bool isDecisionSarBearish = decisionConditions.x121Conditions.isSarBearish; + // Method 1 ... + // VWap Switch Start ... // - bool isDecisionStrBullish = decisionConditions.x121Conditions.isStrBullish; - bool isDecisionStrBearish = decisionConditions.x121Conditions.isStrBearish; + bool bullishMethod1 = + // + isSarBullish && + isStrBullish && + isSlopesBullish && + hasBullishTrend && + cBar.IsBullish() && + isAtrBullishSlope && + isPVBullishFormed && + isRsiBullishFormed && + isVWapBullishFormed + // + ; // - bool isDecisionSarCrossedOverVale = decisionConditions.x121Conditions.isSarCrossedOverVale; - bool isDecisionSarCrossedUnderPeak = decisionConditions.x121Conditions.isSarCrossedUnderPeak; + bool bearishMethod1 = + // + isSarBearish && + isStrBearish && + isSlopesBearish && + hasBearishTrend && + cBar.IsBearish() && + isAtrBearishSlope && + isPVBearishFormed && + isRsiBearishFormed && + isVWapBearishFormed + // + ; // - bool isDecisionStrCrossedOverVale = decisionConditions.x121Conditions.isStrCrossedOverVale; - bool isDecisionStrCrossedUnderPeak = decisionConditions.x121Conditions.isStrCrossedUnderPeak; + // Method 2 ... + // PV Start ... // - bool isDecisionPeakOverAtrUpper = decisionConditions.x121Conditions.isPeakOverAtrUpper; - bool isDecisionValeUnderAtrLower = decisionConditions.x121Conditions.isValeUnderAtrLower; + bool bullishMethod2 = + // + false + // isStrCrossedOverVale + // + ; // - bool isDecisionVWapBullishState = decisionConditions.x121Conditions.isVWapBullishState; - bool isDecisionVWapSwitchedToBullishState = decisionConditions.x121Conditions.isVWapSwitchedToBullishState; + bool bearishMethod2 = + // + !isNewVale && + ( + // + isStrCrossedUnderPeak + // + || + // + (isPrevSarBreakedDown && + isStrSwitchedToBearish) + // + ) + // + ; // - bool isDecisionVWapBullishOrdered = decisionConditions.x121Conditions.isVWapBullishOrdered; - bool isDecisionVWapSwitchedToBullishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBullishOrdered; - - // - bool isDecisionVWapBearishState = decisionConditions.x121Conditions.isVWapBearishState; - bool isDecisionVWapSwitchedToBearishState = decisionConditions.x121Conditions.isVWapSwitchedToBearishState; - - // - bool isDecisionVWapBearishOrdered = decisionConditions.x121Conditions.isVWapBearishOrdered; - bool isDecisionVWapSwitchedToBearishOrdered = decisionConditions.x121Conditions.isVWapSwitchedToBearishOrdered; - - // - bool isDecisionStrUpperOverPeak = decisionConditions.x121Conditions.isStrUpperOverPeak; - bool isDecisionStrLowerOverVale = decisionConditions.x121Conditions.isStrLowerOverVale; - - // - bool isDecisionStrUpperUnderPeak = decisionConditions.x121Conditions.isStrUpperUnderPeak; - bool isDecisionStrLowerUnderVale = decisionConditions.x121Conditions.isStrLowerUnderVale; - - // - bool isDecisionDonLowUpperLesserThanDonCloseUpper = - decisionConditions.x121Conditions.donLowUpperBuffer[1] < - decisionConditions.x121Conditions.donCloseUpperBuffer[1]; - - // - bool isDecisionDonHighLowerGreaterThanDonCloseLower = - decisionConditions.x121Conditions.donHighLowerBuffer[1] < - decisionConditions.x121Conditions.donCloseLowerBuffer[1]; // // Summarize Conditions ... @@ -524,101 +999,22 @@ bool DetectX121SMCXOBSPVSiganlSetup( // isBullish = // - isDecisionValeUnderAtrLower + // bullishMethod1 + // // + // || // - && - // - isDecisionDonHighLowerGreaterThanDonCloseLower - // - && - // - ( - // - isDecisionVWapBullishState || - isDecisionVWapBullishOrdered - // - ) - // - && - // - ( - // - isDecisionStrUpperOverPeak || - isDecisionStrLowerOverVale - // - ) - // - && - // - ( - // - ( - // - isDecisionStrBullish && - isDecisionSarCrossedOverVale - // - ) - // - || - // - ( - // - isDecisionSarBullish && - isDecisionStrCrossedOverVale - // - ) - // - ) + bullishMethod2 // ; // isBearish = // - isDecisionPeakOverAtrUpper + // bearishMethod1 + // // + // || // - && - // - isDecisionDonLowUpperLesserThanDonCloseUpper - // - && - // - ( - // - isDecisionVWapBearishState || - isDecisionVWapBearishOrdered - // - ) - // - && - // - ( - // - isDecisionStrUpperUnderPeak || - isDecisionStrLowerUnderVale - // - ) - // - && - // - ( - // - ( - // - isDecisionStrBearish && - isDecisionSarCrossedUnderPeak - // - ) - // - || - // - ( - // - isDecisionSarBearish && - isDecisionStrCrossedUnderPeak // - ) - // - ) + bearishMethod2 // ; @@ -631,21 +1027,32 @@ bool DetectX121SMCXOBSPVSiganlSetup( } // + conditions.point = + isBullish + ? vale + : peak; conditions.setupTime = cTime; conditions.dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; + // + double point = GetEntry( + conditions.symbol, + conditions.dir // + ); + conditions.point = point; + // return result; } // // Detect Trigger Conditions ... -bool DetectX121SMCXOBSPVSiganlTrigger( +bool DetectX121SMCXSTRPVSiganlTrigger( // - X121SMCStrategyXOBSPVSignalConditions &conditions, + X121SMCStrategyXSTRPVSignalConditions &conditions, // string _symbol, ENUM_TIMEFRAMES _period, @@ -859,20 +1266,46 @@ bool DetectX121SMCXOBSPVSiganlTrigger( // Trigger Conditions ... // - double decisionLastBullishStr = decisionCycleHelper.mX121Helper.xstrHelper.GetLastSTR(X_DIRECTION_BULLISH); - double decisionLastBearishStr = decisionCycleHelper.mX121Helper.xstrHelper.GetLastSTR(X_DIRECTION_BEARISH); + // SAR ... + double sar = decisionConditions.x121Conditions.sarBuffer[1]; // - bool isDecisionLastBearishStrBreakedUp = IsBarBreak( - decisionLastBearishStr, - X_DIRECTION_BULLISH, - cBar // - ); + // STR ... + double str = decisionConditions.x121Conditions.strBuffer[1]; // - bool isDecisionLastBullishStrBreakedDown = IsBarBreak( - decisionLastBullishStr, - X_DIRECTION_BEARISH, + // ATR ... + double atrUpper = decisionConditions.x121Conditions.atrUpperBuffer[1]; + double atrLower = decisionConditions.x121Conditions.atrLowerBuffer[1]; + + // + // PV ... + double peak = decisionConditions.x121Conditions.peaksBuffer[1]; + double vale = decisionConditions.x121Conditions.valesBuffer[1]; + + // + int higherPeakIDX = -1; + double higherPeak = decisionCycleHelper + .mX121Helper + .xpvHelper.GetHigherPeak( + higherPeakIDX, + peak // + ); + + // + int lowerValeIDX = -1; + double lowerVale = decisionCycleHelper + .mX121Helper + .xpvHelper.GetLowerVale( + lowerValeIDX, + vale // + ); + + // + double point = conditions.point; + bool isPointBreak = IsBarBreak( + point, + setupDir, cBar // ); @@ -881,7 +1314,12 @@ bool DetectX121SMCXOBSPVSiganlTrigger( isBullish = // isBullish && - isDecisionLastBearishStrBreakedUp + isPointBreak && + cBar.IsBullish() + // + // && + // // + // false // ; @@ -890,7 +1328,12 @@ bool DetectX121SMCXOBSPVSiganlTrigger( isBearish = // isBearish && - isDecisionLastBullishStrBreakedDown + isPointBreak && + cBar.IsBearish() + // + // && + // // + // false // ; @@ -920,7 +1363,7 @@ bool DetectX121SMCXOBSPVSiganlTrigger( // Detect Target ... double target = CalculateTarget( cBar, - analyseState, + decisionState, setupDir // ); if (target == 0) @@ -928,17 +1371,22 @@ bool DetectX121SMCXOBSPVSiganlTrigger( // target = CalculateTarget( cBar, - verificationState, + analyseState, setupDir // ); - } - // - double oppositTarget = CalculateTarget( - cBar, - analyseState, - Opposit(setupDir) // - ); + // + if (target == 0) + { + // + target = CalculateTarget( + cBar, + verificationState, + setupDir // + ); + } + } + target = 0; // double entry = GetEntry( @@ -948,21 +1396,140 @@ bool DetectX121SMCXOBSPVSiganlTrigger( // // Filling SL Candidates ... + double momentumBarPointsDif = 30 * points; + + // + // Bullish Momentum Bar Selection ... + XOHCL bullishMomentumBar; + int bullishMomentumBarsCount = decisionState.CountBullishMomentumBars(); + if (IsValidSize(bullishMomentumBarsCount)) + { + // + for (int i = 0; i < bullishMomentumBarsCount; i++) + { + // + XCMomentumBar *iMomentum = decisionState.bullishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isValidDistane = (MathAbs(iBar.low) - entry) >= momentumBarPointsDif; + if (!isValidDistane) + { + continue; + } + + // + bool isIndexPassed = iBar.Index() <= 5; + if (!isIndexPassed) + { + continue; + } + + // + bool canSet = + !bullishMomentumBar.IsValid() || + (bullishMomentumBar.IsValid() && + bullishMomentumBar.low < entry && + bullishMomentumBar.Index() > iBar.Index()); + if (canSet) + { + bullishMomentumBar = iBar; + } + } + } + + // + // Bearish Momentum Bar Selection ... + XOHCL bearishMomentumBar; + int bearishMomentumBarsCount = decisionState.CountBearishMomentumBars(); + if (IsValidSize(bearishMomentumBarsCount)) + { + // + for (int i = 0; i < bearishMomentumBarsCount; i++) + { + // + XCMomentumBar *iMomentum = decisionState.bearishMomentumBars[i]; + + // + XOHCL iBar; + bool isFilled = iMomentum.FillBar(iBar); + if (!isFilled) + { + continue; + } + + // + bool isValidDistane = (MathAbs(iBar.high) - entry) >= momentumBarPointsDif; + if (!isValidDistane) + { + continue; + } + + // + bool isIndexPassed = iBar.Index() <= 5; + if (!isIndexPassed) + { + continue; + } + + // + bool canSet = + !bearishMomentumBar.IsValid() || + (bearishMomentumBar.IsValid() && + bearishMomentumBar.high > entry && + bearishMomentumBar.Index() > iBar.Index()); + if (canSet) + { + bearishMomentumBar = iBar; + } + } + } // double sls[]; - - // - double iAtr = triggerConditions.x121Conditions.atrBuffer[1]; - double iPeak = triggerConditions.x121Conditions.peaksBuffer[1]; - double iVale = triggerConditions.x121Conditions.valesBuffer[1]; + Add( + sar, + sls // + ); + Add( + str, + sls // + ); // if (isBullish) { // - double lowerVale = triggerCycleHelper.mX121Helper.xpvHelper.GetLowerVale(iVale); - if (lowerVale > 0) + Add( + atrLower, + sls // + ); + + // + Add( + vale, + sls // + ); + + // + if (bullishMomentumBar.IsValid()) + { + // + Add( + bullishMomentumBar.low, + sls // + ); + } + + // + if (IsValidIndex(lowerValeIDX)) { // Add( @@ -970,18 +1537,33 @@ bool DetectX121SMCXOBSPVSiganlTrigger( sls // ); } + } + else + { + // + Add( + atrUpper, + sls // + ); // Add( - iVale, + peak, sls // ); - } - else if (isBearish) - { + // - double higherPeak = triggerCycleHelper.mX121Helper.xpvHelper.GetHigherPeak(iPeak); - if (higherPeak > 0) + if (bearishMomentumBar.IsValid()) + { + // + Add( + bearishMomentumBar.high, + sls // + ); + } + + // + if (IsValidIndex(higherPeakIDX)) { // Add( @@ -989,14 +1571,11 @@ bool DetectX121SMCXOBSPVSiganlTrigger( sls // ); } - - // - Add( - iPeak, - sls // - ); } + // + double iAtr = decisionConditions.x121Conditions.atrBuffer[1]; + // double slsMin = GetMin(sls); double slsMax = GetMax(sls); @@ -1006,34 +1585,19 @@ bool DetectX121SMCXOBSPVSiganlTrigger( ? slsMin - iAtr : slsMax + iAtr; double risk = MathAbs(entry - sl); - double targetDelta = 2 * (risk / 3); - if (target == 0) + double riskInPoints = risk / points; + if (riskInPoints >= 150) { // - int minTargetPint = 50; - double minTargetPointValue = minTargetPint * points; - if (targetDelta < minTargetPointValue) - { - targetDelta = minTargetPointValue; - } - - // - // Force Target On Half Risk ... target = isBullish - ? entry + targetDelta - : entry - targetDelta; + ? entry + (points * 200) + : entry - (points * 200); // target = 0; - - // } - // - // Ignore Target ... - target = 0; - // // Filling Conditions Props ... conditions.sl = sl; @@ -1048,9 +1612,9 @@ bool DetectX121SMCXOBSPVSiganlTrigger( } // -int AddX121SMCXOBSPVConditionsIfNotExists( - X121SMCStrategyXOBSPVSignalConditions &item, - X121SMCStrategyXOBSPVSignalConditions &items[], +int AddX121SMCXSTRPVConditionsIfNotExists( + X121SMCStrategyXSTRPVSignalConditions &item, + X121SMCStrategyXSTRPVSignalConditions &items[], int maxAllowed = 10 // ) { @@ -1071,7 +1635,7 @@ int AddX121SMCXOBSPVConditionsIfNotExists( { // // Copy Original Items ... - X121SMCStrategyXOBSPVSignalConditions tmpItems[]; + X121SMCStrategyXSTRPVSignalConditions tmpItems[]; Copy( items, tmpItems // @@ -1085,7 +1649,7 @@ int AddX121SMCXOBSPVConditionsIfNotExists( for (int i = 0; i < count; i++) { // - X121SMCStrategyXOBSPVSignalConditions iItem = tmpItems[i]; + X121SMCStrategyXSTRPVSignalConditions iItem = tmpItems[i]; // bool canRemove = item.dir == iItem.dir && diff --git a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 index 95e4df6d..955a9c51 100644 --- a/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.strategy.class.mq5 @@ -30,6 +30,7 @@ #include "../Signals/x-121.smc.test.signal.lib.mq5" #include "../Signals/x-121.smc.xobgpv.signal.lib.mq5" #include "../Signals/x-121.smc.xobspv.signal.lib.mq5" +#include "../Signals/x-121.smc.xstrpv.signal.lib.mq5" // // Definitions ... @@ -185,13 +186,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // bool useTestSignal = false; - bool useXOBGPVSignal = true; - bool useXOBSPVSignal = true; + bool useXOBGPVSignal = false; + bool useXOBSPVSignal = false; + bool useXSTRPVSignal = true; // bool hasTestSignal = false; bool hasXOBGPVSignal = false; bool hasXOBSPVSignal = false; + bool hasXSTRPVSignal = false; // // Test Signal ... @@ -220,6 +223,15 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy hasSignal = hasXOBSPVSignal; } + // + // XSTRPV Signal ... + if (useXSTRPVSignal && !hasSignal) + { + // + hasXSTRPVSignal = DetectXSTRPVSignal(conditions); + hasSignal = hasXSTRPVSignal; + } + // result = hasSignal; if (!result) @@ -325,6 +337,18 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // if (result) { + // + // Configure Signal Protector ... + if (useXSTRPVSignal) + { + // + signal.trailSL = false; + signal.fullTPLevel = r2r; + signal.partialCloseOnTPLevel = 2; + signal.partialCloseMultiplier = 0.5; + signal.trailSLStartOnReachTPLevel = 2; + } + // // TODO: Remove this ... // XCSignalObject *iObj; @@ -964,6 +988,224 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy return result; } + // + // XSTRPV Signal ... + bool DetectXSTRPVSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + bool isBullish = false; + bool isBearish = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + pIndex // + ); + if (!result) + { + return result; + } + + // + double cLL = cBar.FindLowest(7, MODE_LOW); + double cHH = cBar.FindHighest(7, MODE_HIGH); + + // + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_XSTRPV; + string providerStr = ToString(provider); + + // + // Detect Setup Conditions ... + datetime setupTime = mXSTRPVConditions.setupTime; + bool isSetuped = mXSTRPVConditions.IsSetuped(); + ENUM_X_DIRECTION setupDir = mXSTRPVConditions.dir; + if (!isSetuped) + { + // + // Detect Signal Setup ... + isSetuped = DetectX121SMCXSTRPVSiganlSetup( + symbol, + period, + mXSTRPVConditions, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + setupDir = mXSTRPVConditions.dir; + setupTime = mXSTRPVConditions.setupTime; + + // + if (isSetuped) + { + // + int items = AddX121SMCXSTRPVConditionsIfNotExists( + mXSTRPVConditions, + mXSTRPVConditionsCollection // + ); + + // + mXSTRPVConditions.Clean(); + } + } + + // + int conditionsCount = ArraySize(mXSTRPVConditionsCollection); + result = IsValidSize(conditionsCount); + if (!result) + { + return result; + } + + // + // Looking For Conditions ... + int selectedIndex = 0; + X121SMCStrategyXSTRPVSignalConditions mTmpConditions[]; + Copy( + mXSTRPVConditionsCollection, + mTmpConditions // + ); + X121SMCStrategyXSTRPVSignalConditions mConditions; + for (int i = 0; i < conditionsCount; i++) + { + // + // Check Triggers ... + bool canTrigger = mTmpConditions[i].CanTrigger(); + datetime triggerTime = mTmpConditions[i].triggerTime; + if (!canTrigger) + { + // + // Detect Signal Trigger ... + canTrigger = DetectX121SMCXSTRPVSiganlTrigger( + mTmpConditions[i], + symbol, + period, + mTriggerCycleHelper, + mDecisionCycleHelper, + mAnalyseCycleHelper, + mVerificationCycleHelper, + mConsolidationCycleHelper, + mVisionCycleHelper // + ); + + // + result = canTrigger; + if (!result) + { + // + bool isISetuped = mTmpConditions[i].IsSetuped(); + if (!isISetuped) + { + // + ArrayRemove( + mXSTRPVConditionsCollection, + i, + 1 // + ); + } + continue; + } + + // + triggerTime = mTmpConditions[i].triggerTime; + } + + // + if (canTrigger) + { + // + selectedIndex = i; + mConditions = mTmpConditions[i]; + break; + } + } + + // + result = IsValid(mConditions.setupTime) && + HasDirection(mConditions.dir); + if (!result) + { + return result; + } + + // + // Remove Selected Index from Main Collection ... + ArrayRemove( + mXSTRPVConditionsCollection, + selectedIndex, + 1 // + ); + + // + // Check Signal Direction ... + isBullish = IsBullish(mConditions.dir); + isBearish = IsBearish(mConditions.dir); + result = isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Issues Signal on Conditions ... + conditions.sl = mConditions.sl; + conditions.provider = providerStr; + conditions.signalDir = mConditions.dir; + conditions.target = mConditions.target; + + // + return result; + } + // // Private ... private: @@ -1015,6 +1257,9 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy // x121Inputs.Default(); + // + bool showAll = false; + // x121Inputs.showRSI = false; @@ -1035,33 +1280,40 @@ class XCX121SMCStrategy : public XCX121SMCBaseStrategy x121Inputs.xpvInputs.hcPeriod = hcPeriod; // - x121Inputs.xpvInputs.showSar = true; - x121Inputs.xpvInputs.showPeaks = true; - x121Inputs.xpvInputs.showVales = true; + x121Inputs.xpvInputs.showSar = showAll || true; + x121Inputs.xpvInputs.showPeaks = showAll || true; + x121Inputs.xpvInputs.showVales = showAll || true; // // XATR ... - x121Inputs.xatrInputs.showATRUpper = false; - x121Inputs.xatrInputs.showATRLower = false; + x121Inputs.xatrInputs.showATRUpper = showAll || false; + x121Inputs.xatrInputs.showATRLower = showAll || false; // // XSTR ... - x121Inputs.xstrInputs.showStr = true; - x121Inputs.xstrInputs.showStrUpper = false; - x121Inputs.xstrInputs.showStrLower = false; + x121Inputs.xstrInputs.showStr = showAll || true; + x121Inputs.xstrInputs.showStrUpper = showAll || false; + x121Inputs.xstrInputs.showStrLower = showAll || false; + + // + // XCHE ... + x121Inputs.xcheInputs.showLE1 = showAll || true; + x121Inputs.xcheInputs.showLE2 = showAll || true; + x121Inputs.xcheInputs.showSE1 = showAll || true; + x121Inputs.xcheInputs.showSE2 = showAll || true; // // XDON ... - x121Inputs.xdonInputs.showOpen = false; - x121Inputs.xdonInputs.showClose = true; - x121Inputs.xdonInputs.showLow = true; - x121Inputs.xdonInputs.showHigh = true; + x121Inputs.xdonInputs.showOpen = showAll || false; + x121Inputs.xdonInputs.showClose = showAll || false; + x121Inputs.xdonInputs.showLow = showAll || false; + x121Inputs.xdonInputs.showHigh = showAll || false; // // XVWAP ... - x121Inputs.xvwapInputs.showVWapFast = false; - x121Inputs.xvwapInputs.showVWapMedium = false; - x121Inputs.xvwapInputs.showVWapSlow = false; + x121Inputs.xvwapInputs.showVWapFast = showAll || false; + x121Inputs.xvwapInputs.showVWapMedium = showAll || false; + x121Inputs.xvwapInputs.showVWapSlow = showAll || false; // // Initialize Cycle Helpers ...