/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XCX121SMCTestStrategy // Description: provides all based classes for use ... // // // 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 "../../Helpers/x-saherelm.xchvwap.helper.mq5" #include "../Classes/x-121.smc.base.strategy.class.mq5" // // Helper(s) ... // // XStrategy Class Implementation(s) ... class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy { // // Public ... public: // // // Constructor(s) ... void XCX121SMCTestStrategy( // // Base ... string _symbol, // Trading Symbol ENUM_TIMEFRAMES _period // Trading TimeFrame ) : XCX121SMCBaseStrategy(_symbol, _period) { InitialHelpers(); } // // Overrides Actions ... // // Check Conditions For Signal ... bool HasSignal( XSignal &signal, X121SMCStrategyConditions &conditions // ) override { // bool result = false; // signal.Clean(); conditions.Clean(); // int pushers = 0; // double sl = 0; double tp = 0; double risk = 0; double entry = 0; double reward = 0; double r2r = R2R(); double volume = Volume(); ENUM_POSITION_TYPE type = POSITION_TYPE_BUY; ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; // bool hasLong = false; bool hasShort = false; // // Start Calculations ... // string _symbol = GetSymbol(); ENUM_TIMEFRAMES _period = GetPeriod(); // double points = GetPoints(_symbol); // int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 1; int ppIndex = pIndex + 1; // // Retrieve Bars ... // // Zero Bar ... XOHCL zBar; result = zBar.Init( _symbol, _period, zIndex // ); if (!result) { return result; } // // Last Bar ... XOHCL cBar; result = cBar.Init( _symbol, _period, cIndex // ); if (!result) { return result; } // // Previous Bar ... XOHCL pBar; result = pBar.Init( _symbol, _period, pIndex // ); if (!result) { return result; } // bool isSpreadPassed = IsSpreadPass(); result = isSpreadPassed; if (!result) { return result; } // // Try to Implement SMC Based Conditions ... // ENUM_X_POSITION_TYPES breakeType; bool isBreaked = IsRangeBreaked(breakeType); if (isBreaked) { // Print("Breaked"); } // // 1- First Step is Find a Supply and Demand Zone ... // - [] this Zone must be Fresh ... // - [] contains Engulfing ... // - [] has Order Block ... // - [] has FVG ... bool isDetected = DetectRange(); result = isDetected; if (!result) { return result; } // ClearDraws(); DrawRange(); // result = hasLong || hasShort; // // Rmove Signal Condition ... if (result) { // signal.sl = sl; signal.tp = tp; signal.type = type; signal.mode = mode; signal.entry = entry; signal.volume = volume; signal.symbol = _symbol; signal.pushers = pushers; signal.provider = GetTag(); signal.time = TimeCurrent(); signal.period = _5MState.period; // result = PrepareSignal(signal); // hasLong = false; hasShort = false; } // return result; } /** * Detect Valid Market Conditions ... * * @param conditions: X121SMCStrategyConditions instance ... */ bool DetecConditions(X121SMCStrategyConditions &conditions) override { // bool result = false; // // Prepare Conditions ... // datetime time = TimeCurrent(); // conditions.Clean(); conditions.time = time; conditions.symbol = GetSymbol(); conditions.period = GetPeriod(); // // // bool d1HasBullishTrend = HasBullishTrend(d1State); // bool d1HasBearishTrend = HasBearishTrend(d1State); // // // bool h4HasBullishTrend = HasBullishTrend(h4State); // bool h4HasBearishTrend = HasBearishTrend(h4State); // // // bool m15HasBullishTrend = HasBullishTrend(_15MState); // bool m15HasBearishTrend = HasBearishTrend(_15MState); // // // bool m5HasBullishTrend = HasBullishTrend(m5State); // bool m5HasBearishTrend = HasBearishTrend(m5State); // // // bool m1HasBullishTrend = HasBullishTrend(m1State); // bool m1HasBearishTrend = HasBearishTrend(m1State); // // // bool isBullishTrendValid = h4HasBullishTrend && // m15HasBullishTrend && // m1HasBullishTrend; // if (isBullishTrendValid) // { // Print("isBullishTrendValid"); // } // // // bool isBearishTrendValid = h4HasBearishTrend && // m15HasBearishTrend && // m1HasBearishTrend; // if (isBearishTrendValid) // { // Print("isBearishTrendValid"); // } // int supplyZonesCount = ArraySize(_15MState.supplyZones); int demandZonesCount = ArraySize(_15MState.demandZones); result = IsValidSize(demandZonesCount) || IsValidSize(supplyZonesCount); if (!result) { return result; } // bool checkDemands = true; bool checkSupplies = true; // // Demand Zone ... if (checkDemands) { // for (int i = 0; i < demandZonesCount; i++) { // // Demand Zone ... XZone iDemandZone = _15MState.demandZones[i]; iDemandZone.to = time; conditions.demandZone = iDemandZone; conditions.bullishOrderBlock.Clean(); conditions.bullishFVG.Clean(); // // Bullish Order Block ... int obCount = ArraySize(_15MState.bullishOrderBlocks); if (IsValidSize(obCount)) { // for (int j = 0; j < obCount; j++) { // XZone jZone = _15MState.bullishOrderBlocks[j]; // bool isBreaked = IsBreakeUpper( jZone, iDemandZone // ); if (isBreaked) { // jZone.to = time; conditions.bullishOrderBlock = jZone; // break; } } } // // Validate Order Block ... bool isValidOrderBlock = conditions.bullishOrderBlock.IsValid(); if (!isValidOrderBlock) { continue; } // // Bullish FVG ... int fairValueGapsCount = ArraySize(_15MState.bullishFVGs); if (IsValidSize(fairValueGapsCount)) { // for (int j = 0; j < fairValueGapsCount; j++) { // XZone jZone = _15MState.bullishFVGs[j]; // bool isBreaked = IsBreakeUpper( jZone, conditions.bullishOrderBlock // ); if (isBreaked) { // jZone.to = time; conditions.bullishFVG = jZone; // break; } } } // // Validate FVG ... bool isValidFVG = conditions.bullishFVG.IsValid(); if (!isValidFVG) { continue; } // // Detect Inside Demand POIs ... // // Order Blocks ... // CState ... int orderBlocksCount = ArraySize(_CombineState.bullishOrderBlocks); if (IsValidSize(orderBlocksCount)) { // for (int j = 0; j < orderBlocksCount; j++) { // XZone jZone = _CombineState.bullishOrderBlocks[j]; // bool isInside = IsInside( jZone, iDemandZone, X_ZONE_LOWER_EDGE, true // ); if (isInside) { // jZone.to = TimeCurrent(); // AddIfNotExists( jZone, conditions.bullishOrderBlocks // ); } } } // // Support Zones ... // CState ... int supportsCount = ArraySize(_CombineState.supportZones); if (IsValidSize(supportsCount)) { // for (int j = 0; j < supportsCount; j++) { // XOHCL jBar = _CombineState.supportZones[j]; // bool isInside = IsInside( jBar, iDemandZone, X_ZONE_LOWER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.supports // ); } } } // // Fair Value Gaps ... // CState ... int fvgsCount = ArraySize(_CombineState.bullishFVGs); if (IsValidSize(fvgsCount)) { // for (int j = 0; j < fvgsCount; j++) { // XZone jFVG = _CombineState.bullishFVGs[j]; // bool isInside = IsInside( jFVG, iDemandZone, X_ZONE_LOWER_EDGE, true // ); if (isInside) { // jFVG.to = TimeCurrent(); // AddIfNotExists( jFVG, conditions.bullishFVGs // ); } } } // // Swings ... // CState ... int swingsCount = ArraySize(_CombineState.swingLows); if (IsValidSize(swingsCount)) { // for (int j = 0; j < swingsCount; j++) { // XOHCL jBar = _CombineState.swingLows[j]; // bool isInside = IsInside( jBar, iDemandZone, X_ZONE_LOWER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.swingLows // ); } } } // // Momentum Bars ... // CState ... int momentumBarsCount = ArraySize(_CombineState.momentumBars); if (IsValidSize(momentumBarsCount)) { // for (int j = 0; j < momentumBarsCount; j++) { // XOHCL jBar = _CombineState.momentumBars[j]; // bool isInside = jBar.IsBullish() && jBar.time > iDemandZone.from && IsInside( jBar, iDemandZone, X_ZONE_LOWER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.bullishMomentumBars // ); } } } // // Rejection Bars ... // CState ... int rejectionBarsCount = ArraySize(_CombineState.rejectionBars); if (IsValidSize(rejectionBarsCount)) { // for (int j = 0; j < rejectionBarsCount; j++) { // XOHCL jBar = _CombineState.rejectionBars[j]; // bool isInside = jBar.GetLowShadow() > jBar.GetHighShadow() && jBar.time > iDemandZone.from && IsInside( jBar, iDemandZone, X_ZONE_LOWER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.bullishRejectionBars // ); } } } // bool hasValidDemandZone = conditions.ValidateDemand(); if (!hasValidDemandZone) { conditions.CleanDemand(); } else { break; } } } // // Supply Zone ... if (checkSupplies) { // for (int i = 0; i < supplyZonesCount; i++) { // // Supply Zone ... XZone iSupplyZone = _15MState.supplyZones[i]; iSupplyZone.to = time; conditions.supplyZone = iSupplyZone; conditions.bearishOrderBlock.Clean(); conditions.bearishFVG.Clean(); // // Bearish Order Block ... int obCount = ArraySize(_15MState.bearishOrderBlocks); if (IsValidSize(obCount)) { // for (int j = 0; j < obCount; j++) { // XZone jZone = _15MState.bearishOrderBlocks[j]; // bool isBreaked = IsBreakeLower( jZone, iSupplyZone // ); if (isBreaked) { // jZone.to = time; conditions.bearishOrderBlock = jZone; // break; } } } // // Validate Order Block ... bool isValidOrderBlock = conditions.bearishOrderBlock.IsValid(); if (!isValidOrderBlock) { continue; } // // Bearish FVG ... int fairValueGapsCount = ArraySize(_15MState.bearishFVGs); if (IsValidSize(fairValueGapsCount)) { // for (int j = 0; j < fairValueGapsCount; j++) { // XZone jZone = _15MState.bearishFVGs[j]; // bool isBreaked = IsBreakeLower( jZone, conditions.bearishOrderBlock // ); if (isBreaked) { // jZone.to = time; conditions.bearishFVG = jZone; // break; } } } // // Validate FVG ... bool isValidFVG = conditions.bearishFVG.IsValid(); if (!isValidFVG) { continue; } // // Detect Inside Demand POIs ... // // Order Blocks ... // CState ... int orderBlocksCount = ArraySize(_CombineState.bearishOrderBlocks); if (IsValidSize(orderBlocksCount)) { // for (int j = 0; j < orderBlocksCount; j++) { // XZone jZone = _CombineState.bearishOrderBlocks[j]; // bool isInside = IsInside( jZone, iSupplyZone, X_ZONE_UPPER_EDGE, true // ); if (isInside) { // jZone.to = TimeCurrent(); // AddIfNotExists( jZone, conditions.bearishOrderBlocks // ); } } } // // Resistance Zones ... // CState ... int resistancesCount = ArraySize(_CombineState.resistanceZones); if (IsValidSize(resistancesCount)) { // for (int j = 0; j < resistancesCount; j++) { // XOHCL jBar = _CombineState.resistanceZones[j]; // bool isInside = IsInside( jBar, iSupplyZone, X_ZONE_UPPER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.resistances // ); } } } // // Fair Value Gaps ... // CState ... int fvgsCount = ArraySize(_CombineState.bearishFVGs); if (IsValidSize(fvgsCount)) { // for (int j = 0; j < fvgsCount; j++) { // XZone jFVG = _CombineState.bearishFVGs[j]; // bool isInside = IsInside( jFVG, iSupplyZone, X_ZONE_UPPER_EDGE, true // ); if (isInside) { // jFVG.to = TimeCurrent(); // AddIfNotExists( jFVG, conditions.bearishFVGs // ); } } } // // Swings ... // CState ... int swingsCount = ArraySize(_CombineState.swingHighs); if (IsValidSize(swingsCount)) { // for (int j = 0; j < swingsCount; j++) { // XOHCL jBar = _CombineState.swingHighs[j]; // bool isInside = IsInside( jBar, iSupplyZone, X_ZONE_UPPER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.swingHighs // ); } } } // // Momentum Bars ... // CState ... int momentumBarsCount = ArraySize(_CombineState.momentumBars); if (IsValidSize(momentumBarsCount)) { // for (int j = 0; j < momentumBarsCount; j++) { // XOHCL jBar = _CombineState.momentumBars[j]; // bool isInside = jBar.IsBearish() && jBar.time > iSupplyZone.from && IsInside( jBar, iSupplyZone, X_ZONE_UPPER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.bearishMomentumBars // ); } } } // // Rejection Bars ... // CState ... int rejectionBarsCount = ArraySize(_CombineState.rejectionBars); if (IsValidSize(rejectionBarsCount)) { // for (int j = 0; j < rejectionBarsCount; j++) { // XOHCL jBar = _CombineState.rejectionBars[j]; // bool isInside = jBar.GetLowShadow() < jBar.GetHighShadow() && jBar.time > iSupplyZone.from && IsInside( jBar, iSupplyZone, X_ZONE_UPPER_EDGE, true // ); if (isInside) { // AddIfNotExists( jBar, conditions.bearishRejectionBars // ); } } } // bool hasValidSupplyZone = conditions.ValidateSupply(); if (!hasValidSupplyZone) { conditions.CleanSupply(); } else { break; } } } // // Demand ... // Used for Long ... bool hasValidDemandZone = conditions.ValidateDemand(); // // Supply ... // Used for Short ... bool hasValidSupplyZone = conditions.ValidateSupply(); // // Check Conditions is Valid or not ... result = hasValidDemandZone || hasValidSupplyZone; if (!result) { conditions.Clean(); } // return result; } /** * Detect Market Structure for Specified Conditions ... * * @param structure: X121SMCMarketStructure instance ... * @param conditions: X121SMCStrategyConditions instance ... * @param d1State: XPOIState instance ... * @param h4State: XPOIState instance ... * @param _15MState: XPOIState instance ... * @param m5State: XPOIState instance ... * @param m1State: XPOIState instance ... */ void DetectMarketStructure( X121SMCMarketStructure &structure, X121SMCStrategyConditions &conditions // ) override { // structure.Clean(); // if (!conditions.IsValid()) { return; } // bool hasValidDemand = conditions.ValidateDemand(); bool hasValidSupply = conditions.ValidateSupply(); if (!hasValidDemand && !hasValidSupply) { return; } // structure.supplyZone = conditions.supplyZone; structure.demandZone = conditions.demandZone; // datetime cTime = TimeCurrent(); // // Supply Zones ... int supplysCount = ArraySize(_CombineState.supplyZones); if (IsValidSize(supplysCount)) { // for (int i = 0; i < supplysCount; i++) { // XZone iZone = _CombineState.supplyZones[i]; // bool isBetween = IsBetween( iZone, structure.supplyZone, structure.demandZone // ); if (isBetween) { // iZone.to = cTime; // AddIfNotExists( iZone, structure.supplyZones // ); } } } // // Demand Zones ... int demandsCount = ArraySize(_CombineState.demandZones); if (IsValidSize(demandsCount)) { // for (int i = 0; i < demandsCount; i++) { // XZone iZone = _CombineState.demandZones[i]; // bool isBetween = IsBetween( iZone, structure.supplyZone, structure.demandZone // ); if (isBetween) { // iZone.to = cTime; // AddIfNotExists( iZone, structure.demandZones // ); } } } // // Order Blocks ... // // Bullish OBs ... int bullishOBsCount = ArraySize(_CombineState.bullishOrderBlocks); if (IsValidSize(bullishOBsCount)) { // for (int i = 0; i < bullishOBsCount; i++) { // XZone iZone = _CombineState.bullishOrderBlocks[i]; // bool isBetween = IsBetween( iZone, structure.supplyZone, structure.demandZone // ); if (isBetween) { // iZone.to = cTime; // AddIfNotExists( iZone, structure.bullishOrderBlocks // ); } } } // // Bearish OBs ... int bearishOBsCount = ArraySize(_CombineState.bearishOrderBlocks); if (IsValidSize(bearishOBsCount)) { // for (int i = 0; i < bearishOBsCount; i++) { // XZone iZone = _CombineState.bearishOrderBlocks[i]; // bool isBetween = IsBetween( iZone, structure.supplyZone, structure.demandZone // ); if (isBetween) { // iZone.to = cTime; // AddIfNotExists( iZone, structure.bearishOrderBlocks // ); } } } // // Fair Value Gaps ... // // Bullish FVGs ... int bullishFVGsCount = ArraySize(_CombineState.bullishFVGs); if (IsValidSize(bullishFVGsCount)) { // for (int i = 0; i < bullishFVGsCount; i++) { // XZone iZone = _CombineState.bullishFVGs[i]; // bool isBetween = IsBetween( iZone, structure.supplyZone, structure.demandZone // ); if (isBetween) { // iZone.to = cTime; // AddIfNotExists( iZone, structure.bullishFVGs // ); } } } // // Bearish FVGs ... int bearishFVGsCount = ArraySize(_CombineState.bearishFVGs); if (IsValidSize(bearishFVGsCount)) { // for (int i = 0; i < bearishFVGsCount; i++) { // XZone iZone = _CombineState.bearishFVGs[i]; // bool isBetween = IsBetween( iZone, structure.supplyZone, structure.demandZone // ); if (isBetween) { // iZone.to = cTime; // AddIfNotExists( iZone, structure.bearishFVGs // ); } } } // // Swing Highs ... int swingHighsCount = ArraySize(_CombineState.swingHighs); if (IsValidSize(swingHighsCount)) { // for (int i = 0; i < swingHighsCount; i++) { // XOHCL iBar = _CombineState.swingHighs[i]; // bool isBetween = IsBetween( iBar, structure.supplyZone, structure.demandZone // ); if (isBetween) { // AddIfNotExists( iBar, structure.swingHighs // ); } } } // // Swing Lows ... int swingLowsCount = ArraySize(_CombineState.swingLows); if (IsValidSize(swingLowsCount)) { // for (int i = 0; i < swingLowsCount; i++) { // XOHCL iBar = _CombineState.swingLows[i]; // bool isBetween = IsBetween( iBar, structure.supplyZone, structure.demandZone // ); if (isBetween) { // AddIfNotExists( iBar, structure.swingLows // ); } } } // // Support Zones ... int supportsCount = ArraySize(_CombineState.supportZones); if (IsValidSize(supportsCount)) { // for (int i = 0; i < supportsCount; i++) { // XOHCL iBar = _CombineState.supportZones[i]; // bool isBetween = IsBetween( iBar, structure.supplyZone, structure.demandZone // ); if (isBetween) { // AddIfNotExists( iBar, structure.supports // ); } } } // // Resistance Zones ... int resistancesCount = ArraySize(_CombineState.resistanceZones); if (IsValidSize(resistancesCount)) { // for (int i = 0; i < resistancesCount; i++) { // XOHCL iBar = _CombineState.resistanceZones[i]; // bool isBetween = IsBetween( iBar, structure.supplyZone, structure.demandZone // ); if (isBetween) { // AddIfNotExists( iBar, structure.resistances // ); } } } // // Momentum Bars ... int momentumBarCount = ArraySize(_CombineState.momentumBars); if (IsValidSize(momentumBarCount)) { // for (int i = 0; i < momentumBarCount; i++) { // XOHCL iBar = _CombineState.momentumBars[i]; // bool isBetween = IsBetween( iBar, structure.supplyZone, structure.demandZone // ); if (isBetween) { // bool isBullish = iBar.IsBullish(); // if (isBullish) { // AddIfNotExists( iBar, structure.bullishMomentumBars // ); } else { // AddIfNotExists( iBar, structure.bearishMomentumBars // ); } } } } // // Rejection Bars ... int rejectionBarCount = ArraySize(_CombineState.rejectionBars); if (IsValidSize(rejectionBarCount)) { // for (int i = 0; i < rejectionBarCount; i++) { // XOHCL iBar = _CombineState.rejectionBars[i]; // bool isBetween = IsBetween( iBar, structure.supplyZone, structure.demandZone // ); if (isBetween) { // bool isBullish = iBar.GetLowShadow() > iBar.GetHighShadow(); // if (isBullish) { // AddIfNotExists( iBar, structure.bullishRejectionBars // ); } else { // AddIfNotExists( iBar, structure.bearishRejectionBars // ); } } } } } /** * Remove Specific Conditions if Exists ... * * @param conditions: X121SMCStrategyConditions instance ... */ void RemoveConditionsIfExists(X121SMCStrategyConditions &conditions) override { // int count = ArraySize(mConditions); if (!IsValidSize(count)) { return; } // bool hasValidSupply = conditions.ValidateSupply(); bool hasValidDemand = conditions.ValidateDemand(); if (!hasValidSupply && !hasValidDemand) { return; } // int idx = -1; for (int i = 0; i < count; i++) { // X121SMCStrategyConditions iConditions = mConditions[i]; // bool isSupplySame = hasValidSupply && iConditions.ValidateSupply() && conditions.supplyZone.from == iConditions.supplyZone.from && conditions.supplyZone.upper == iConditions.supplyZone.upper && conditions.supplyZone.lower == iConditions.supplyZone.lower; bool isDemandSame = hasValidDemand && iConditions.ValidateDemand() && conditions.demandZone.from == iConditions.demandZone.from && conditions.demandZone.upper == iConditions.demandZone.upper && conditions.demandZone.lower == iConditions.demandZone.lower; // if (isSupplySame || isDemandSame) { // idx = i; break; } } // if (IsValidIndex(idx)) { // ArrayRemove( mConditions, idx, 1 // ); } } // // Customize Strategy Identifier ... string GetTag() override { return X121SMCSUPDEMStrategyToken; } // // Protected ... protected: // // // Props ... // // XCHVWAP ... XCHVWAPInputs chvwapInputs; XSCXCHVWAPHelper *chvwapHelper; // // Private ... private: // // Props ... /** * Validate a Condition ... * * @param conditions: Argument 1 * @return ( bool ) */ bool ValidateConditions(X121SMCStrategyConditions &conditions) { // bool result = false; // result = conditions.IsValid(); if (!result) { return result; } // bool hasValidDemnd = conditions.ValidateDemand(); bool hasValidSupply = conditions.ValidateSupply(); result = hasValidDemnd || hasValidSupply; if (!result) { return result; } // string _symbol = GetSymbol(); ENUM_TIMEFRAMES _period = GetPeriod(); // int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 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; } // result = hasValidDemnd ? cBar.high < conditions.demandZone.upper && zBar.high < conditions.demandZone.upper && cBar.low > conditions.demandZone.lower && zBar.low > conditions.demandZone.lower : hasValidSupply ? cBar.high < conditions.demandZone.upper && zBar.high < conditions.demandZone.upper && cBar.low > conditions.demandZone.lower && zBar.low > conditions.demandZone.lower : false; // return result; } /** * Initial Required Indicators Helper ... */ void InitialHelpers() { // // XCHVWAP ... // // Short ... ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_MANUALLY; // How to Find Period ENUM_TIMEFRAMES scPeriod = PERIOD_M15; // Time Period // // Medium ... ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_MANUALLY; // How to Find Period ENUM_TIMEFRAMES mcPeriod = PERIOD_H1; // Time Period // // Long ... ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_MANUALLY; // How to Find Period ENUM_TIMEFRAMES lcPeriod = PERIOD_H4; // Time Period // // Hind ... ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_MANUALLY; // How to Find Period ENUM_TIMEFRAMES hcPeriod = PERIOD_D1; // Time Period // chvwapInputs.Default(); // chvwapInputs.scMethod = scMethod; chvwapInputs.scPeriod = scPeriod; chvwapInputs.mcMethod = mcMethod; chvwapInputs.mcPeriod = mcPeriod; chvwapInputs.lcMethod = lcMethod; chvwapInputs.lcPeriod = lcPeriod; chvwapInputs.hcMethod = hcMethod; chvwapInputs.hcPeriod = hcPeriod; // chvwapInputs.showShort = true; chvwapInputs.showMedium = true; chvwapInputs.showLong = true; chvwapInputs.showHind = true; // chvwapHelper = new XSCXCHVWAPHelper(); chvwapHelper.Init( GetSymbol(), GetPeriod(), chvwapInputs // ); } // // XCHVWAP ... // XRange mVWAPRange; int mVWAPRangeLongBreakeouts; int mVWAPRangeShortBreakeouts; bool DetectRange() { // bool result = false; // int cIndex = 1; int loopback = 7; int dest = cIndex + loopback; string symbol = GetSymbol(); datetime cTime = TimeCurrent(); ENUM_TIMEFRAMES period = GetPeriod(); // // Reading Indicator's Conditions ... XCHVWAPConditions chvwapConditions; chvwapHelper.GetConditions( chvwapConditions, cIndex, loopback // ); // mVWAPRange.symbol = symbol; mVWAPRange.period = period; // // Find Range Start ... if (!mVWAPRange.IsValid()) { // bool hasTouchedMedium = false; bool hasTouchedLong = false; bool hasTouchedHind = false; // int count = ArraySize(chvwapConditions.h); result = IsValidSize(count); if (!result) { return result; } // for (int i = 0; i < count; i++) { // ENUM_XCHVWAP_STATES mState = chvwapHelper.ToState(chvwapConditions.mState[i]); if (!hasTouchedMedium && mState == XCHVWAP_NEUTURAL_STATE) { hasTouchedMedium = true; } // ENUM_XCHVWAP_STATES lState = chvwapHelper.ToState(chvwapConditions.lState[i]); if (!hasTouchedLong && lState == XCHVWAP_NEUTURAL_STATE) { hasTouchedLong = true; } // ENUM_XCHVWAP_STATES hState = chvwapHelper.ToState(chvwapConditions.hState[i]); if (!hasTouchedHind && hState == XCHVWAP_NEUTURAL_STATE) { hasTouchedHind = true; } // result = // hasTouchedMedium && hasTouchedLong && hasTouchedHind // ; if (result) { break; } } // if (result) { // XOHCL sBar; result = sBar.Init( symbol, period, dest // ); if (result) { // mVWAPRange.from = sBar.time; } } } // if (IsValid(mVWAPRange.from)) { // mVWAPRange.to = cTime; // int highIDX = iHighest( symbol, period, MODE_HIGH, dest, cIndex // ); double high = iHigh( symbol, period, highIDX // ); // int lowIDX = iLowest( symbol, period, MODE_LOW, dest, cIndex // ); double low = iLow( symbol, period, lowIDX // ); // if (mVWAPRange.upper == 0 || high > mVWAPRange.upper) { mVWAPRange.upper = high; } // if (mVWAPRange.lower == 0 || low < mVWAPRange.lower) { mVWAPRange.lower = low; } } // result = mVWAPRange.IsValid(); // return result; } // bool IsRangeBreaked( ENUM_X_POSITION_TYPES &type // ) { // bool result = false; // type = X_POSITION_TYPE_NONE; // int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 1; // int loopback = 7; int dest = cIndex + loopback; string symbol = GetSymbol(); datetime cTime = TimeCurrent(); ENUM_TIMEFRAMES period = GetPeriod(); // result = mVWAPRange.IsValid(); if (!result) { return result; } // // Reading Indicator's Conditions ... XCHVWAPConditions chvwapConditions; chvwapHelper.GetConditions( chvwapConditions, cIndex, loopback // ); // XOHCL zBar; result = zBar.Init( symbol, period, zIndex // ); if (!result) { return result; } // XOHCL cBar; result = cBar.Init( symbol, period, cIndex // ); if (!result) { return result; } // bool isBullishOrdered = // chvwapConditions.m[0] > chvwapConditions.l[0] && chvwapConditions.l[0] > chvwapConditions.h[0] // ; bool isBullishState = // chvwapHelper.IsBullish(chvwapConditions.mState[0]) && chvwapHelper.IsBullish(chvwapConditions.lState[0]) && chvwapHelper.IsBullish(chvwapConditions.hState[0]) // ; bool isBullishBreaked = isBullishState && isBullishOrdered && cBar.IsStrong(50) && cBar.IsBullish() && zBar.low > mVWAPRange.upper && cBar.GetUp() > mVWAPRange.upper; if (isBullishBreaked) { // mVWAPRangeLongBreakeouts++; type = X_POSITION_TYPE_LONG; } // bool isBearishOrdered = // chvwapConditions.m[0] < chvwapConditions.l[0] && chvwapConditions.l[0] < chvwapConditions.h[0] // ; bool isBearishState = // chvwapHelper.IsBearish(chvwapConditions.mState[0]) && chvwapHelper.IsBearish(chvwapConditions.lState[0]) && chvwapHelper.IsBearish(chvwapConditions.hState[0]) // ; bool isBearishBreaked = isBearishState && isBearishOrdered && // cBar.IsStrong(50) && cBar.IsBearish() && // zBar.high < mVWAPRange.lower && cBar.GetDown() < mVWAPRange.lower; if (isBearishBreaked) { // mVWAPRangeShortBreakeouts++; type = X_POSITION_TYPE_SHORT; } // result = isBullishBreaked || isBearishBreaked; // return result; } // void ResetRange() { // mVWAPRange.Clean(); mVWAPRangeLongBreakeouts = 0; mVWAPRangeShortBreakeouts = 0; } // void DrawRange() { // bool canDraw = mVWAPRange.IsValid(); if (!canDraw) { return; } // string name = mVWAPRange.GetTag(); string tooltip = mVWAPRange.GetTooltip(); // CChartObjectRectangle *iObj; iObj = new CChartObjectRectangle(); bool isCreated = iObj.Create( ChartIdentification(), name, SubWindowIdentification(), mVWAPRange.from, mVWAPRange.upper, mVWAPRange.to, mVWAPRange.lower // ); if (!isCreated) { return; } // iObj.Width(1); iObj.Color(clrAqua); iObj.Style(STYLE_SOLID); iObj.Tooltip(tooltip); // mDrawnObjects.Add(iObj); } // // Override Draw Condition ... /** * Draw Specific Condition ... * * @param conditions: X121SMCStrategyConditions instance ... */ void DrawConditions( X121SMCStrategyConditions &conditions // ) { // // Draw Configurations ... // bool drawMainDemand = true; bool drawMainSupply = true; // bool drawMainBullishOrderBlock = true; bool drawMainBearishOrderBlock = true; // bool drawMainBullishFVG = true; bool drawMainBearishFVG = true; // bool drawOrderBlocks = false; bool drawFVGs = false; bool drawSupportResistances = false; bool drawSwings = false; bool drawMomentumBars = false; bool drawRejectionBars = false; // bool renewDates = true; // if (!conditions.IsValid()) { return; } // datetime time = TimeCurrent(); bool hasValidDemand = conditions.ValidateDemand(); bool hasValidSupply = conditions.ValidateSupply(); if (!hasValidDemand && !hasValidSupply) { return; } // // Demand Zone ... if (hasValidDemand) { // // Demand ... if (drawMainDemand) { // if (renewDates) { conditions.demandZone.to = time; } // XCDemandZoneObject *iObj; bool isCreated = mPOIDrawer.CreateDemandZone( conditions.demandZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // if (drawMainBullishOrderBlock) { // if (renewDates) { conditions.bullishOrderBlock.to = time; } // XCBullishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBullishOrderBlock( conditions.bullishOrderBlock, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // if (drawMainBullishFVG) { // if (renewDates) { conditions.bullishFVG.to = time; } // XCBullishFVGObject *iObj; bool isCreated = mPOIDrawer.CreateBullishFVG( conditions.bullishFVG, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Order Blocks ... int obsCount = ArraySize(conditions.bullishOrderBlocks); if (drawOrderBlocks && IsValidSize(obsCount)) { // for (int i = 0; i < obsCount; i++) { // XZone iZone = conditions.bullishOrderBlocks[i]; // if (renewDates) { iZone.to = time; } // XCBullishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBullishOrderBlock( iZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Fair Value Gaps ... int fvgsCount = ArraySize(conditions.bullishFVGs); if (drawFVGs && IsValidSize(fvgsCount)) { // for (int i = 0; i < fvgsCount; i++) { // XZone iZone = conditions.bullishFVGs[i]; // if (renewDates) { iZone.to = time; } // XCBullishFVGObject *iObj; bool isCreated = mPOIDrawer.CreateBullishFVG( iZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Supports ... int supportsCount = ArraySize(conditions.supports); if (drawSupportResistances && IsValidSize(supportsCount)) { // for (int i = 0; i < supportsCount; i++) { // XOHCL iBar = conditions.supports[i]; // XCSupportZoneObject *iObj; bool isCreated = mPOIDrawer.CreateSupportZone( iBar, iObj, time // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Swings ... int swingsCount = ArraySize(conditions.swingLows); if (drawSwings && IsValidSize(swingsCount)) { // for (int i = 0; i < swingsCount; i++) { // XOHCL iBar = conditions.swingLows[i]; // XCSwingLowObject *iObj; bool isCreated = mPOIDrawer.CreateSwingLow( iBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Momentum Bars ... int momentumBarsCount = ArraySize(conditions.bullishMomentumBars); if (drawMomentumBars && IsValidSize(momentumBarsCount)) { // for (int i = 0; i < momentumBarsCount; i++) { // XOHCL iBar = conditions.bullishMomentumBars[i]; // XCBullishMomentumBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishMomentumBar( iBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Rejection Bars ... int rejectionBarsCount = ArraySize(conditions.bullishRejectionBars); if (drawRejectionBars && IsValidSize(rejectionBarsCount)) { // for (int i = 0; i < rejectionBarsCount; i++) { // XOHCL iBar = conditions.bullishRejectionBars[i]; // XCBullishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishRejectionBar( iBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } } // // Supply Zone ... if (hasValidSupply) { // // Supply ... if (drawMainSupply) { // if (renewDates) { conditions.supplyZone.to = time; } // XCSupplyZoneObject *iObj; bool isCreated = mPOIDrawer.CreateSupplyZone( conditions.supplyZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // if (drawMainBearishOrderBlock) { // if (renewDates) { conditions.bearishOrderBlock.to = time; } // XCBearishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBearishOrderBlock( conditions.bearishOrderBlock, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // if (drawMainBearishFVG) { // if (renewDates) { conditions.bearishFVG.to = time; } // XCBearishFVGObject *iObj; bool isCreated = mPOIDrawer.CreateBearishFVG( conditions.bearishFVG, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Order Blocks ... int obsCount = ArraySize(conditions.bearishOrderBlocks); if (drawOrderBlocks && IsValidSize(obsCount)) { // for (int i = 0; i < obsCount; i++) { // XZone iZone = conditions.bearishOrderBlocks[i]; // if (renewDates) { iZone.to = time; } // XCBearishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBearishOrderBlock( iZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Fair Value Gaps ... int fvgsCount = ArraySize(conditions.bearishFVGs); if (drawFVGs && IsValidSize(fvgsCount)) { // for (int i = 0; i < fvgsCount; i++) { // XZone iZone = conditions.bearishFVGs[i]; // if (renewDates) { iZone.to = time; } // XCBearishFVGObject *iObj; bool isCreated = mPOIDrawer.CreateBearishFVG( iZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Resistances ... int resistancesCount = ArraySize(conditions.resistances); if (drawSupportResistances && IsValidSize(resistancesCount)) { // for (int i = 0; i < resistancesCount; i++) { // XOHCL iBar = conditions.resistances[i]; // XCResistanceZoneObject *iObj; bool isCreated = mPOIDrawer.CreateResistanceZone( iBar, iObj, time // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Swings ... int swingsCount = ArraySize(conditions.swingHighs); if (drawSwings && IsValidSize(swingsCount)) { // for (int i = 0; i < swingsCount; i++) { // XOHCL iBar = conditions.swingHighs[i]; // XCSwingHighObject *iObj; bool isCreated = mPOIDrawer.CreateSwingHigh( iBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Momentum Bars ... int momentumBarsCount = ArraySize(conditions.bearishMomentumBars); if (drawMomentumBars && IsValidSize(momentumBarsCount)) { // for (int i = 0; i < momentumBarsCount; i++) { // XOHCL iBar = conditions.bearishMomentumBars[i]; // XCBearishMomentumBarObject *iObj; bool isCreated = mPOIDrawer.CreateBearishMomentumBar( iBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } // // Rejection Bars ... int rejectionBarsCount = ArraySize(conditions.bearishRejectionBars); if (drawRejectionBars && IsValidSize(rejectionBarsCount)) { // for (int i = 0; i < rejectionBarsCount; i++) { // XOHCL iBar = conditions.bearishRejectionBars[i]; // XCBearishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBearishRejectionBar( iBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } } } // }; //