/////////////////////////////////////////////////////// // // 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); double pip = GetPipPrice(_symbol); double pip2 = 2 * pip; // 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_DIRECTION breakeType; bool isBreaked = IsRangeBreaked(breakeType); // if (isBreaked) { // // Detect Trend ... // bool d1HasBullishTrend = HasBullishTrend(_1DState); bool d1HasBearishTrend = HasBearishTrend(_1DState); // bool h4HasBullishTrend = HasBullishTrend(_4HState); bool h4HasBearishTrend = HasBearishTrend(_4HState); // bool m15HasBullishTrend = HasBullishTrend(_15MState); bool m15HasBearishTrend = HasBearishTrend(_15MState); // bool m5HasBullishTrend = HasBullishTrend(_5MState); bool m5HasBearishTrend = HasBearishTrend(_5MState); // bool m1HasBullishTrend = HasBullishTrend(_1MState); bool m1HasBearishTrend = HasBearishTrend(_1MState); // bool isBullishTrendValid = m15HasBullishTrend && m5HasBullishTrend && m1HasBullishTrend; // bool isBearishTrendValid = m15HasBearishTrend && m5HasBearishTrend && m1HasBearishTrend; // bool isRangeStructureDetected = DetectRangeStructure(); if (isRangeStructureDetected) { // conditions.Clean(); conditions.symbol = GetSymbol(); conditions.period = GetPeriod(); conditions.time = TimeCurrent(); // bool isValidBreake = ValidateRangeBreake( breakeType, conditions // ); if (!isValidBreake) { conditions.Clean(); } // bool isBullish = breakeType == X_DIRECTION_BULLISH; bool isBearish = breakeType == X_DIRECTION_BEARISH; // hasLong = isBullish && isValidBreake; // hasShort = isBearish && isValidBreake; } } // bool isDetected = DetectRange(); if (isDetected) { // DrawRange(); } // result = hasLong || hasShort; // // Rmove Signal Condition ... if (result) { // // TYPE ... type = hasLong ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; ENUM_X_POSITION_TYPES xType = hasLong ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; // entry = GetEntry( conditions.symbol, type // ); // double candidates[]; DetectSLCandidates( candidates, entry, conditions, xType // ); double selectedSL = hasLong ? GetMax(candidates) : GetMin(candidates); sl = hasLong ? selectedSL - pip2 : selectedSL + pip2; // // RISK Reward ... risk = hasLong ? entry - sl : sl - entry; reward = risk * r2r; tp = hasLong ? entry + reward : entry - reward; // ResetRange(); ClearDraws(); // 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; } // // 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 // ); } // XRange mVWAPRange; int mVWAPRangeLongBreakeouts; int mVWAPRangeShortBreakeouts; XRangeStructure mVWAPRangeStructure; /** * Detect Range ... * * @return ( bool ) */ 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; } /** * Check Range is Breaked or not ... * * @param type: Argument 1 * @return ( bool ) */ bool IsRangeBreaked( ENUM_X_DIRECTION &type // ) { // bool result = false; // type = X_DIRECTION_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_DIRECTION_BULLISH; } // 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_DIRECTION_BEARISH; } // result = isBullishBreaked || isBearishBreaked; // return result; } /** * Detect Range Structure ... * * @return ( bool ) */ bool DetectRangeStructure() { // mVWAPRangeStructure.Clean(); mVWAPRangeStructure.range = mVWAPRange; // // 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, mVWAPRange // ); if (isBetween) { // iZone.to = mVWAPRange.to; // AddIfNotExists( iZone, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // iZone.to = mVWAPRange.to; // AddIfNotExists( iZone, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // iZone.to = mVWAPRange.to; // AddIfNotExists( iZone, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // iZone.to = mVWAPRange.to; // AddIfNotExists( iZone, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // iZone.to = mVWAPRange.to; // AddIfNotExists( iZone, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // iZone.to = mVWAPRange.to; // AddIfNotExists( iZone, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // AddIfNotExists( iBar, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // AddIfNotExists( iBar, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // AddIfNotExists( iBar, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // AddIfNotExists( iBar, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // bool isBullish = iBar.IsBullish(); // if (isBullish) { // AddIfNotExists( iBar, mVWAPRangeStructure.bullishMomentumBars // ); } else { // AddIfNotExists( iBar, mVWAPRangeStructure.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, mVWAPRange // ); if (isBetween) { // bool isBullish = iBar.GetLowShadow() > iBar.GetHighShadow(); // if (isBullish) { // AddIfNotExists( iBar, mVWAPRangeStructure.bullishRejectionBars // ); } else { // AddIfNotExists( iBar, mVWAPRangeStructure.bearishRejectionBars // ); } } } } // bool result = mVWAPRangeStructure.IsValid(); return result; } /** * Validate Range Break ... * * @param type: ENUM_X_DIRECTION member ... * * @return ( bool ) */ bool ValidateRangeBreake( ENUM_X_DIRECTION type, X121SMCStrategyConditions &conditions // ) { // bool result = false; // bool drawPOIs = true; bool drawFVG = true; bool drawSwing = true; bool drawOrderBlock = true; bool drawMomentumBar = true; bool drawSupplyDemand = true; bool drawRejectionBar = true; bool drawSupportResistance = true; // result = mVWAPRange.IsValid() && mVWAPRangeStructure.IsValid(); if (!result) { return result; } // result = type == X_DIRECTION_BULLISH || type == X_DIRECTION_BEARISH; if (!result) { return result; } // bool isBullish = type == X_DIRECTION_BULLISH; // string symbol = GetSymbol(); ENUM_TIMEFRAMES period = GetPeriod(); // int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 1; // XOHCL breakeBar; result = breakeBar.Init( symbol, period, cIndex // ); if (!result) { return result; } // XZone fvg; XOHCL swing; XOHCL supRes; XZone supDem; XZone orderBlock; XOHCL momentumBar; XOHCL rejectionBar; // // Do this for Better Changes Later ... XRangeStructure state = mVWAPRangeStructure; // // First we Have to find Supply or Demand ... int demandsCount = ArraySize(state.demandZones); int suppliesCount = ArraySize(state.supplyZones); // result = isBullish ? IsValidSize(demandsCount) : IsValidSize(suppliesCount); if (!result) { return result; } // // Detect Supply and Demands ... if (isBullish) { // for (int i = 0; i < demandsCount; i++) { // XZone iZone = state.demandZones[i]; // if (!supDem.IsValid() || supDem.lower < iZone.lower) { supDem = iZone; } // AddRef( iZone, conditions.demandZones // ); } } else { // for (int i = 0; i < suppliesCount; i++) { // XZone iZone = state.supplyZones[i]; // if (!supDem.IsValid() || supDem.upper > iZone.upper) { supDem = iZone; } // AddRef( iZone, conditions.supplyZones // ); } } // result = supDem.IsValid(); if (!result) { return result; } // // Detect Order Block ... if (isBullish) { // int count = ArraySize(state.bullishOrderBlocks); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XZone iZone = state.bullishOrderBlocks[i]; // if (!orderBlock.IsValid() || orderBlock.lower < iZone.lower) { orderBlock = iZone; } // AddRef( iZone, conditions.bullishOrderBlocks // ); } } } else { // int count = ArraySize(state.bearishOrderBlocks); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XZone iZone = state.bearishOrderBlocks[i]; // if (!orderBlock.IsValid() || orderBlock.upper > iZone.upper) { orderBlock = iZone; } // AddRef( iZone, conditions.bearishOrderBlocks // ); } } } // result = orderBlock.IsValid(); if (!result) { return result; } // // Detect Fair Value Gaps ... if (isBullish) { // int count = ArraySize(state.bullishFVGs); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XZone iZone = state.bullishFVGs[i]; // if (!fvg.IsValid() || fvg.lower < iZone.lower) { fvg = iZone; } // AddRef( iZone, conditions.bullishFVGs // ); } } } else { // int count = ArraySize(state.bearishFVGs); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XZone iZone = state.bearishFVGs[i]; // if (!fvg.IsValid() || fvg.upper > iZone.upper) { fvg = iZone; } // AddRef( iZone, conditions.bearishFVGs // ); } } } // // Detect Swings ... if (isBullish) { // int count = ArraySize(state.swingLows); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XOHCL iBar = state.swingLows[i]; // if (!swing.IsValid() || swing.low < iBar.low) { swing = iBar; } // AddRef( iBar, conditions.swingLows // ); } } } else { // int count = ArraySize(state.swingHighs); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XOHCL iBar = state.swingHighs[i]; // if (!swing.IsValid() || swing.high > iBar.high) { swing = iBar; } // AddRef( iBar, conditions.swingHighs // ); } } } // // Detect Momentum Bar ... if (isBullish) { // int count = ArraySize(state.bullishMomentumBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XOHCL iBar = state.bullishMomentumBars[i]; // if (!momentumBar.IsValid() || momentumBar.low < iBar.low) { momentumBar = iBar; } // AddRef( iBar, conditions.bullishMomentumBars // ); } } } else { // int count = ArraySize(state.bearishMomentumBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XOHCL iBar = state.bearishMomentumBars[i]; // if (!momentumBar.IsValid() || momentumBar.high > iBar.high) { momentumBar = iBar; } // AddRef( iBar, conditions.bearishMomentumBars // ); } } } // result = momentumBar.IsValid(); if (!result) { return result; } // // Detect Rejection Bar ... if (isBullish) { // int count = ArraySize(state.bullishRejectionBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XOHCL iBar = state.bullishRejectionBars[i]; // if (!rejectionBar.IsValid() || rejectionBar.low < iBar.low) { rejectionBar = iBar; } // AddRef( iBar, conditions.bullishRejectionBars // ); } } } else { // int count = ArraySize(state.bearishRejectionBars); if (IsValidSize(count)) { // for (int i = 0; i < count; i++) { // XOHCL iBar = state.bearishRejectionBars[i]; // if (!rejectionBar.IsValid() || rejectionBar.high > iBar.high) { rejectionBar = iBar; } // AddRef( iBar, conditions.bearishRejectionBars // ); } } } // result = rejectionBar.IsValid(); if (!result) { return result; } // if (drawPOIs) { // bool isCreated = false; // if (isBullish) { // // Demand ... if (drawSupplyDemand) { // XCDemandZoneObject *iObj; isCreated = mPOIDrawer.CreateDemandZone( supDem, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Order Block ... if (drawOrderBlock) { // XCBullishOrderBlockObject *iObj; isCreated = mPOIDrawer.CreateBullishOrderBlock( orderBlock, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Fair Value Gap ... if (drawFVG) { // XCBullishFVGObject *iObj; isCreated = mPOIDrawer.CreateBullishFVG( fvg, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Support ... if (drawSupportResistance) { // XCSupportZoneObject *iObj; isCreated = mPOIDrawer.CreateSupportZone( supRes, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Swing ... if (drawSwing) { // XCSwingLowObject *iObj; isCreated = mPOIDrawer.CreateSwingLow( swing, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Momentum Bar ... if (drawMomentumBar) { // XCBullishMomentumBarObject *iObj; isCreated = mPOIDrawer.CreateBullishMomentumBar( momentumBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Rejection Bar ... if (drawRejectionBar) { // XCBullishRejectionBarObject *iObj; isCreated = mPOIDrawer.CreateBullishRejectionBar( momentumBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } else { // // Supply ... if (drawSupplyDemand) { // XCSupplyZoneObject *iObj; isCreated = mPOIDrawer.CreateSupplyZone( supDem, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Order Block ... if (drawOrderBlock) { // XCBearishOrderBlockObject *iObj; isCreated = mPOIDrawer.CreateBearishOrderBlock( orderBlock, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Fair Value Gap ... if (drawFVG) { // XCBearishFVGObject *iObj; isCreated = mPOIDrawer.CreateBearishFVG( fvg, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Resistance ... if (drawSupportResistance) { // XCResistanceZoneObject *iObj; isCreated = mPOIDrawer.CreateResistanceZone( supRes, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Swing ... if (drawSwing) { // XCSwingHighObject *iObj; isCreated = mPOIDrawer.CreateSwingHigh( swing, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Momentum Bar ... if (drawMomentumBar) { // XCBearishMomentumBarObject *iObj; isCreated = mPOIDrawer.CreateBearishMomentumBar( momentumBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Rejection Bar ... if (drawRejectionBar) { // XCBearishRejectionBarObject *iObj; isCreated = mPOIDrawer.CreateBearishRejectionBar( momentumBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } } } // if (isBullish) { // conditions.bullishFVG = fvg; conditions.support = supRes; conditions.swingLow = swing; conditions.demandZone = supDem; conditions.bullishOrderBlock = orderBlock; conditions.bullishMomentumBar = momentumBar; conditions.bullishRejectionBar = rejectionBar; } else { // conditions.bearishFVG = fvg; conditions.swingHigh = swing; conditions.resistance = supRes; conditions.supplyZone = supDem; conditions.bearishOrderBlock = orderBlock; conditions.bearishMomentumBar = momentumBar; conditions.bearishRejectionBar = rejectionBar; } // return result; } /** * Reset Range ... */ void ResetRange() { // mVWAPRange.Clean(); mVWAPRangeStructure.Clean(); mVWAPRangeLongBreakeouts = 0; mVWAPRangeShortBreakeouts = 0; } /** * Draw Range ... */ 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); } /** * Draw Detected Market Structure ... * * @param direction: ENUM_X_DIRECTION member ... */ void DrawRangeStructure(ENUM_X_DIRECTION direction) { // if (!mVWAPRangeStructure.IsValid()) { return; } // bool canAll = direction == X_DIRECTION_ALL; bool canBullish = direction == X_DIRECTION_BULLISH; bool canBearish = direction == X_DIRECTION_BEARISH; if (!canAll && !canBullish && !canBearish) { return; } // // Supply Zones ... int supplysCount = ArraySize(mVWAPRangeStructure.supplyZones); if ((canAll || canBearish) && IsValidSize(supplysCount)) { // for (int i = 0; i < supplysCount; i++) { // XZone iZone = mVWAPRangeStructure.supplyZones[i]; // XCSupplyZoneObject *iObj; bool isCreated = mPOIDrawer.CreateSupplyZone( iZone, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Demand Zones ... int demandsCount = ArraySize(mVWAPRangeStructure.demandZones); if ((canAll || canBullish) && IsValidSize(demandsCount)) { // for (int i = 0; i < demandsCount; i++) { // XZone iZone = mVWAPRangeStructure.demandZones[i]; // XCDemandZoneObject *iObj; bool isCreated = mPOIDrawer.CreateDemandZone( iZone, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Order Blocks ... // // Bullish OBs ... int bullishOBsCount = ArraySize(mVWAPRangeStructure.bullishOrderBlocks); if ((canAll || canBullish) && IsValidSize(bullishOBsCount)) { // for (int i = 0; i < bullishOBsCount; i++) { // XZone iZone = mVWAPRangeStructure.bullishOrderBlocks[i]; // XCBullishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBullishOrderBlock( iZone, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Bearish OBs ... int bearishOBsCount = ArraySize(mVWAPRangeStructure.bearishOrderBlocks); if ((canAll || canBearish) && IsValidSize(bearishOBsCount)) { // for (int i = 0; i < bearishOBsCount; i++) { // XZone iZone = mVWAPRangeStructure.bearishOrderBlocks[i]; // XCBearishOrderBlockObject *iObj; bool isCreated = mPOIDrawer.CreateBearishOrderBlock( iZone, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Fair Value Gaps ... // // Bullish FVGs ... int bullishFVGsCount = ArraySize(mVWAPRangeStructure.bullishFVGs); if ((canAll || canBullish) && IsValidSize(bullishFVGsCount)) { // for (int i = 0; i < bullishFVGsCount; i++) { // XZone iZone = mVWAPRangeStructure.bullishFVGs[i]; // XCBullishFVGObject *iObj; bool isCreated = mPOIDrawer.CreateBullishFVG( iZone, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Bearish FVGs ... int bearishFVGsCount = ArraySize(mVWAPRangeStructure.bearishFVGs); if ((canAll || canBearish) && IsValidSize(bearishFVGsCount)) { // for (int i = 0; i < bearishFVGsCount; i++) { // XZone iZone = mVWAPRangeStructure.bearishFVGs[i]; // XCBearishFVGObject *iObj; bool isCreated = mPOIDrawer.CreateBearishFVG( iZone, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Swing Highs ... int swingHighsCount = ArraySize(mVWAPRangeStructure.swingHighs); if ((canAll || canBearish) && IsValidSize(swingHighsCount)) { // for (int i = 0; i < swingHighsCount; i++) { // XOHCL iBar = mVWAPRangeStructure.swingHighs[i]; // XCSwingHighObject *iObj; bool isCreated = mPOIDrawer.CreateSwingHigh( iBar, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Swing Lows ... int swingLowsCount = ArraySize(mVWAPRangeStructure.swingLows); if ((canAll || canBullish) && IsValidSize(swingLowsCount)) { // for (int i = 0; i < swingLowsCount; i++) { // XOHCL iBar = mVWAPRangeStructure.swingLows[i]; // XCSwingLowObject *iObj; bool isCreated = mPOIDrawer.CreateSwingLow( iBar, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Support Zones ... int supportsCount = ArraySize(mVWAPRangeStructure.supports); if ((canAll || canBullish) && IsValidSize(supportsCount)) { // for (int i = 0; i < supportsCount; i++) { // XOHCL iBar = mVWAPRangeStructure.supports[i]; // XCSupportZoneObject *iObj; bool isCreated = mPOIDrawer.CreateSupportZone( iBar, iObj, mVWAPRange.to // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Resistance Zones ... int resistancesCount = ArraySize(mVWAPRangeStructure.resistances); if ((canAll || canBearish) && IsValidSize(resistancesCount)) { // for (int i = 0; i < resistancesCount; i++) { // XOHCL iBar = mVWAPRangeStructure.resistances[i]; // XCResistanceZoneObject *iObj; bool isCreated = mPOIDrawer.CreateResistanceZone( iBar, iObj, mVWAPRange.to // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Momentum Bars ... // // Bullish Momentum Bars ... int momentumBarCount = ArraySize(mVWAPRangeStructure.bullishMomentumBars); if ((canAll || canBullish) && IsValidSize(momentumBarCount)) { // for (int i = 0; i < momentumBarCount; i++) { // XOHCL iBar = mVWAPRangeStructure.bullishMomentumBars[i]; // XCBullishMomentumBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishMomentumBar( iBar, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Bearish Momentum Bars ... momentumBarCount = ArraySize(mVWAPRangeStructure.bearishMomentumBars); if ((canAll || canBearish) && IsValidSize(momentumBarCount)) { // for (int i = 0; i < momentumBarCount; i++) { // XOHCL iBar = mVWAPRangeStructure.bearishMomentumBars[i]; // XCBearishMomentumBarObject *iObj; bool isCreated = mPOIDrawer.CreateBearishMomentumBar( iBar, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Rejection Bars ... // // Bullish Rejection Bars ... int rejectionBarCount = ArraySize(mVWAPRangeStructure.bullishRejectionBars); if ((canAll || canBullish) && IsValidSize(rejectionBarCount)) { // for (int i = 0; i < rejectionBarCount; i++) { // XOHCL iBar = mVWAPRangeStructure.bullishRejectionBars[i]; // XCBullishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishRejectionBar( iBar, iObj // ); if (isCreated) { // mDrawnObjects.Add(iObj); } } } // // Bearish Rejection Bars ... rejectionBarCount = ArraySize(mVWAPRangeStructure.bearishRejectionBars); if ((canAll || canBearish) && IsValidSize(rejectionBarCount)) { // for (int i = 0; i < rejectionBarCount; i++) { // XOHCL iBar = mVWAPRangeStructure.bearishRejectionBars[i]; // XCBearishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBearishRejectionBar( iBar, iObj // ); if (isCreated) { // 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); } } } } } // }; //