// // LONG ... // bool isSoImportantLong = iConditions.demandZone.IsValid() && iConditions.bullishFVG.IsValid() && iConditions.bullishOrderBlock.IsValid(); // bool isImportantLong = iConditions.demandZone.IsValid() && (iConditions.bullishFVG.IsValid() || iConditions.bullishOrderBlock.IsValid()); // bool isRiskyLong = iConditions.demandZone.IsValid() && (iConditions.bullishFVG.IsValid() || iConditions.bullishOrderBlock.IsValid()); // bool hasLongConditions = isSoImportantLong || isImportantLong || isRiskyLong; // if (hasLongConditions) { // // Find Trigger for Input Positions ... // - [] Breakout; // - [] Engulf; // - [] Rejection Bar; // - [] Momentum Bar; // type = POSITION_TYPE_BUY; entry = GetEntry(mSymbol, type); sl = iConditions.demandZone.lower - (10 * points); risk = entry - sl; reward = risk * r2r; tp = entry + reward; // bool isSpreadOK = IsSpreadPass(); // // Price Must Breakout the Upper of Demand ... bool isBreakout = // cBar.IsBullish() && zBar.low > conditions.demandZone.upper && cBar.high > conditions.demandZone.upper && cBar.close > conditions.demandZone.upper && (cBar.open < conditions.demandZone.upper || cBar.low < conditions.demandZone.upper) // ; // // Price Must have Bullish Trend and Momentum on Ticks ... bool isTicksBullishMomentum = IsTicksBullish() && IsTicksHasMomentum(); // // Detect momentum / Swing Low / Rejection Bars ... bool hasMomentumBars = false; int swingLowsCount = ArraySize(_5MState.swingLows); int momentumBarsCount = ArraySize(_5MState.momentumBars); int rejectionBarsCount = ArraySize(_5MState.rejectionBars); if (IsValidSize(swingLowsCount) || IsValidSize(momentumBarsCount) || IsValidSize(rejectionBarsCount)) { // int foundedPOIs = 0; // // Check Swing Lows ... if (IsValidSize(swingLowsCount)) { // for (int i = 0; i < swingLowsCount; i++) { // XOHCL iBar = _5MState.swingLows[i]; // if (iBar.time > iConditions.demandZone.from) { // if (iBar.low < entry) { // foundedPOIs++; DrawSwingBar(iBar, true); } } } } // // Check Momentum Bars ... if (IsValidSize(momentumBarsCount)) { // for (int i = 0; i < momentumBarsCount; i++) { // XOHCL iBar = _5MState.momentumBars[i]; // if (iBar.time > iConditions.demandZone.from) { // if (iBar.IsBullish() && iBar.low < entry) { // foundedPOIs++; DrawMomentumBar(iBar); } } } } // // Check Rejection Bars ... if (IsValidSize(rejectionBarsCount)) { // for (int i = 0; i < rejectionBarsCount; i++) { // XOHCL iBar = _5MState.rejectionBars[i]; // if (iBar.time > iConditions.demandZone.from) { // if (iBar.low < entry && iBar.GetLowShadow() > iBar.GetHighShadow()) { // foundedPOIs++; DrawRejectionBar(iBar); } } } } // pushers = foundedPOIs; hasMomentumBars = foundedPOIs > 0; } // hasLongConditions = hasLongConditions && // isSpreadOK && // isBreakout && isTicksBullishMomentum && // hasMomentumBars // ; // if (hasLongConditions) { // removeIDX = i; conditions = iConditions; result = hasLongConditions; // break; } } // // SHORT ... // bool isSoImportantShort = iConditions.supplyZone.IsValid() && iConditions.bearishFVG.IsValid() && iConditions.bearishOrderBlock.IsValid(); // bool isImportantShort = iConditions.supplyZone.IsValid() && (iConditions.bearishFVG.IsValid() || iConditions.bearishOrderBlock.IsValid()); // bool isRiskyShort = iConditions.supplyZone.IsValid() && (!iConditions.bearishFVG.IsValid() && !iConditions.bearishOrderBlock.IsValid()); // bool hasShortConditions = isSoImportantShort || isImportantShort || isRiskyShort; // if (hasShortConditions) { // // Find Trigger for Input Positions ... // - [] Breakout; // - [] Engulf; // - [] Rejection Bar; // - [] Momentum Bar; // // // removeIDX = i; // conditions = iConditions; // // DrawConditions(iConditions); // Print("hasShortConditions"); break; } ////////////////////////////////////////////////////////////////////////////// // XZone iBearishOrderBlock; XZone iBearishFVG; // bool isPassed = false; int orderBlocksCount = ArraySize(orderBlocksState.bearishOrderBlocks); isPassed = IsValidSize(orderBlocksCount); if (!isPassed) { continue; } // // Find Related Order Block ... isPassed = false; for (int j = 0; j < orderBlocksCount; j++) { // XZone jOrderBlock = orderBlocksState.bearishOrderBlocks[j]; // bool isOrderBlockInsideZone = IsSupplyZoneOrderBlock( iSupplyZone, jOrderBlock // ); if (isOrderBlockInsideZone) { // isPassed = true; iBearishOrderBlock = jOrderBlock; conditions.bearishOrderBlock = jOrderBlock; break; } } if (!isPassed) { continue; } // isPassed = false; int fairValueGapsCount = ArraySize(fvgsState.bearishFVGs); isPassed = IsValidSize(fairValueGapsCount); if (!isPassed) { continue; } // // Find Related Fair Value Gaps ... isPassed = false; for (int j = 0; j < fairValueGapsCount; j++) { // XZone jFVG = fvgsState.bearishFVGs[j]; // bool isBelongs = IsBearishOrderBlockFVG( iBearishOrderBlock, jFVG // ); if (isBelongs) { // iBearishFVG = jFVG; conditions.bearishFVG = jFVG; // isPassed = true; break; } } // if (!isPassed) // { // continue; // } // // // if (isPassed) // { // // // DrawSupplyZone(iSupplyZone); // DrawBearishOrderBlock(iBearishOrderBlock); // DrawBearishFVG(iBearishFVG); // } ////////////////////////////////////////////// // XZone iBullishOrderBlock; XZone iBullishFVG; // bool isPassed = false; int orderBlocksCount = ArraySize(orderBlocksState.bullishOrderBlocks); isPassed = IsValidSize(orderBlocksCount); if (!isPassed) { continue; } // // Find Related Order Block ... isPassed = false; for (int j = 0; j < orderBlocksCount; j++) { // XZone jOrderBlock = orderBlocksState.bullishOrderBlocks[j]; // bool isOrderBlockInsideZone = IsDemandZoneOrderBlock( iDemandZone, jOrderBlock // ); if (isOrderBlockInsideZone) { // isPassed = true; iBullishOrderBlock = jOrderBlock; conditions.bullishOrderBlock = jOrderBlock; break; } } if (!isPassed) { continue; } // isPassed = false; int fairValueGapsCount = ArraySize(fvgsState.bullishFVGs); isPassed = IsValidSize(fairValueGapsCount); if (!isPassed) { continue; } // // Find Related Fair Value Gaps ... isPassed = false; for (int j = 0; j < fairValueGapsCount; j++) { // XZone jFVG = fvgsState.bullishFVGs[j]; // bool isBelongs = IsBullishOrderBlockFVG( iBullishOrderBlock, jFVG // ); if (isBelongs) { // iBullishFVG = jFVG; conditions.bullishFVG = jFVG; // isPassed = true; break; } } // if (!isPassed) // { // continue; // } // // // if (isPassed) // { // // // DrawDemandZone(iDemandZone); // DrawBullishOrderBlock(iBullishOrderBlock); // DrawBullishFVG(iBullishFVG); // } ////////////////////////////////////////////// // // Tools Functions ... /** * Check an Order Block belongs to a Supply Zone ... * * @param supply: XZone instance ... * @param orderBlock: XZone instance ... * * @return ( bool ) */ bool IsSupplyZoneOrderBlock( XZone &supply, XZone &orderBlock // ) { // bool result = false; // result = supply.IsValid() && orderBlock.IsValid(); if (!result) { return result; } // result = orderBlock.upper <= supply.upper; // return result; } /** * Check an Order Block belongs to a Demand Zone ... * * @param demand: XZone instance ... * @param orderBlock: XZone instance ... * * @return ( bool ) */ bool IsDemandZoneOrderBlock( XZone &demand, XZone &orderBlock // ) { // bool result = false; // result = demand.IsValid() && orderBlock.IsValid(); if (!result) { return result; } // result = orderBlock.lower >= demand.lower; // return result; } /** * Check a Bearish FVG belongs to a Bearish Order Block ... * * @param orderBlock: XZone instance ... * @param fvg: XZone instance ... * * @return ( bool ) */ bool IsBearishOrderBlockFVG( XZone &orderBlock, XZone &fvg // ) { // bool result = false; // result = fvg.IsValid() && orderBlock.IsValid(); if (!result) { return result; } // result = fvg.upper <= orderBlock.upper && fvg.upper > orderBlock.lower; // return result; } /** * Check a Bullish FVG belongs to a Bullish Order Block ... * * @param orderBlock: XZone instance ... * @param fvg: XZone instance ... * * @return ( bool ) */ bool IsBullishOrderBlockFVG( XZone &orderBlock, XZone &fvg // ) { // bool result = false; // result = fvg.IsValid() && orderBlock.IsValid(); if (!result) { return result; } // result = fvg.lower >= orderBlock.lower && fvg.lower < orderBlock.upper; // return result; } //////////////////////////////////////////////////////////////////////// // int supplyZonesCount = ArraySize(supplyAndDemandZoneState.supplyZones); int demandZonesCount = ArraySize(supplyAndDemandZoneState.demandZones); // XOHCL swingHighs[]; Copy( orderBlocksState.swingHighs, swingHighs // ); Copy( fvgsState.swingHighs, swingHighs, false // ); Copy( triggerState.swingHighs, swingHighs, false // ); // XOHCL swingLows[]; Copy( orderBlocksState.swingLows, swingLows // ); Copy( fvgsState.swingLows, swingLows, false // ); Copy( triggerState.swingLows, swingLows, false // ); // int swingHighsCount = ArraySize(swingHighs); int swingLowsCount = ArraySize(swingLows); if (!IsValidSize(swingLowsCount) || !IsValidSize(swingHighsCount) || !IsValidSize(supplyZonesCount) || !IsValidSize(demandZonesCount)) { return result; } // XOHCL zBar; bool isInited = zBar.Init( Symbol(), Period(), 0 // ); if (!isInited) { return result; } // // Detect Swing High and Low as Market Structure Boundaries ... // // Swing High ... XOHCL tmpBar; for (int i = 0; i < swingHighsCount; i++) { // XOHCL iSwing = swingHighs[i]; // if (!tmpBar.IsValid() || tmpBar.high < iSwing.high) { tmpBar = iSwing; } } if (tmpBar.IsValid()) { // mSwingHigh = tmpBar; string name = tmpBar.GetTag(ToString(X_POI_SWING_HIGH)); if (mSwingHighObject != NULL) { mSwingHighObject.Delete(); } mSwingHighObject = new CChartObjectHLine(); bool isCreated = mSwingHighObject.Create( ChartIdentification(), name, SubWindowIdentification(), tmpBar.high // ); if (isCreated) { // mSwingHighObject.Width(2); mSwingHighObject.Color(clrRed); mSwingHighObject.Style(STYLE_DASHDOTDOT); } } // // Swing Low ... tmpBar.Clean(); for (int i = 0; i < swingLowsCount; i++) { // XOHCL iSwing = swingLows[i]; // if (!tmpBar.IsValid() || tmpBar.low > iSwing.low) { tmpBar = iSwing; } } if (tmpBar.IsValid()) { // mSwingLow = tmpBar; string name = tmpBar.GetTag(ToString(X_POI_SWING_LOW)); if (mSwingLowObject != NULL) { mSwingLowObject.Delete(); } mSwingLowObject = new CChartObjectHLine(); bool isCreated = mSwingLowObject.Create( ChartIdentification(), name, SubWindowIdentification(), tmpBar.low // ); if (isCreated) { // mSwingLowObject.Width(2); mSwingLowObject.Color(clrLime); mSwingLowObject.Style(STYLE_DASHDOTDOT); } } tmpBar.Clean(); // // Demand Zone ... for (int i = 0; i < demandZonesCount; i++) { // // Demand Zone ... XZone iDemandZone = supplyAndDemandZoneState.demandZones[i]; conditions.demandZone = iDemandZone; // // TODO: Remove this ... // XCDemandZoneObject *iDemandZoneObj; // bool isCreated = mPOIDrawer.CreateDemandZone( // iDemandZone, // iDemandZoneObj // // ); // // Order Blocks ... int orderBlocksCount = ArraySize(orderBlocksState.bullishOrderBlocks); if (IsValidSize(orderBlocksCount)) { // for (int j = 0; j < orderBlocksCount; j++) { // XZone jZone = orderBlocksState.bullishOrderBlocks[j]; // bool isInside = (jZone.lower > iDemandZone.lower && jZone.lower < iDemandZone.upper) || (jZone.lower < iDemandZone.lower); if (isInside) { // jZone.to = TimeCurrent(); // // TODO: Remove this ... // XCBullishOrderBlockObject *iBullOBObj; // bool isCreated = mPOIDrawer.CreateBullishOrderBlock( // jZone, // iBullOBObj // // ); AddRef( jZone, conditions.bullishOrderBlocks // ); } } } // // Support Zones ... int supportsCount = ArraySize(fvgsState.supportZones); if (IsValidSize(supportsCount)) { // for (int j = 0; j < supportsCount; j++) { // XOHCL jBar = fvgsState.supportZones[j]; // bool isInside = (jBar.low > iDemandZone.lower && jBar.low < iDemandZone.upper) || (jBar.low < iDemandZone.lower); if (isInside) { // // TODO: Remove this ... // XCSupportZoneObject *iSupportZoneObj; // bool isCreated = mPOIDrawer.CreateSupportZone( // jBar, // iSupportZoneObj, // TimeCurrent() // // ); // AddRef( jBar, conditions.supports // ); } } } // // Bullish FVGs ... int fvgsCount = ArraySize(fvgsState.bullishFVGs); if (IsValidSize(fvgsCount)) { // for (int j = 0; j < fvgsCount; j++) { // XZone jFVG = fvgsState.bullishFVGs[j]; // bool isInside = jFVG.from > iDemandZone.from && jFVG.lower < iDemandZone.upper && jFVG.upper > iDemandZone.upper; if (isInside) { // jFVG.to = TimeCurrent(); // // TODO: Remove This ... // XCBullishFVGObject *iObj; // bool isCreated = mPOIDrawer.CreateBullishFVG( // jFVG, // iObj // // ); // AddRef( jFVG, conditions.bullishFVGs // ); } } } // // Swing Lows ... int swingLowsCount = ArraySize(triggerState.swingLows); if (IsValidSize(swingLowsCount)) { // for (int j = 0; j < swingLowsCount; j++) { // XOHCL jBar = triggerState.swingLows[j]; // bool isInside = jBar.time > iDemandZone.from && jBar.low > iDemandZone.lower && jBar.GetDown() < iDemandZone.upper; if (isInside) { // // TODO: Remve this ... // XCSwingLowObject *iObj; // bool isCreated = mPOIDrawer.CreateSwingLow( // jBar, // iObj // // ); // AddRef( jBar, conditions.swingLows // ); } } } // // Bullish Momentum Bars ... int bullishMomentumBarsCount = ArraySize(triggerState.momentumBars); if (IsValidSize(bullishMomentumBarsCount)) { // for (int j = 0; j < bullishMomentumBarsCount; j++) { // XOHCL jBar = triggerState.momentumBars[j]; // bool isInside = jBar.IsBullish() && jBar.time > iDemandZone.from && jBar.low > iDemandZone.lower && jBar.low < iDemandZone.upper; if (isInside) { // // TODO: Remove this ... // XCBullishMomentumBarObject *iObj; // bool isCreated = mPOIDrawer.CreateBullishMomentumBar( // jBar, // iObj // // ); // AddRef( jBar, conditions.bullishMomentumBars // ); } } } // // Bullish Rejection Bars ... int bullishRejectionBarsCount = ArraySize(triggerState.rejectionBars); if (IsValidSize(bullishRejectionBarsCount)) { // for (int j = 0; j < bullishRejectionBarsCount; j++) { // XOHCL jBar = triggerState.rejectionBars[j]; // bool isInside = jBar.GetLowShadow() > jBar.GetHighShadow() && jBar.time > iDemandZone.from && jBar.low > iDemandZone.lower && jBar.low < iDemandZone.upper; if (isInside) { // // TODO: Remove this ... XCBullishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishRejectionBar( jBar, iObj // ); // AddRef( jBar, conditions.bullishRejectionBars // ); } } } } // // Supply Zone ... // for (int i = 0; i < demandZonesCount; i++) // { // // // // Supply Zone ... // XZone iSupplyZone = supplyAndDemandZoneState.supplyZones[i]; // conditions.supplyZone = iSupplyZone; // // // // Order Blocks ... // int orderBlocksCount = ArraySize(orderBlocksState.bearishOrderBlocks); // if (IsValidSize(orderBlocksCount)) // { // // // for (int j = 0; j < orderBlocksCount; j++) // { // // // XZone jZone = orderBlocksState.bearishOrderBlocks[j]; // // // bool isInside = // jZone.from > iSupplyZone.from && // jZone.upper > iSupplyZone.lower && // jZone.upper < iSupplyZone.upper; // if (isInside) // { // // // AddRef( // jZone, // conditions.bearishOrderBlocks // // ); // } // } // } // // // // Resistance Zones ... // int resistancesCount = ArraySize(fvgsState.resistanceZones); // if (IsValidSize(resistancesCount)) // { // // // for (int j = 0; j < resistancesCount; j++) // { // // // XOHCL jBar = fvgsState.resistanceZones[j]; // // // bool isInside = // jBar.time > iSupplyZone.from && // jBar.high > iSupplyZone.lower && // jBar.high < iSupplyZone.upper; // if (isInside) // { // // // AddRef( // jBar, // conditions.resistances // // ); // } // } // } // // // // Bearish FVGs ... // int fvgsCount = ArraySize(fvgsState.bearishFVGs); // if (IsValidSize(fvgsCount)) // { // // // for (int j = 0; j < fvgsCount; j++) // { // // // XZone jZone = fvgsState.bearishFVGs[j]; // // // bool isInside = // jZone.from > iSupplyZone.from && // jZone.upper > iSupplyZone.lower && // jZone.upper < iSupplyZone.upper; // if (isInside) // { // // // AddRef( // jZone, // conditions.bearishFVGs // // ); // } // } // } // // // // Swing Highs ... // int swingHighsCount = ArraySize(triggerState.swingHighs); // if (IsValidSize(swingHighsCount)) // { // // // for (int j = 0; j < swingHighsCount; j++) // { // // // XOHCL jBar = triggerState.swingHighs[j]; // // // bool isInside = // jBar.time > iSupplyZone.from && // jBar.high > iSupplyZone.lower && // jBar.high < iSupplyZone.upper; // if (isInside) // { // // // AddRef( // jBar, // conditions.swingHighs // // ); // } // } // } // // // // Bearish Momentum Bars ... // int bearishMomentumBarsCount = ArraySize(triggerState.momentumBars); // if (IsValidSize(bearishMomentumBarsCount)) // { // // // for (int j = 0; j < bearishMomentumBarsCount; j++) // { // // // XOHCL jBar = fvgsState.momentumBars[j]; // // // bool isInside = // jBar.IsBearish() && // jBar.time > iSupplyZone.from && // jBar.high > iSupplyZone.lower && // jBar.high < iSupplyZone.upper; // if (isInside) // { // // // AddRef( // jBar, // conditions.bearishMomentumBars // // ); // } // } // } // // // // Bearish Rejection Bars ... // int bearishRejectionBarsCount = ArraySize(triggerState.rejectionBars); // if (IsValidSize(bearishRejectionBarsCount)) // { // // // for (int j = 0; j < bearishRejectionBarsCount; j++) // { // // // XOHCL jBar = fvgsState.rejectionBars[j]; // // // bool isInside = // jBar.GetHighShadow() > jBar.GetLowShadow() && // jBar.time > iSupplyZone.from && // jBar.high > iSupplyZone.lower && // jBar.high < iSupplyZone.upper; // if (isInside) // { // // // AddRef( // jBar, // conditions.bearishRejectionBars // // ); // } // } // } // } // bool isConditionReadyForDemand = conditions.demandZone.IsValid() && (ArraySize(conditions.supports) > 0 || ArraySize(conditions.swingLows) > 0 || ArraySize(conditions.bullishFVGs) > 0 || ArraySize(conditions.bullishOrderBlocks) > 0 || ArraySize(conditions.bullishMomentumBars) > 0 || ArraySize(conditions.bullishRejectionBars) > 0); // bool isConditionReadyForSupply = conditions.supplyZone.IsValid() && (ArraySize(conditions.swingHighs) > 0 || ArraySize(conditions.bearishFVGs) > 0 || ArraySize(conditions.resistances) > 0 || ArraySize(conditions.bearishOrderBlocks) > 0 || ArraySize(conditions.bearishMomentumBars) > 0 || ArraySize(conditions.bearishRejectionBars) > 0); // result = isConditionReadyForDemand || isConditionReadyForSupply;