diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index f41d4dca..133f918b 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -3531,16 +3531,20 @@ class XCX121Helper : public XCBaseHelper // // Conditions ... + // + int cIDX = 1; + int pIDX = cIDX + 1; + // // XSAR ... // - bool isSarBullish = conditions.sarBuffer[cIndex] < cBar.low; - bool isSarBullishPrev = conditions.sarBuffer[pIndex] < pBar.low; + bool isSarBullish = conditions.sarBuffer[cIDX] < cBar.low; + bool isSarBullishPrev = conditions.sarBuffer[pIDX] < pBar.low; // - bool isSarBearish = conditions.sarBuffer[cIndex] > cBar.high; - bool isSarBearishPrev = conditions.sarBuffer[pIndex] > pBar.high; + bool isSarBearish = conditions.sarBuffer[cIDX] > cBar.high; + bool isSarBearishPrev = conditions.sarBuffer[pIDX] > pBar.high; // bool isSarSwitchedToBullish = isSarBullish && @@ -3552,73 +3556,73 @@ class XCX121Helper : public XCBaseHelper // XPV ... // - bool isNewPeak = conditions.peaksBuffer[cIndex] != conditions.peaksBuffer[pIndex]; + bool isNewPeak = conditions.peaksBuffer[cIDX] != conditions.peaksBuffer[pIDX]; bool isNewPeakOverLast = isNewPeak && - conditions.peaksBuffer[cIndex] > conditions.peaksBuffer[pIndex]; + conditions.peaksBuffer[cIDX] > conditions.peaksBuffer[pIDX]; bool isNewPeakUnderLast = isNewPeak && - conditions.peaksBuffer[cIndex] < conditions.peaksBuffer[pIndex]; + conditions.peaksBuffer[cIDX] < conditions.peaksBuffer[pIDX]; // - bool isNewVale = conditions.valesBuffer[cIndex] != conditions.valesBuffer[pIndex]; + bool isNewVale = conditions.valesBuffer[cIDX] != conditions.valesBuffer[pIDX]; bool isNewValeOverLast = isNewVale && - conditions.valesBuffer[cIndex] > conditions.valesBuffer[pIndex]; + conditions.valesBuffer[cIDX] > conditions.valesBuffer[pIDX]; bool isNewValeUnderLast = isNewVale && - conditions.valesBuffer[cIndex] < conditions.valesBuffer[pIndex]; + conditions.valesBuffer[cIDX] < conditions.valesBuffer[pIDX]; // // XVWAP ... // - bool isVWapFastBullish = IsVWAPBullish(conditions.vwapFastStateBuffer[cIndex]); - bool isVWapFastBullishPrev = IsVWAPBullish(conditions.vwapFastStateBuffer[pIndex]); + bool isVWapFastBullish = IsVWAPBullish(conditions.vwapFastStateBuffer[cIDX]); + bool isVWapFastBullishPrev = IsVWAPBullish(conditions.vwapFastStateBuffer[pIDX]); // - bool isVWapFastBearish = IsVWAPBearish(conditions.vwapFastStateBuffer[cIndex]); - bool isVWapFastBearishPrev = IsVWAPBearish(conditions.vwapFastStateBuffer[pIndex]); + bool isVWapFastBearish = IsVWAPBearish(conditions.vwapFastStateBuffer[cIDX]); + bool isVWapFastBearishPrev = IsVWAPBearish(conditions.vwapFastStateBuffer[pIDX]); // - bool isVWapFastNeutural = IsVWAPNeutural(conditions.vwapFastStateBuffer[cIndex]); - bool isVWapFastNeuturalPrev = IsVWAPNeutural(conditions.vwapFastStateBuffer[pIndex]); + bool isVWapFastNeutural = IsVWAPNeutural(conditions.vwapFastStateBuffer[cIDX]); + bool isVWapFastNeuturalPrev = IsVWAPNeutural(conditions.vwapFastStateBuffer[pIDX]); // - bool isVWapMidBullish = IsVWAPBullish(conditions.vwapMidStateBuffer[cIndex]); - bool isVWapMidBullishPrev = IsVWAPBullish(conditions.vwapMidStateBuffer[pIndex]); + bool isVWapMidBullish = IsVWAPBullish(conditions.vwapMidStateBuffer[cIDX]); + bool isVWapMidBullishPrev = IsVWAPBullish(conditions.vwapMidStateBuffer[pIDX]); // - bool isVWapMidBearish = IsVWAPBearish(conditions.vwapMidStateBuffer[cIndex]); - bool isVWapMidBearishPrev = IsVWAPBearish(conditions.vwapMidStateBuffer[pIndex]); + bool isVWapMidBearish = IsVWAPBearish(conditions.vwapMidStateBuffer[cIDX]); + bool isVWapMidBearishPrev = IsVWAPBearish(conditions.vwapMidStateBuffer[pIDX]); // - bool isVWapMidNeutural = IsVWAPNeutural(conditions.vwapMidStateBuffer[cIndex]); - bool isVWapMidNeuturalPrev = IsVWAPNeutural(conditions.vwapMidStateBuffer[pIndex]); + bool isVWapMidNeutural = IsVWAPNeutural(conditions.vwapMidStateBuffer[cIDX]); + bool isVWapMidNeuturalPrev = IsVWAPNeutural(conditions.vwapMidStateBuffer[pIDX]); // - bool isVWapSlowBullish = IsVWAPBullish(conditions.vwapSlowStateBuffer[cIndex]); - bool isVWapSlowBullishPrev = IsVWAPBullish(conditions.vwapSlowStateBuffer[pIndex]); + bool isVWapSlowBullish = IsVWAPBullish(conditions.vwapSlowStateBuffer[cIDX]); + bool isVWapSlowBullishPrev = IsVWAPBullish(conditions.vwapSlowStateBuffer[pIDX]); // - bool isVWapSlowBearish = IsVWAPBearish(conditions.vwapSlowStateBuffer[cIndex]); - bool isVWapSlowBearishPrev = IsVWAPBearish(conditions.vwapSlowStateBuffer[pIndex]); + bool isVWapSlowBearish = IsVWAPBearish(conditions.vwapSlowStateBuffer[cIDX]); + bool isVWapSlowBearishPrev = IsVWAPBearish(conditions.vwapSlowStateBuffer[pIDX]); // - bool isVWapSlowNeutural = IsVWAPNeutural(conditions.vwapSlowStateBuffer[cIndex]); - bool isVWapSlowNeuturalPrev = IsVWAPNeutural(conditions.vwapSlowStateBuffer[pIndex]); + bool isVWapSlowNeutural = IsVWAPNeutural(conditions.vwapSlowStateBuffer[cIDX]); + bool isVWapSlowNeuturalPrev = IsVWAPNeutural(conditions.vwapSlowStateBuffer[pIDX]); // - bool isVWapFastOverMid = conditions.vwapFastBuffer[cIndex] > conditions.vwapMidBuffer[cIndex]; - bool isVWapFastOverMidPrev = conditions.vwapFastBuffer[pIndex] > conditions.vwapMidBuffer[pIndex]; + bool isVWapFastOverMid = conditions.vwapFastBuffer[cIDX] > conditions.vwapMidBuffer[cIDX]; + bool isVWapFastOverMidPrev = conditions.vwapFastBuffer[pIDX] > conditions.vwapMidBuffer[pIDX]; // - bool isVWapMidOverSlow = conditions.vwapMidBuffer[cIndex] > conditions.vwapSlowBuffer[cIndex]; - bool isVWapMidOverSlowPrev = conditions.vwapMidBuffer[pIndex] > conditions.vwapSlowBuffer[pIndex]; + bool isVWapMidOverSlow = conditions.vwapMidBuffer[cIDX] > conditions.vwapSlowBuffer[cIDX]; + bool isVWapMidOverSlowPrev = conditions.vwapMidBuffer[pIDX] > conditions.vwapSlowBuffer[pIDX]; // - bool isVWapFastUnderMid = conditions.vwapFastBuffer[cIndex] < conditions.vwapMidBuffer[cIndex]; - bool isVWapFastUnderMidPrev = conditions.vwapFastBuffer[pIndex] < conditions.vwapMidBuffer[pIndex]; + bool isVWapFastUnderMid = conditions.vwapFastBuffer[cIDX] < conditions.vwapMidBuffer[cIDX]; + bool isVWapFastUnderMidPrev = conditions.vwapFastBuffer[pIDX] < conditions.vwapMidBuffer[pIDX]; // - bool isVWapMidUnderSlow = conditions.vwapMidBuffer[cIndex] < conditions.vwapSlowBuffer[cIndex]; - bool isVWapMidUnderSlowPrev = conditions.vwapMidBuffer[pIndex] < conditions.vwapSlowBuffer[pIndex]; + bool isVWapMidUnderSlow = conditions.vwapMidBuffer[cIDX] < conditions.vwapSlowBuffer[cIDX]; + bool isVWapMidUnderSlowPrev = conditions.vwapMidBuffer[pIDX] < conditions.vwapSlowBuffer[pIDX]; // bool isVWapBullishState = isVWapFastBullish && @@ -3677,32 +3681,32 @@ class XCX121Helper : public XCBaseHelper // XFIBONACCI ... // - bool isOerFib1 = cBar.low > conditions.fl1Buffer[cIndex]; - bool isOerFib2 = cBar.low > conditions.fl2Buffer[cIndex]; - bool isOerFib3 = cBar.low > conditions.fl3Buffer[cIndex]; - bool isOerFib4 = cBar.low > conditions.fl4Buffer[cIndex]; - bool isOerFib5 = cBar.low > conditions.fl5Buffer[cIndex]; + bool isOerFib1 = cBar.low > conditions.fl1Buffer[cIDX]; + bool isOerFib2 = cBar.low > conditions.fl2Buffer[cIDX]; + bool isOerFib3 = cBar.low > conditions.fl3Buffer[cIDX]; + bool isOerFib4 = cBar.low > conditions.fl4Buffer[cIDX]; + bool isOerFib5 = cBar.low > conditions.fl5Buffer[cIDX]; // - bool isUnderFib1 = cBar.high < conditions.fl1Buffer[cIndex]; - bool isUnderFib2 = cBar.high < conditions.fl2Buffer[cIndex]; - bool isUnderFib3 = cBar.high < conditions.fl3Buffer[cIndex]; - bool isUnderFib4 = cBar.high < conditions.fl4Buffer[cIndex]; - bool isUnderFib5 = cBar.high < conditions.fl5Buffer[cIndex]; + bool isUnderFib1 = cBar.high < conditions.fl1Buffer[cIDX]; + bool isUnderFib2 = cBar.high < conditions.fl2Buffer[cIDX]; + bool isUnderFib3 = cBar.high < conditions.fl3Buffer[cIDX]; + bool isUnderFib4 = cBar.high < conditions.fl4Buffer[cIDX]; + bool isUnderFib5 = cBar.high < conditions.fl5Buffer[cIDX]; // - bool isCloseOerFib1 = cBar.close > conditions.fl1Buffer[cIndex]; - bool isCloseOerFib2 = cBar.close > conditions.fl2Buffer[cIndex]; - bool isCloseOerFib3 = cBar.close > conditions.fl3Buffer[cIndex]; - bool isCloseOerFib4 = cBar.close > conditions.fl4Buffer[cIndex]; - bool isCloseOerFib5 = cBar.close > conditions.fl5Buffer[cIndex]; + bool isCloseOerFib1 = cBar.close > conditions.fl1Buffer[cIDX]; + bool isCloseOerFib2 = cBar.close > conditions.fl2Buffer[cIDX]; + bool isCloseOerFib3 = cBar.close > conditions.fl3Buffer[cIDX]; + bool isCloseOerFib4 = cBar.close > conditions.fl4Buffer[cIDX]; + bool isCloseOerFib5 = cBar.close > conditions.fl5Buffer[cIDX]; // - bool isCloseUnderFib1 = cBar.close < conditions.fl1Buffer[cIndex]; - bool isCloseUnderFib2 = cBar.close < conditions.fl2Buffer[cIndex]; - bool isCloseUnderFib3 = cBar.close < conditions.fl3Buffer[cIndex]; - bool isCloseUnderFib4 = cBar.close < conditions.fl4Buffer[cIndex]; - bool isCloseUnderFib5 = cBar.close < conditions.fl5Buffer[cIndex]; + bool isCloseUnderFib1 = cBar.close < conditions.fl1Buffer[cIDX]; + bool isCloseUnderFib2 = cBar.close < conditions.fl2Buffer[cIDX]; + bool isCloseUnderFib3 = cBar.close < conditions.fl3Buffer[cIDX]; + bool isCloseUnderFib4 = cBar.close < conditions.fl4Buffer[cIDX]; + bool isCloseUnderFib5 = cBar.close < conditions.fl5Buffer[cIDX]; // diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index 43056bcb..2123c9ed 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -3943,6 +3943,163 @@ struct XConsolidationZone // }; +// +// Model Value Changed ... +struct XValueChange +{ + // + // Props ... + double before; // Before Change Value ... + double after; // After Change Value ... + datetime time; // Change Time ... + ENUM_X_DIRECTION dir; // Change Direction ... + + // + // Constructor ... + XValueChange() + { + Clean(); + } + + // + // Tools ... + + /** + * Initialize ... + * + * @param _before: Double, Value Before Change ... + * @param _after: Double, Value After Change ... + * @param _time: Datetime, Change Time ... + * @param _dir: ENUM_X_DIRECTION member, Specified Changed Direction ... + * + * @return ( bool ) + */ + bool Init( + double _before, // Before Change Value ... + double _after, // After Change Value ... + ENUM_X_DIRECTION _dir, // Change Direction ... + datetime _time = NULL // Change Time ... + ) + { + // + bool result = false; + + // + _time = NormalizeTime(_time); + + // + // Validate Inputs ... + result = + // + _after > 0 && + _before > 0 && + IsValid(_time) && + _after != _before && + HasDirection(_dir) + // + ; + if (!result) + { + return result; + } + + // + // Set Validated Values ... + dir = _dir; + time = _time; + after = _after; + before = _before; + + // + result = IsValid(); + + // + return result; + } + + /** + * Cleaning Up ... + */ + void Clean() + { + // + after = 0; + before = 0; + time = NULL; + dir = X_DIRECTION_NONE; + } + + /** + * Validate Model ... + * + * @return ( bool ) + */ + bool IsValid() + { + // + bool result = false; + + // + result = + // + after > 0 && + before > 0 && + IsValid(time) && + after != before && + HasDirection(dir) + // + ; + + // + return result; + } + + /** + * Fill Change Bar ... + * + * @param bar: XOHCL instance Reference, holds Change Bar ... + * @param _symbol: String, Specified Symbol ... + * @param _period: ENUM_TIMEFRAMES _period member, Specified Period ... + * + * @return ( bool ) + */ + bool FillBar( + XOHCL &bar, + string _symbol = NULL, + ENUM_TIMEFRAMES _period = NULL // + ) + { + // + bool result = false; + + // + bar.Clean(); + _symbol = NormalizeSymbol(_symbol); + _period = NormalizePeriod(_period); + + // + result = IsValid() && + IsValid(_symbol) && + IsValid(_period); + if (!result) + { + return result; + } + + // + result = bar.Init( + _symbol, + _period, + time // + ); + + // + return result; + } + + // +}; + // // Extensions ... @@ -4196,6 +4353,74 @@ string ToString(ENUM_XPOI_EVENTS value) return result; } +/** + * Add Value Change instance to Exists Collection if it's not Exists ... + * + * @param item: XValueChange instance Reference ... + * @param items: XValueChange instance Array Reference ... + * + * @return ( int ) + */ +int AddIfNotExists( + XValueChange &item, + XValueChange &items[] // +) +{ + // + int result = 0; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + bool canAdd = false; + int count = ArraySize(items); + if (!IsValidSize(count)) + { + canAdd = true; + } + else + { + // + XValueChange last; + bool hasItem = GetLastItem( + last, + items // + ); + if (!hasItem) + { + canAdd = true; + } + else + { + // + // Compare Last Item with Current ... + canAdd = item.time > last.time; + } + } + + // + // Add Item if Allowed ... + if (canAdd) + { + // + AddRef( + item, + items // + ); + } + + // + result = ArraySize(items); + + // + return result; +} + /** * Combine a Collection of States into dest ... * 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 98d1e991..908908f9 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -203,6 +203,40 @@ class XC121SMCCycleHelper : public XCBase return result; } + /** + * Retrieve Symbol ... + * + * @return ( string ) + */ + string GetSymbol() + { + // + string result = NULL; + + // + result = mX121Helper.GetSymbol(); + + // + return result; + } + + /** + * Retrieve TimeFrame (Period) ... + * + * @return ( ENUM_TIMEFRAMES ) + */ + ENUM_TIMEFRAMES GetPeriod() + { + // + ENUM_TIMEFRAMES result = NULL; + + // + result = mX121Helper.GetPeriod(); + + // + return result; + } + /** * Get Specified Bar ... * @@ -1474,40 +1508,6 @@ class XC121SMCCycleHelper : public XCBase ChartSetInteger(chartId, CHART_COLOR_VOLUME, mVolumesColor); } - /** - * Retrieve Symbol ... - * - * @return ( string ) - */ - string GetSymbol() - { - // - string result = NULL; - - // - result = mX121Helper.GetSymbol(); - - // - return result; - } - - /** - * Retrieve TimeFrame (Period) ... - * - * @return ( ENUM_TIMEFRAMES ) - */ - ENUM_TIMEFRAMES GetPeriod() - { - // - ENUM_TIMEFRAMES result = NULL; - - // - result = mX121Helper.GetPeriod(); - - // - return result; - } - // // Change Values Actions ... diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index 67616d00..de52818c 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -561,12 +561,9 @@ class XC121SMCExpert : public XCBaseExpert mTradeHandler.SetAlertPushAlerts(GetAlertPushAlerts()); mTradeHandler.SetAlertTerminalAlerts(GetAlertTerminalAlerts()); - // - // TODO: Make This Configurable Later ... - // mTradeHandler.MaxAllowedSLToPause(0); - mTradeHandler.DelayBarBetweenTwoSignal(3); + mTradeHandler.DelayBarBetweenTwoSignal(240); mTradeHandler.MaxAllowedSLReachedPauseDelay(HoursToSeconds(24)); // @@ -583,7 +580,6 @@ class XC121SMCExpert : public XCBaseExpert // mTradeHandler.UseForceMomentumsInProtection(true); - mTradeHandler.DelayBarBetweenTwoSignal(2); // // Configure Hedging ... diff --git a/X121SMCEA/Libraries/x-121.smc.lib.mq5 b/X121SMCEA/Libraries/x-121.smc.lib.mq5 index 79346722..b71adeee 100644 --- a/X121SMCEA/Libraries/x-121.smc.lib.mq5 +++ b/X121SMCEA/Libraries/x-121.smc.lib.mq5 @@ -30,25 +30,25 @@ // // Definitions ... +// const string X121SMCStrategyToken = "X121SMC"; -const string X121SMCPVToken = "X121SMCPV"; -const string X121SMCBOSToken = "X121SMCBOS"; -const string X121SMCSARToken = "X121SMCSAR"; -const string X121SMCCHOCHToken = "X121SMCCHOCH"; -const string X121SMCPULLBKToken = "X121SMCPULLBK"; +// +const string X121SMCSMPVToken = "X121SMCSMPV"; +const string X121SMCVWAPCToken = "X121SMCVWAPC"; +// +// X121 SMC Providers ... enum ENUM_X_121_SMC_PROVIDERS { // X_121_SMC_PROVIDER_NONE, - X_121_SMC_PROVIDER_PV, - X_121_SMC_PROVIDER_BOS, - X_121_SMC_PROVIDER_SAR, - X_121_SMC_PROVIDER_CHOCH, - X_121_SMC_PROVIDER_PULLBK, + X_121_SMC_PROVIDER_SMPV, + X_121_SMC_PROVIDER_VWAPC, }; +// +// Pivot Types ... enum ENUM_XPV_PIVOTS { XPV_NONE, @@ -56,6 +56,8 @@ enum ENUM_XPV_PIVOTS XPV_VALE, }; +// +// Model a Pivot structure ... struct XPVPivot { // @@ -634,11 +636,12 @@ struct X121SMCStrategyConditions // double sl; + double tp; string provider; + ENUM_X_DIRECTION signalDir; ENUM_X_DIRECTION marketStructureDir; // - // void X121SMCStrategyConditions() @@ -661,7 +664,9 @@ struct X121SMCStrategyConditions // sl = 0; + tp = 0; provider = NULL; + signalDir = X_DIRECTION_NONE; marketStructureDir = X_DIRECTION_NONE; // @@ -692,6 +697,64 @@ struct X121SMCStrategyConditions return result; } + /** + * Check Conditions Has Valid Bullish Signal ... + * + * @return ( bool ) + */ + bool HasBullishSignal() + { + // + bool result = false; + + // + result = + (sl > 0 || + tp > 0) && + IsValid() && + HasDirection(signalDir); + if (!result) + { + return result; + } + + // + result = + IsBullish(signalDir); + + // + return result; + } + + /** + * Check Conditions Has Valid Bearish Signal ... + * + * @return ( bool ) + */ + bool HasBearishSignal() + { + // + bool result = false; + + // + result = + (sl > 0 || + tp > 0) && + IsValid() && + HasDirection(signalDir); + if (!result) + { + return result; + } + + // + result = + IsBearish(signalDir); + + // + return result; + } + // // Reporter Functions ... @@ -1769,28 +1832,13 @@ string ToString(ENUM_X_121_SMC_PROVIDERS value) switch (value) { // - case X_121_SMC_PROVIDER_PV: - result = X121SMCPVToken; + case X_121_SMC_PROVIDER_SMPV: + result = X121SMCSMPVToken; break; // - case X_121_SMC_PROVIDER_BOS: - result = X121SMCBOSToken; - break; - - // - case X_121_SMC_PROVIDER_SAR: - result = X121SMCSARToken; - break; - - // - case X_121_SMC_PROVIDER_CHOCH: - result = X121SMCCHOCHToken; - break; - - // - case X_121_SMC_PROVIDER_PULLBK: - result = X121SMCPULLBKToken; + case X_121_SMC_PROVIDER_VWAPC: + result = X121SMCVWAPCToken; break; } @@ -1817,208 +1865,14 @@ ENUM_X_121_SMC_PROVIDERS ParseProvider(string value) } // - if (Contains(X121SMCPVToken, value)) + if (Contains(X121SMCSMPVToken, value)) { - result = X_121_SMC_PROVIDER_PV; + result = X_121_SMC_PROVIDER_SMPV; } - else if (Contains(X121SMCBOSToken, value)) + else if (Contains(X121SMCVWAPCToken, value)) { - result = X_121_SMC_PROVIDER_BOS; + result = X_121_SMC_PROVIDER_VWAPC; } - else if (Contains(X121SMCSARToken, value)) - { - result = X_121_SMC_PROVIDER_SAR; - } - else if (Contains(X121SMCCHOCHToken, value)) - { - result = X_121_SMC_PROVIDER_CHOCH; - } - else if (Contains(X121SMCPULLBKToken, value)) - { - result = X_121_SMC_PROVIDER_PULLBK; - } - - // - return result; -} - -// -// Model Value Changed ... -struct XValueChange -{ - // - // Props ... - double before; // Before Change Value ... - double after; // After Change Value ... - datetime time; // Change Time ... - ENUM_X_DIRECTION dir; // Change Direction ... - - // - // Constructor ... - XValueChange() - { - Clean(); - } - - // - // Tools ... - - /** - * Initialize ... - * - * @param _before: Double, Value Before Change ... - * @param _after: Double, Value After Change ... - * @param _time: Datetime, Change Time ... - * @param _dir: ENUM_X_DIRECTION member, Specified Changed Direction ... - * - * @return ( bool ) - */ - bool Init( - double _before, // Before Change Value ... - double _after, // After Change Value ... - ENUM_X_DIRECTION _dir, // Change Direction ... - datetime _time = NULL // Change Time ... - ) - { - // - bool result = false; - - // - _time = NormalizeTime(_time); - - // - // Validate Inputs ... - result = - // - _after > 0 && - _before > 0 && - IsValid(_time) && - _after != _before && - HasDirection(_dir) - // - ; - if (!result) - { - return result; - } - - // - // Set Validated Values ... - dir = _dir; - time = _time; - after = _after; - before = _before; - - // - result = IsValid(); - - // - return result; - } - - /** - * Cleaning Up ... - */ - void Clean() - { - // - after = 0; - before = 0; - time = NULL; - dir = X_DIRECTION_NONE; - } - - /** - * Validate Model ... - * - * @return ( bool ) - */ - bool IsValid() - { - // - bool result = false; - - // - result = - // - after > 0 && - before > 0 && - IsValid(time) && - after != before && - HasDirection(dir) - // - ; - - // - return result; - } - - // -}; - -/** - * Add Value Change instance to Exists Collection if it's not Exists ... - * - * @param item: XValueChange instance Reference ... - * @param items: XValueChange instance Array Reference ... - * - * @return ( int ) - */ -int AddIfNotExists( - XValueChange &item, - XValueChange &items[] // -) -{ - // - int result = 0; - - // - result = item.IsValid(); - if (!result) - { - return result; - } - - // - bool canAdd = false; - int count = ArraySize(items); - if (!IsValidSize(count)) - { - canAdd = true; - } - else - { - // - XValueChange last; - bool hasItem = GetLastItem( - last, - items // - ); - if (!hasItem) - { - canAdd = true; - } - else - { - // - // Compare Last Item with Current ... - canAdd = item.time > last.time; - } - } - - // - // Add Item if Allowed ... - if (canAdd) - { - // - AddRef( - item, - items // - ); - } - - // - result = ArraySize(items); // return result; diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index d111dd05..2bc150a0 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -148,7 +148,15 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // // Detect Signal Conditions ... - result = DetectConditions(conditions); + result = DetectSamePeaksAndValesSignal(conditions); + if (!result) + { + // + // TODO: Enable this ... + // result = DetectVWAPSignal(conditions); + } + + // if (!result) { // @@ -164,14 +172,14 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // hasLong = // - IsBullish(conditions.marketStructureDir) + IsBullish(conditions.signalDir) // ; // hasShort = // - IsBearish(conditions.marketStructureDir) + IsBearish(conditions.signalDir) // ; @@ -435,14 +443,17 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + // + // Signalling Functions ... + /** - * Detect and Parse Market Conditions ... + * Detect and Parse Market Conditions for Signalling ... * * @param conditions: X121SMCStrategyConditions instance Reference ... * * @return ( bool ) */ - bool DetectConditions( + bool DetectSamePeaksAndValesSignal( X121SMCStrategyConditions &conditions // ) { @@ -453,6 +464,10 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod(); + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_SMPV; + string providerStr = ToString(provider); + // int zIndex = 0; int cIndex = zIndex + 1; @@ -511,9 +526,86 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy hasSamePeaks || hasSameVales; if (!result) + { + return result; + } + + // + // Check Peaks And Vales Order ... + bool hasPeakBreak = false; + bool hasValeBreak = false; + + // + // Retrieve Last Sar Change ... + XOHCL cSarChangeBar; + XOHCL pSarChangeBar; + XValueChange cSarChange; // Current Sar Change (IsDirect) ... + XValueChange pSarChange; // Prev Sar Change (Direct) ... + XValueChange sarChanges[]; + int sarChangesCount = mTriggerCycleHelper + .FillSarChanges(sarChanges); + if (IsValidSize(sarChangesCount) && + sarChangesCount > 2) { // - conditions.Clean(); + cSarChange = sarChanges[sarChangesCount - 1]; + pSarChange = sarChanges[sarChangesCount - 2]; + + // + result = cSarChange.FillBar( + cSarChangeBar, + symbol, + period // + ); + if (!result) + { + return result; + } + + // + result = pSarChange.FillBar( + pSarChangeBar, + symbol, + period // + ); + if (!result) + { + return result; + } + + // + int start = cSarChangeBar.Index(); + int end = pSarChangeBar.Index(); + for (int i = start; i < end; i++) + { + // + ENUM_X_CYCLE_EVENTS iEvents[]; + X121SMCCycleConditions iConditions; + result = mTriggerCycleHelper.GetConditions( + iEvents, + iConditions, + i // + ); + if (!result) + { + continue; + } + + // + hasPeakBreak = + iConditions.x121Conditions.isNewPeakOverLast; + hasValeBreak = + iConditions.x121Conditions.isNewValeUnderLast; + result = hasPeakBreak || + hasValeBreak; + if (result) + { + break; + } + } + } + if (!result) + { return result; } @@ -521,13 +613,12 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // Check Sar State ... ENUM_X_DIRECTION sarDir; result = DetectSarState( + provider, sarDir, conditions // ); if (!result) { - // - conditions.Clean(); return result; } @@ -535,38 +626,167 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // Check VWAP State ... ENUM_X_DIRECTION vwapDir; result = DetectVWapState( + provider, vwapDir, conditions // ); if (!result) { - // - conditions.Clean(); return result; } + // + bool isBullish = + // + hasSamePeaks && + hasPeakBreak && + IsBullish(sarDir) && + IsBullish(vwapDir) + // + ; + + // + bool isBearish = + // + hasSameVales && + hasValeBreak && + IsBearish(sarDir) && + IsBearish(vwapDir) + // + ; + + // + result = + isBullish || + isBearish; + if (!result) + { + return result; + } + + // + // Set SL, Provider and Direction ... + conditions.signalDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + conditions.provider = providerStr; + + // + // Detect SL and TP ... + conditions.sl = + isBullish + ? pSarChangeBar.low + : pSarChangeBar.high; + + // + return result; + } + + /** + * Detect and Parse Market Conditions for Signalling ... + * + * @param conditions: X121SMCStrategyConditions instance Reference ... + * + * @return ( bool ) + */ + bool DetectVWAPSignal( + X121SMCStrategyConditions &conditions // + ) + { + // + bool result = false; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = GetPeriod(); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + XOHCL zBar; + result = zBar.Init( + symbol, + period, + zIndex // + ); + if (!result) + { + return result; + } + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + cIndex // + ); + if (!result) + { + return result; + } + + // + string msg = NULL; + + // + double bid = GetBid(symbol); + datetime cTime = TimeCurrent(); + + // + ENUM_X_121_SMC_PROVIDERS provider = X_121_SMC_PROVIDER_VWAPC; + string providerStr = ToString(provider); + // // Check Candlestic State ... ENUM_X_DIRECTION candlesticDir; result = DetectCandlestic( + provider, candlesticDir, conditions // ); if (!result) { - // - conditions.Clean(); return result; } // - Print("Has Same Peaks or Vales ..."); + // Check Sar State ... + ENUM_X_DIRECTION sarDir; + result = DetectSarState( + provider, + sarDir, + conditions // + ); + if (!result) + { + return result; + } + + // + // Check VWAP State ... + ENUM_X_DIRECTION vwapDir; + result = DetectVWapState( + provider, + vwapDir, + conditions // + ); + if (!result) + { + return result; + } + + // + Print("VWap Signal ..."); // if (!result) { - // - conditions.Clean(); return result; } @@ -574,6 +794,9 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + // + // Helper Functions ... + /** * Detect Where Cycles has Same Peaks ... * @@ -753,12 +976,14 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy /** * Detect Sar State for Signalling ... * + * @param forProvider: ENUM_X_121_SMC_PROVIDERS member ... * @param dir: ENUM_X_DIRECTION member Reference ... * @param conditions: X121SMCStrategyConditions instance, Reference ... * * @return ( bool ) */ bool DetectSarState( + ENUM_X_121_SMC_PROVIDERS forProvider, ENUM_X_DIRECTION &dir, X121SMCStrategyConditions &conditions // ) @@ -770,44 +995,57 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy dir = X_DIRECTION_NONE; // - bool isBullish = - // - // Check One of Verification or Consolidation Cycles Must be Sar Bullish ... - (conditions.verificationConditions.x121Conditions.isSarBullish || - conditions.consolidationConditions.x121Conditions.isSarBullish) - // - && - // - // Decision and Analyse Cycles Must be Bullish ... - (conditions.decisionConditions.x121Conditions.isSarBullish && - conditions.analyseConditions.x121Conditions.isSarBullish) - // - && - // - // Trigger State Must be Bearish ... - conditions.triggerConditions.x121Conditions.isSarBearish - // - ; + bool isBullish = false; + bool isBearish = false; // - bool isBearish = + if (forProvider == X_121_SMC_PROVIDER_SMPV) + { // - // Check One of Verification or Consolidation Cycles Must be Sar Bearish ... - (conditions.verificationConditions.x121Conditions.isSarBearish || - conditions.consolidationConditions.x121Conditions.isSarBearish) + isBullish = + // + // Check One of Verification or Consolidation Cycles Must be Sar Bullish ... + (conditions.verificationConditions.x121Conditions.isSarBullish || + conditions.consolidationConditions.x121Conditions.isSarBullish) + // + && + // + // Decision and Analyse Cycles Must be Bullish ... + (conditions.decisionConditions.x121Conditions.isSarBullish && + conditions.analyseConditions.x121Conditions.isSarBullish) + // + && + // + // Trigger State Must be Bearish ... + conditions.triggerConditions.x121Conditions.isSarBearish + // + ; + // - && - // - // Decision and Analyse Cycles Must be Bearish ... - (conditions.decisionConditions.x121Conditions.isSarBearish && - conditions.analyseConditions.x121Conditions.isSarBearish) - // - && - // - // Trigger State Must be Bullish ... - conditions.triggerConditions.x121Conditions.isSarBullish - // - ; + isBearish = + // + // Check One of Verification or Consolidation Cycles Must be Sar Bearish ... + (conditions.verificationConditions.x121Conditions.isSarBearish || + conditions.consolidationConditions.x121Conditions.isSarBearish) + // + && + // + // Decision and Analyse Cycles Must be Bearish ... + (conditions.decisionConditions.x121Conditions.isSarBearish && + conditions.analyseConditions.x121Conditions.isSarBearish) + // + && + // + // Trigger State Must be Bullish ... + conditions.triggerConditions.x121Conditions.isSarBullish + // + ; + } + + // + if (forProvider == X_121_SMC_PROVIDER_VWAPC) + { + } // result = isBullish || @@ -830,12 +1068,14 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy /** * Detect Sar State for Signalling ... * + * @param forProvider: ENUM_X_121_SMC_PROVIDERS member ... * @param dir: ENUM_X_DIRECTION member Reference ... * @param conditions: X121SMCStrategyConditions instance, Reference ... * * @return ( bool ) */ bool DetectVWapState( + ENUM_X_121_SMC_PROVIDERS forProvider, ENUM_X_DIRECTION &dir, X121SMCStrategyConditions &conditions // ) @@ -847,54 +1087,67 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy dir = X_DIRECTION_NONE; // - bool isBullish = - // - // Trigger, Decision and Analyse Cycles Must be in Direction Order and State ... - // - // Orders ... - (conditions.triggerConditions.x121Conditions.isVWapBullishOrdered && - conditions.decisionConditions.x121Conditions.isVWapBullishOrdered && - conditions.analyseConditions.x121Conditions.isVWapBullishOrdered) - // - && - // - // State ... - (conditions.triggerConditions.x121Conditions.isVWapBullishState && - conditions.decisionConditions.x121Conditions.isVWapBullishState && - conditions.analyseConditions.x121Conditions.isVWapBullishState) - // - && - // - // One of Verification and Consolidation must Be in Direction State ... - (conditions.verificationConditions.x121Conditions.isVWapBullishState || - conditions.consolidationConditions.x121Conditions.isVWapBullishState) - // - ; + bool isBullish = false; + bool isBearish = false; // - bool isBearish = + if (forProvider == X_121_SMC_PROVIDER_SMPV) + { // - // Trigger, Decision and Analyse Cycles Must be in Direction Order and State ... + isBullish = + // + // Trigger, Decision and Analyse Cycles Must be in Direction Order and State ... + // + // Orders ... + (conditions.triggerConditions.x121Conditions.isVWapBullishOrdered && + conditions.decisionConditions.x121Conditions.isVWapBullishOrdered && + conditions.analyseConditions.x121Conditions.isVWapBullishOrdered) + // + && + // + // State ... + (conditions.triggerConditions.x121Conditions.isVWapBullishState && + conditions.decisionConditions.x121Conditions.isVWapBullishState && + conditions.analyseConditions.x121Conditions.isVWapBullishState) + // + && + // + // One of Verification and Consolidation must Be in Direction State ... + (conditions.verificationConditions.x121Conditions.isVWapBullishState || + conditions.consolidationConditions.x121Conditions.isVWapBullishState) + // + ; + // - // Orders ... - (conditions.triggerConditions.x121Conditions.isVWapBearishOrdered && - conditions.decisionConditions.x121Conditions.isVWapBearishOrdered && - conditions.analyseConditions.x121Conditions.isVWapBearishOrdered) - // - && - // - // State ... - (conditions.triggerConditions.x121Conditions.isVWapBearishState && - conditions.decisionConditions.x121Conditions.isVWapBearishState && - conditions.analyseConditions.x121Conditions.isVWapBearishState) - // - && - // - // One of Verification and Consolidation must Be in Direction State ... - (conditions.verificationConditions.x121Conditions.isVWapBearishState || - conditions.consolidationConditions.x121Conditions.isVWapBearishState) - // - ; + isBearish = + // + // Trigger, Decision and Analyse Cycles Must be in Direction Order and State ... + // + // Orders ... + (conditions.triggerConditions.x121Conditions.isVWapBearishOrdered && + conditions.decisionConditions.x121Conditions.isVWapBearishOrdered && + conditions.analyseConditions.x121Conditions.isVWapBearishOrdered) + // + && + // + // State ... + (conditions.triggerConditions.x121Conditions.isVWapBearishState && + conditions.decisionConditions.x121Conditions.isVWapBearishState && + conditions.analyseConditions.x121Conditions.isVWapBearishState) + // + && + // + // One of Verification and Consolidation must Be in Direction State ... + (conditions.verificationConditions.x121Conditions.isVWapBearishState || + conditions.consolidationConditions.x121Conditions.isVWapBearishState) + // + ; + } + + // + if (forProvider == X_121_SMC_PROVIDER_VWAPC) + { + } // result = isBullish || @@ -914,7 +1167,17 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + /** + * Detect Candlestic Patters for Signalling ... + * + * @param forProvider: ENUM_X_121_SMC_PROVIDERS member ... + * @param dir: ENUM_X_DIRECTION member Reference ... + * @param conditions: X121SMCStrategyConditions instance, Reference ... + * + * @return ( bool ) + */ bool DetectCandlestic( + ENUM_X_121_SMC_PROVIDERS forProvider, ENUM_X_DIRECTION &dir, X121SMCStrategyConditions &conditions // ) @@ -925,14 +1188,18 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy // dir = X_DIRECTION_NONE; - // - string symbol = GetSymbol(); - ENUM_TIMEFRAMES period = GetPeriod(); - // int cIndex = 1; int pIndex = cIndex + 1; + // + // Select Specified Cycle Helper ... + XC121SMCCycleHelper *cycleHelper = mTriggerCycleHelper; + + // + string symbol = GetSymbol(); + ENUM_TIMEFRAMES period = cycleHelper.GetPeriod(); + // XOHCL cBar; result = cBar.Init( @@ -945,6 +1212,38 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + // + // Momentum Bar ... + ENUM_X_DIRECTION cBarMomentumDir; + bool isCBarMomentum = cycleHelper.mBarAnalyser.IsMomentumBar( + cBar, + cBarMomentumDir // + ); + + // + // Rejection Bar ... + ENUM_X_DIRECTION cBarRejectionDir; + bool isCBarRejection = cycleHelper.mBarAnalyser.IsRejectionBar( + cBar, + cBarRejectionDir // + ); + + // + // Engulf Bar ... + ENUM_X_DIRECTION cBarEngulfDir; + bool isCBarEngulf = cycleHelper.mBarAnalyser.IsEngulfBar( + cBar, + cBarEngulfDir // + ); + + // + // Pin Bar ... + ENUM_X_DIRECTION cBarPinDir; + bool isCBarPin = cycleHelper.mBarAnalyser.IsPinBar( + cBar, + cBarPinDir // + ); + // XOHCL pBar; result = pBar.Init( @@ -958,40 +1257,300 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy } // - ENUM_X_DIRECTION cBarMomentumDir; - bool isCBarMomentum = mTriggerCycleHelper.mBarAnalyser. - IsMomentumBar( - cBar, - cBarMomentumDir // + // Momentum Bar ... + ENUM_X_DIRECTION pBarMomentumDir; + bool isPBarMomentum = cycleHelper.mBarAnalyser.IsMomentumBar( + pBar, + pBarMomentumDir // ); // - ENUM_X_DIRECTION cBarRejectionDir; - bool isCBarRejection = mTriggerCycleHelper.mBarAnalyser. - IsRejectionBar( - cBar, - cBarRejectionDir // + // Rejection Bar ... + ENUM_X_DIRECTION pBarRejectionDir; + bool isPBarRejection = cycleHelper.mBarAnalyser.IsRejectionBar( + pBar, + pBarRejectionDir // ); // - bool isBullish = - // - // pBar is Rejection and cBar is Momentum ... - // pBar is Momentum and cBar is Rejection ... - // cBar is Momentum and Rejection ... - // - // - ; + // Engulf Bar ... + ENUM_X_DIRECTION pBarEngulfDir; + bool isPBarEngulf = cycleHelper.mBarAnalyser.IsEngulfBar( + pBar, + pBarEngulfDir // + ); // - bool isBearish = + // Pin Bar ... + ENUM_X_DIRECTION pBarPinDir; + bool isPBarPin = cycleHelper.mBarAnalyser.IsPinBar( + pBar, + pBarPinDir // + ); + + // + bool isBullish = false; + bool isBearish = false; + + // + if (forProvider == X_121_SMC_PROVIDER_VWAPC) + { // - // pBar is Rejection and cBar is Momentum ... - // pBar is Momentum and cBar is Rejection ... - // cBar is Momentum and Rejection ... + isBullish = + // + // pBar is Pin and cBar is Momentum or Rejection or Engulf + ( + // + (isPBarPin && + IsBullish(pBarPinDir) && + ( + // + (isCBarMomentum && + IsBullish(cBarMomentumDir)) + // + || + // + (isCBarRejection && + IsBullish(cBarRejectionDir)) + // + || + // + (isCBarEngulf && + IsBullish(cBarEngulfDir)) + // + ) + // + ) + // + || + // + // pBar is Engulf and cBar is Momentum or Rejection or Pin ... + (isPBarEngulf && + IsBullish(pBarEngulfDir) && + ( + // + (isCBarMomentum && + IsBullish(cBarMomentumDir)) + // + || + // + (isCBarRejection && + IsBullish(cBarRejectionDir)) + // + || + // + (isCBarPin && + IsBullish(cBarPinDir)) + // + ) + // + ) + // + || + // + // pBar is Rejection and cBar is Momentum or Engulf or Pin ... + (isPBarRejection && + IsBullish(pBarRejectionDir) && + ( + // + (isCBarMomentum && + IsBullish(cBarMomentumDir)) + // + || + // + (isCBarEngulf && + IsBullish(cBarEngulfDir)) + // + || + // + (isCBarPin && + IsBullish(cBarPinDir)) + // + ) + // + ) + // + || + // + // pBar is Momentum and cBar is Rejection or Engulf or Pin ... + (isPBarMomentum && + IsBullish(pBarMomentumDir) && + ( + // + (isCBarRejection && + IsBullish(cBarRejectionDir)) + // + || + // + (isCBarEngulf && + IsBullish(cBarEngulfDir)) + // + || + // + (isCBarPin && + IsBullish(cBarPinDir)) + // + ) + // + ) + // + || + // + // cBar is Pin and Momentum and Rejection and Engulf ... + ( + // + (isCBarPin && + IsBullish(cBarPinDir)) + // + && + // + (isCBarMomentum && + IsBullish(cBarMomentumDir)) + // + && + // + (isCBarRejection && + IsBullish(cBarRejectionDir)) + // + && + // + (isCBarEngulf && + IsBullish(cBarEngulfDir)) + // + ) + // + ) + // + ; + // - // - ; + isBearish = + // + // pBar is Pin and cBar is Momentum or Rejection or Engulf + ( + // + (isPBarPin && + IsBearish(pBarPinDir) && + ( + // + (isCBarMomentum && + IsBearish(cBarMomentumDir)) + // + || + // + (isCBarRejection && + IsBearish(cBarRejectionDir)) + // + || + // + (isCBarEngulf && + IsBearish(cBarEngulfDir)) + // + ) + // + ) + // + || + // + // pBar is Engulf and cBar is Momentum or Rejection or Pin ... + (isPBarEngulf && + IsBearish(pBarEngulfDir) && + ( + // + (isCBarMomentum && + IsBearish(cBarMomentumDir)) + // + || + // + (isCBarRejection && + IsBearish(cBarRejectionDir)) + // + || + // + (isCBarPin && + IsBearish(cBarPinDir)) + // + ) + // + ) + // + || + // + // pBar is Rejection and cBar is Momentum or Engulf or Pin ... + (isPBarRejection && + IsBearish(pBarRejectionDir) && + ( + // + (isCBarMomentum && + IsBearish(cBarMomentumDir)) + // + || + // + (isCBarEngulf && + IsBearish(cBarEngulfDir)) + // + || + // + (isCBarPin && + IsBearish(cBarPinDir)) + // + ) + // + ) + // + || + // + // pBar is Momentum and cBar is Rejection or Engulf or Pin ... + (isPBarMomentum && + IsBearish(pBarMomentumDir) && + ( + // + (isCBarRejection && + IsBearish(cBarRejectionDir)) + // + || + // + (isCBarEngulf && + IsBearish(cBarEngulfDir)) + // + || + // + (isCBarPin && + IsBearish(cBarPinDir)) + // + ) + // + ) + // + || + // + // cBar is Pin and Momentum and Rejection and Engulf ... + ( + // + (isCBarPin && + IsBearish(cBarPinDir)) + // + && + // + (isCBarMomentum && + IsBearish(cBarMomentumDir)) + // + && + // + (isCBarRejection && + IsBearish(cBarRejectionDir)) + // + && + // + (isCBarEngulf && + IsBearish(cBarEngulfDir)) + // + ) + // + ) + // + ; + } // result = isBullish ||