/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 X121 SMC Signal Class // ------------------------------------------------- // Name: XWZ // Description: provide all Signalling functions ... // // // 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 "../../Libraries/x-trade.lib" #include "../Classes/x-121.smc.market.cycle.helper.class.mq5" #include "../Libraries/x-121.smc.guard.lib.mq5" #include "../Libraries/x-121.smc.lib.mq5" // // Provided Signals Enumeration ... enum ENUM_X121SMC_XWZ_PROVIDERS { X121SMC_XWZ_PROVIDER_NONE, X121SMC_XWZ_PROVIDER_XWPVZ, X121SMC_XWZ_PROVIDER_XFVGMA, X121SMC_XWZ_PROVIDER_XBREAKED_BOX, X121SMC_XWZ_PROVIDER_XREJECTED_BOX, X121SMC_XWZ_PROVIDER_XACTIVATED_BOX, }; // // Provided Priority based on Working Zone and // Quarter Places ... enum ENUM_X121SMC_XWZ_PRIORITY { X121SMC_XWZ_PRIORITY_NONE, X121SMC_XWZ_PRIORITY_WEAK, X121SMC_XWZ_PRIORITY_LOW, X121SMC_XWZ_PRIORITY_REGULAR, X121SMC_XWZ_PRIORITY_HIGH, X121SMC_XWZ_PRIORITY_STRONG_HIGH, }; // // Definitions ... // // XWZ Working Zone Model ... struct X121SMCStrategyXWZWorkingZone { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // double quarter1; double quarter2; double quarter3; // XCSupplyZone *supplyZone; XCDemandZone *demandZone; // XBoxZone support; XBoxZone resistance; ENUM_X_DIRECTION trend; // XSignalBox waitingBoxes[]; XSignalBox breakedBoxes[]; XSignalBox unavailableBoxes[]; // CArrayObj mDrawnObjects; CArrayObj mWorkingZoneObjects; // // Constructor ... X121SMCStrategyXWZWorkingZone() { Clean(); } // // Properties ... /** * Check Working Zone has Supply Zone as Upper Boundary ... * * @return ( bool ) */ bool HasSupplyZone() { return supplyZone != NULL && supplyZone.IsValid(); } /** * Check Working Zone has Demand Zone as Lower Boundary ... * * @return ( bool ) */ bool HasDemandZone() { return demandZone != NULL && demandZone.IsValid(); } /** * Check Working Zone has Waiting Boxes or not ... * * @return ( bool ) */ bool HasWaitingBoxes() { return HasChild(waitingBoxes); } /** * Count Working Zone's Waiting Boxes ... * * @return ( int ) */ int CountWaitingBoxes() { return ArraySize(waitingBoxes); } /** * Check Working Zone has Breaked Boxes or not ... * * @return ( bool ) */ bool HasBreakedBoxes() { return HasChild(breakedBoxes); } /** * Count Working Zone's Breaked Boxes ... * * @return ( int ) */ int CountBreakedBoxes() { return ArraySize(breakedBoxes); } /** * Check Working Zone has Unavailable Boxes or not ... * * @return ( bool ) */ bool HasUnavailableBoxes() { return HasChild(unavailableBoxes); } /** * Count Working Zone's Unavailable Boxes ... * * @return ( int ) */ int CountUnavailableBoxes() { return ArraySize(unavailableBoxes); } // // Tools ... /** * Cleanup Model ... */ void Clean() { // quarter1 = 0; quarter2 = 0; quarter3 = 0; // symbol = NULL; period = NULL; // Clean(waitingBoxes); Clean(breakedBoxes); Clean(unavailableBoxes); // ZeroMemory(supplyZone); ZeroMemory(demandZone); // mDrawnObjects.Clear(); mWorkingZoneObjects.Clear(); } /** * Validate Model ... * * @return ( bool ) */ bool IsValid() { // bool result = false; // result = // quarter1 > 0 && quarter2 > 0 && quarter3 > 0 && HasSupplyZone() && HasDemandZone() && quarter1 > quarter2 && quarter2 > quarter3 // ; // return result; } /** * Checking a Box Exists in Collections or not ... * * @param box: XBoxZone instance reference ... * * @return ( bool ) */ bool IsExists(XSignalBox &box) { // bool result = false; // // Check Validation ... result = box.IsValid() && (HasWaitingBoxes() || HasBreakedBoxes() || HasUnavailableBoxes()); if (!result) { return result; } // int idx = -1; bool has = false; // // Check Index in Waiting Boxes ... has = HasWaitingBoxes(); if (has) { // result = FindIndex( idx, box, waitingBoxes // ); if (result) { return result; } } // // Check Index in Breaked Boxes ... has = HasBreakedBoxes(); if (has) { // result = FindIndex( idx, box, breakedBoxes // ); if (result) { return result; } } // // Check Index in Unavailable Boxes ... has = HasUnavailableBoxes(); if (has) { // result = FindIndex( idx, box, unavailableBoxes // ); if (result) { return result; } } // return result; } /** * Initialize Working Zone ... * * @param _symbol: String ... * @param _period: ENUM_TIMEFRAMES member ... * @param barIndex: int ... * @param provider: X121SMCStrategySignalProviderData instance reference ... * * @return ( bool ) */ bool Init( string _symbol, ENUM_TIMEFRAMES _period, int barIndex, X121SMCStrategySignalProviderData &provider // ) { // bool result = false; // if (barIndex < 0) { barIndex = 0; } // result = // IsValid(_symbol) && IsValid(_period) && // provider.IsValid() // ; if (!result) { return result; } // symbol = _symbol; period = _period; // int idx = -1; int count = 0; bool has = false; // XOHCL zBar; has = zBar.Init( symbol, period, barIndex // ); result = has; if (!result) { zBar.Clean(); return result; } double ll5 = zBar.FindLowest(5, MODE_LOW); double hh5 = zBar.FindHighest(5, MODE_HIGH); zBar.Clean(); // // Supply Zone ... has = HasSupplyZone(); if (!has) { // idx = GetHighest(provider .consolidationState .supplyZones // ); has = IsValidIndex(idx); if (has) { // supplyZone = provider .consolidationState .supplyZones[idx]; has = hh5 < supplyZone.Lower(); if (!has) { supplyZone = NULL; } } } // // Demand Zone ... has = HasDemandZone(); if (!has) { // idx = GetLowest(provider .consolidationState .demandZones // ); has = IsValidIndex(idx); if (has) { // demandZone = provider .consolidationState .demandZones[idx]; has = ll5 > demandZone.Upper(); if (!has) { demandZone = NULL; } } } // if (supplyZone != NULL && demandZone != NULL && supplyZone.IsValid() && demandZone.IsValid()) { // double upper = supplyZone.Lower(); double lower = demandZone.Upper(); // double delta = ((upper - lower) / 100) * 25; // quarter1 = upper - (1 * delta); quarter2 = upper - (2 * delta); quarter3 = upper - (3 * delta); } // result = IsValid(); if (!result) { Clean(); } // return result; } /** * Detect Signal Boxes ... * * @param cycle: ENUM_X_CYCLES member ... * @param provider: X121SMCStrategySignalProviderData instance reference ... * @param barIndex: int ... * * @return ( bool ) */ bool DetectWaitingBoxes( ENUM_X_CYCLES obCycle, ENUM_X_CYCLES fvgCycle, X121SMCStrategySignalProviderData &provider, int barIndex = 0 // ) { // bool result = false; // int idx = -1; int count = 0; bool has = false; datetime cTime = TimeCurrent(); // if (barIndex < 0) { barIndex = 0; } // // Select OB Cycle ... XPOIState obState; XPOIStateEvents obStateEvents; X121Conditions obXConditions; XC121SMCCycleHelper *obHelper; X121SMCCycleConditions obConditions; result = provider.SelectCycle( obCycle, obState, obStateEvents, obXConditions, obHelper, obConditions // ); if (!result) { // obState.Clean(); ZeroMemory(obHelper); obConditions.Clean(); obStateEvents.Clean(); obXConditions.Clean(); // return result; } // // Select FVG Cycle ... XPOIState fvgState; XPOIStateEvents fvgStateEvents; X121Conditions fvgXConditions; XC121SMCCycleHelper *fvgHelper; X121SMCCycleConditions fvgConditions; result = provider.SelectCycle( fvgCycle, fvgState, fvgStateEvents, fvgXConditions, fvgHelper, fvgConditions // ); if (!result) { // obState.Clean(); ZeroMemory(obHelper); obConditions.Clean(); obStateEvents.Clean(); obXConditions.Clean(); // fvgState.Clean(); ZeroMemory(fvgHelper); fvgConditions.Clean(); fvgStateEvents.Clean(); fvgXConditions.Clean(); // return result; } // // Detect a Sharp Zone Which Contains // an Order Block and Also an FVG ... if (obStateEvents.hasNewSharp) { // XBoxZone ob; XBoxZone fvg; XBoxZone currSharp; XBoxZone prevSharp; XBoxZone sharpConsolidation; // // Retrieve Current Sharp ... XBoxZone tmpBoxes[]; Copy( obState.sharps, tmpBoxes // ); idx = GetYoungest(tmpBoxes); has = IsValidIndex(idx); if (has) { // currSharp = tmpBoxes[idx]; bool isBullish = currSharp.IsBullish(); // ArrayRemove( tmpBoxes, idx, 1 // ); // while (HasChild(tmpBoxes)) { // idx = GetYoungest(tmpBoxes); has = IsValidIndex(idx); // if (!has) { break; } // XBoxZone iBox = tmpBoxes[idx]; ArrayRemove( tmpBoxes, idx, 1 // ); // if (iBox.dir == currSharp.dir) { // prevSharp = iBox; iBox.Clean(); break; } // iBox.Clean(); } // Clean(tmpBoxes); } Clean(tmpBoxes); // // Preparing Sharp Consolidation Box ... has = currSharp.IsValid() && prevSharp.IsValid() && prevSharp.lower < currSharp.upper; if (has) { // sharpConsolidation.type = "XSHCNZ"; sharpConsolidation.dir = currSharp.dir; sharpConsolidation.symbol = currSharp.symbol; sharpConsolidation.period = currSharp.period; // sharpConsolidation.from = prevSharp.to; sharpConsolidation.to = currSharp.from; // int toIDX = GetBarIndex( currSharp.symbol, currSharp.period, sharpConsolidation.to // ); int fromIDX = GetBarIndex( currSharp.symbol, currSharp.period, sharpConsolidation.from // ); int length = fromIDX - toIDX; // XOHCL toBar; has = toBar.Init( sharpConsolidation.symbol, sharpConsolidation.period, toIDX // ); // if (has) { // double upper = toBar.FindHighest( length, MODE_HIGH // ); // double lower = toBar.FindLowest( length, MODE_LOW // ); // sharpConsolidation.upper = upper; sharpConsolidation.lower = lower; } // // Detect Order Block / FVG ... has = sharpConsolidation.IsValid(); if (has) { // // Check Direction ... bool isBullish = sharpConsolidation.IsBullish(); // // Find Inside Order Block ... Clean(tmpBoxes); if (isBullish) { // ToBox( obState.bullishOrderBlocks, tmpBoxes // ); } else { // ToBox( obState.bearishOrderBlocks, tmpBoxes // ); } // // Select Order Block ... has = HasChild(tmpBoxes); if (has) { // while (HasChild(tmpBoxes)) { // idx = GetYoungest(tmpBoxes); has = IsValidIndex(idx); if (!has) { break; } // XBoxZone iBox = tmpBoxes[idx]; ArrayRemove( tmpBoxes, idx, 1 // ); // // Validate Selected Box ... bool isDirPassed = iBox.dir == sharpConsolidation.dir; bool isFromPassed = iBox.from > sharpConsolidation.from; bool isInsidePassed = IsBoxInside( iBox, sharpConsolidation // ); bool isValidationPassed = IsBoxValid( iBox, barIndex // ); // has = isDirPassed && isFromPassed && isInsidePassed && isValidationPassed; if (has) { ob = iBox; } // iBox.Clean(); // if (ob.IsValid()) { break; } } } Clean(tmpBoxes); // // Find Inside FVG ... has = ob.IsValid(); if (has) { // Clean(tmpBoxes); if (isBullish) { // ToBox( fvgState.bullishFairValueGaps, tmpBoxes // ); } else { // ToBox( fvgState.bearishFairValueGaps, tmpBoxes // ); } // // Select FVG ... has = HasChild(tmpBoxes); if (has) { // while (HasChild(tmpBoxes)) { // idx = isBullish ? GetLowest(tmpBoxes) : GetHighest(tmpBoxes); has = IsValidIndex(idx); if (!has) { break; } // XBoxZone iBox = tmpBoxes[idx]; ArrayRemove( tmpBoxes, idx, 1 // ); // // Validate Selected Box ... bool isDirPassed = iBox.dir == ob.dir; bool isFromPassed = iBox.from > ob.from; bool isInsidePassed = IsBoxInside( iBox, ob // ); // has = isDirPassed && isFromPassed && isInsidePassed; if (has) { fvg = iBox; } // iBox.Clean(); // if (fvg.IsValid()) { break; } } } Clean(tmpBoxes); } } // // Checking Validation of Boxes ... has = ob.IsValid() && fvg.IsValid() && sharpConsolidation.IsValid(); if (has) { // // Update Time ... ob.to = cTime; fvg.to = cTime; sharpConsolidation.to = cTime; // XSignalBox iSBox; // iSBox.ob = ob; iSBox.fvg = fvg; iSBox.sharp = sharpConsolidation; // has = iSBox.IsValid(); if (has) { // AddRef( iSBox, waitingBoxes // ); } // iSBox.Clean(); } // ob.Clean(); fvg.Clean(); toBar.Clean(); currSharp.Clean(); prevSharp.Clean(); sharpConsolidation.Clean(); } // Clean(tmpBoxes); currSharp.Clean(); prevSharp.Clean(); sharpConsolidation.Clean(); } // // Preparing Waiting Box based on FVG State ... if (fvgStateEvents.hasNewSharp) { // // Select Newest Sharp Change ... XBoxZone sharp; idx = GetYoungest(fvgState.sharps); has = IsValidIndex(idx); if (has) { // XOHCL endBar; XOHCL startBar; int totalBars = 0; int orderBlocksIDX[]; int bullBarsCount = 0; int bearBarsCount = 0; int validPercent = 75; // sharp = fvgState.sharps[idx]; sharp.type = "XSHPOBX"; bool isSharpBullish = sharp.IsBullish(); // // Validate End Bar ... if (sharp.IsValid()) { // // Validate End Bar Direction ... int endBarIDX = GetBarIndex( sharp.symbol, sharp.period, sharp.to // ); // has = endBar.Init( sharp.symbol, sharp.period, endBarIDX + 1 // ); // if (has) { // has = sharp.dir == endBar.GetDirection(); if (!has) { sharp.Clean(); } } } // // Validate Start Bar ... if (sharp.IsValid()) { // // Validate Start Bar Direction ... int startBarIDX = GetBarIndex( sharp.symbol, sharp.period, sharp.from // ); // has = startBar.Init( sharp.symbol, sharp.period, startBarIDX + 1 // ); // if (has) { // has = sharp.dir == Opposit(startBar.GetDirection()); if (!has) { sharp.Clean(); } } } // // Validate OrderBlocks ... if (sharp.IsValid()) { // int end = endBar.Index(); int start = startBar.Index(); for (int i = start; i >= end; i--) { // XOHCL iBar; has = iBar.Init( sharp.symbol, sharp.period, i // ); if (!has) { // iBar.Clean(); continue; } // totalBars++; // bool isBullish = iBar.IsBullish(); if (isBullish) { // bullBarsCount++; // if (!isSharpBullish) { // Add( i, orderBlocksIDX // ); } } else { // bearBarsCount++; // if (isSharpBullish) { // Add( i, orderBlocksIDX // ); } } // iBar.Clean(); } // // Follow Order Blocks ... has = HasChild(orderBlocksIDX); if (has) { // int bullBarsPercent = (bullBarsCount * 100) / totalBars; int bearBarsPercent = (bearBarsCount * 100) / totalBars; // has = isSharpBullish ? bullBarsPercent >= validPercent : bearBarsPercent >= validPercent; if (has) { // // Prepare Waiting Boxes ... count = ArraySize(orderBlocksIDX); for (int i = 0; i < count; i++) { // XOHCL iBar; has = iBar.Init( sharp.symbol, sharp.period, orderBlocksIDX[i] // ); if (!has) { // iBar.Clean(); continue; } // XBoxZone iOB; XBoxZone iFVG; // iOB.to = sharp.to; iOB.type = "XOBX"; iOB.dir = sharp.dir; iOB.from = iBar.time; iOB.lower = iBar.low; iOB.upper = iBar.high; iOB.period = iBar.period; iOB.symbol = iBar.symbol; // // Select FVG ... has = iOB.IsValid(); if (has) { // // Select FVG ... has = HasChild(fvgState.fairValueGaps); if (has) { // XBoxZone tmpBoxes[]; if (isSharpBullish) { // ToBox( fvgState.bullishFairValueGaps, tmpBoxes // ); } else { // ToBox( fvgState.bearishFairValueGaps, tmpBoxes // ); } has = HasChild(tmpBoxes); if (has) { // while (HasChild(tmpBoxes)) { // idx = GetYoungest(tmpBoxes); has = IsValidIndex(idx); if (!has) { break; } // XBoxZone iBox = tmpBoxes[idx]; ArrayRemove( tmpBoxes, idx, 1 // ); // // Validate FVG ... bool isDirPassed = iBox.dir == sharp.dir; bool isFromPassed = iBox.from >= iOB.from; bool isPricePassed = IsBoxInsideOr(iBox, iOB); // has = isDirPassed && isFromPassed && isPricePassed; if (has) { // iFVG = iBox; iBox.Clean(); break; } // iBox.Clean(); } } Clean(tmpBoxes); } } // has = sharp.IsValid() && iOB.IsValid() && iFVG.IsValid(); if (has) { // XSignalBox iSBox; // iSBox.ob = iOB; iSBox.fvg = iFVG; iSBox.sharp = sharp; // AddRef( iSBox, waitingBoxes // ); // iSBox.Clean(); } // iOB.Clean(); iFVG.Clean(); iBar.Clean(); } } } else { // // Follow Non Order Block ... // First Found FVGs ... XBoxZone iOB; XBoxZone iFVG; XBoxZone tmpBoxes[]; if (isSharpBullish) { // ToBox( fvgState.bullishFairValueGaps, tmpBoxes // ); } else { // ToBox( fvgState.bearishFairValueGaps, tmpBoxes // ); } has = HasChild(tmpBoxes); if (has) { // while (HasChild(tmpBoxes)) { // idx = GetYoungest(tmpBoxes); has = IsValidIndex(idx); if (!has) { break; } // XBoxZone iBox = tmpBoxes[idx]; ArrayRemove( tmpBoxes, idx, 1 // ); // // Validate FVG ... bool isDirPassed = iBox.dir == sharp.dir; bool isFromPassed = iBox.from >= sharp.from; bool isPricePassed = IsBoxInside(iBox, sharp); // has = isDirPassed && isFromPassed && isPricePassed; if (has) { // iFVG = iBox; // // Now we Have to Create an Order Block ... // XOHCL iToBar; XOHCL iFromBar; // int fromIDX = GetBarIndex( iBox.symbol, iBox.period, iBox.from // ); int toIDX = GetBarIndex( iBox.symbol, iBox.period, iBox.to // ); has = iToBar.Init( iBox.symbol, iBox.period, toIDX // ); has = has && iFromBar.Init( iBox.symbol, iBox.period, fromIDX // ); if (!has) { // iBox.Clean(); iToBar.Clean(); iFromBar.Clean(); // break; } // iOB.to = iBox.to; iOB.type = "XOBX"; iOB.dir = iBox.dir; iOB.from = iBox.from; iOB.symbol = iBox.symbol; iOB.period = iBox.period; iOB.lower = MathMin(iToBar.low, iFromBar.low); iOB.upper = MathMax(iToBar.high, iFromBar.high); // iBox.Clean(); iToBar.Clean(); iFromBar.Clean(); break; } // iBox.Clean(); } } Clean(tmpBoxes); // has = iOB.IsValid() && iFVG.IsValid() && sharp.IsValid(); if (has) { // XSignalBox iSBox; // iSBox.ob = iOB; iSBox.fvg = iFVG; iSBox.sharp = sharp; // AddRef( iSBox, waitingBoxes // ); // iSBox.Clean(); } // iOB.Clean(); iFVG.Clean(); } } // endBar.Clean(); startBar.Clean(); Clean(orderBlocksIDX); } } // count = CountWaitingBoxes(); result = IsValidSize(count); // // Cleanup Resources ... // obState.Clean(); ZeroMemory(obHelper); obConditions.Clean(); obStateEvents.Clean(); obXConditions.Clean(); // fvgState.Clean(); ZeroMemory(fvgHelper); fvgConditions.Clean(); fvgStateEvents.Clean(); fvgXConditions.Clean(); // return result; } /** * Validating Waiting Boxes and Detect Breaked Boxes ... * * @param barIndex: int ... * * @return ( int ) */ int ValidateWaitingBoxes( int barIndex = 0 // ) { // int result = 0; // bool has = false; // if (barIndex < 0) { barIndex = 0; } // if (barIndex == 0) { barIndex = 1; } // has = HasWaitingBoxes(); if (!has) { return result; } // int removeIDX[]; result = CountWaitingBoxes(); for (int i = 0; i < result; i++) { // XOHCL iBar; XSignalBox iBox = waitingBoxes[i]; bool isInite = iBar.Init( iBox.ob.symbol, iBox.ob.period, iBox.ob.from // ); // has = isInite && ( // IsBoxBreaked( iBox.ob, iBar.Index() - 1, barIndex, period // ) // ); if (has) { // Add( i, removeIDX // ); // AddRef( iBox, breakedBoxes // ); } // // iBox.Clean(); iBar.Clean(); } // has = HasChild(removeIDX); if (has) { // CleanupArray( removeIDX, waitingBoxes // ); } Clean(removeIDX); // result = CountWaitingBoxes(); // return result; } /** * Detect Trend Based On Boxes ... * * @param dir: ENUM_X_DIRECTION ember ... * * @return ( bool ) */ bool DetectTreand( ENUM_X_CYCLES cycle, ENUM_X_DIRECTION &dir, X121SMCStrategySignalProviderData &provider, int barIndex = 0 // ) { // bool result = false; // support.Clean(); resistance.Clean(); dir = X_DIRECTION_NONE; trend = X_DIRECTION_NONE; // if (barIndex < 0) { barIndex = 0; } // result = IsValid(cycle); if (!result) { return result; } // // Select Cycle ... XPOIState cState; XPOIStateEvents cStateEvents; X121Conditions cXConditions; XC121SMCCycleHelper *cHelper; X121SMCCycleConditions cConditions; result = provider.SelectCycle( cycle, cState, cStateEvents, cXConditions, cHelper, cConditions // ); if (!result) { // cState.Clean(); ZeroMemory(cHelper); cConditions.Clean(); cStateEvents.Clean(); cXConditions.Clean(); // return result; } // // Detect Trend ... // int idx = -1; bool has = false; // XBoxZone tmp[]; XBoxZone tmpBoxes[]; // // Select Supports ... ToBox( cState.supportZones, tmp // ); Copy( tmp, tmpBoxes, false // ); Clean(tmp); // // Select Resistances ... ToBox( cState.resistanceZones, tmp // ); Copy( tmp, tmpBoxes, false // ); Clean(tmp); // result = HasChild(tmpBoxes); if (!result) { // Clean(tmpBoxes); // cState.Clean(); ZeroMemory(cHelper); cConditions.Clean(); cStateEvents.Clean(); cXConditions.Clean(); // return result; } // // Select Youngest Valid Zone ... while (HasChild(tmpBoxes) || !(support.IsValid() && resistance.IsValid())) { // // Check Yongest Zone ... idx = GetYoungest(tmpBoxes); has = IsValidIndex(idx); if (!has) { break; } // // Remove Extracted Box ... XBoxZone iBox = tmpBoxes[idx]; ArrayRemove( tmpBoxes, idx, 1 // ); // // Check Validation of Box ... has = IsBoxValid( iBox, barIndex, period // ); if (!has) { // iBox.Clean(); continue; } // // Assign Support or Resistance ... bool isBullish = iBox.IsBullish(); if (isBullish && !support.IsValid()) { support = iBox; } else if (!isBullish && !resistance.IsValid()) { resistance = iBox; } // // Validate Support and Resistance ... has = support.IsValid() && resistance.IsValid(); if (!has) { // iBox.Clean(); continue; } // iBox.Clean(); } // // Checking Result ... bool isBullish = support.from > resistance.from; bool isBearish = support.from < resistance.from; result = isBullish || isBearish; if (result) { // dir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; trend = dir; // support.to = TimeCurrent(); resistance.to = TimeCurrent(); } // // Cleanup Resources ... // Clean(tmp); cState.Clean(); Clean(tmpBoxes); ZeroMemory(cHelper); cConditions.Clean(); cStateEvents.Clean(); cXConditions.Clean(); // return result; } /** * Update all Collections Members To Time ... * * @param value: datetime, Specified To Time ... */ void UpdateTo(datetime value = NULL) { // value = NormalizeTime(value); // int count = 0; bool has = false; // has = HasSupplyZone(); if (has) { supplyZone.To(value); } // has = HasDemandZone(); if (has) { demandZone.To(value); } // has = HasWaitingBoxes(); if (has) { // count = CountWaitingBoxes(); for (int i = 0; i < count; i++) { waitingBoxes[i].UpdateTo(value); } } // } /** * Check Working Zone is Destroyed or not ... * * @param barIndex: int, bar index ... * @param forPeriod: ENUM_TIMEFRAMES member ... * * @return ( bool ) */ bool IsDestroyed( int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = period; } // result = IsValid(); if (!result) { return result; } // XOHCL bar; result = bar.Init( symbol, period, barIndex // ); if (!result) { // bar.Clean(); return result; } // XOHCL cBar; result = bar.GetPreviousBar(cBar); if (!result) { // bar.Clean(); cBar.Clean(); // return result; } // bool isSupplyZoneBreaked = // bar.low > supplyZone.Upper() && cBar.low > supplyZone.Upper() // ; // bool isDemandZoneBreaked = // bar.high < demandZone.Lower() && cBar.high < demandZone.Lower() // ; // bar.Clean(); cBar.Clean(); // result = isSupplyZoneBreaked || isDemandZoneBreaked; // return result; } /** * Detect Signal Box Conditions ... * * @param box: XBoxZone instance reference, Signalled Box ... * @param dir: ENUM_X_DIRECTION member, Specified Signal Direction ... * @param signalProvider: ENUM_X121SMC_XWZ_PROVIDERS member, Specified Signal Type ... * @param provider: X121SMCStrategySignalProviderData instance reference ... * @param barIndex: int ... * * @return ( bool ) */ bool DetectSignalConditions( XSignalBox &box, ENUM_X_DIRECTION &dir, ENUM_X121SMC_XWZ_PROVIDERS &signalProvider, X121SMCStrategySignalProviderData &provider, int barIndex = 0 // ) { // bool result = false; // // Normalize Bars ... // box.Clean(); dir = X_DIRECTION_NONE; signalProvider = X121SMC_XWZ_PROVIDER_NONE; // if (barIndex < 0) { barIndex = 0; } // // TODO: Ignor Working Zone Validation ... // result = IsValid(); // if (!result) // { // return result; // } // int idx = -1; int count = 0; bool has = false; // int zIDX = barIndex; int cIDX = zIDX + 1; int pIDX = cIDX + 1; // bool isBullish = false; bool isBearish = false; // X121SMCStrategyConditionParser cParser; // // Senario 1: // --------------------------------------------- // Rejected Box ... // --------------------------------------------- bool useSenario1 = false; bool isSenario1Happend = false; bool isSenario1Bullish = false; bool isSenario1Bearish = false; if (useSenario1) { // isSenario1Happend = cParser.HasRejectedBoxConditions( X_CYCLE_DECISION, box, dir, waitingBoxes, provider, barIndex // ); // isSenario1Bullish = isSenario1Happend && IsBullish(dir); // isSenario1Bearish = isSenario1Happend && IsBearish(dir); // if (isSenario1Happend) { signalProvider = X121SMC_XWZ_PROVIDER_XREJECTED_BOX; } } // // Senario 2: // --------------------------------------------------- // Activated Box ... // --------------------------------------------------- bool useSenario2 = false; bool isSenario2Happend = false; bool isSenario2Bullish = false; bool isSenario2Bearish = false; if (!isSenario1Happend && useSenario2) { // isSenario2Happend = cParser.HasActivatedBoxConditions( X_CYCLE_DECISION, box, dir, waitingBoxes, provider, barIndex // ); // isSenario2Bullish = isSenario2Happend && IsBullish(dir); // isSenario2Bearish = isSenario2Happend && IsBearish(dir); // if (isSenario2Happend) { signalProvider = X121SMC_XWZ_PROVIDER_XACTIVATED_BOX; } } // // Senario 3: // --------------------------------------------------- // Breaked Box ... // --------------------------------------------------- bool useSenario3 = false; bool isSenario3Happend = false; bool isSenario3Bullish = false; bool isSenario3Bearish = false; if (!isSenario1Happend && !isSenario2Happend && useSenario3) { // isSenario3Happend = cParser.HasBreakedBoxConditions( X_CYCLE_DECISION, box, dir, breakedBoxes, provider, barIndex // ); // isSenario3Bullish = isSenario3Happend && IsBullish(dir); // isSenario3Bearish = isSenario3Happend && IsBearish(dir); // if (isSenario3Happend) { signalProvider = X121SMC_XWZ_PROVIDER_XACTIVATED_BOX; } } // // Senario 4: // ----------------------------------------------- // Detect Signal Box Based On FVG Conditions ... // ----------------------------------------------- bool useSenario4 = false; bool isSenario4Happend = false; bool isSenario4Bullish = false; bool isSenario4Bearish = false; if (!isSenario1Happend && !isSenario2Happend && !isSenario3Happend && useSenario4) { // isSenario4Happend = cParser.HasXFVGMAConditions( X_CYCLE_DECISION, box, dir, waitingBoxes, provider, barIndex // ); // isSenario4Bullish = isSenario4Happend && IsBullish(dir); // isSenario4Bearish = isSenario4Happend && IsBearish(dir); // if (isSenario4Happend) { signalProvider = X121SMC_XWZ_PROVIDER_XFVGMA; } } // // Senario 5: // --------------------------------------------- // XWPVZ ... // --------------------------------------------- bool useSenario5 = true; bool isSenario5Happend = false; bool isSenario5Bullish = false; bool isSenario5Bearish = false; if (!isSenario1Happend && !isSenario2Happend && !isSenario3Happend && !isSenario4Happend && useSenario5) { // isSenario5Happend = cParser.HasXWPVZConditions( X_CYCLE_DECISION, X_CYCLE_CONSOLIDATION, box, dir, provider, barIndex // ); // isSenario5Bullish = isSenario5Happend && IsBullish(dir); // isSenario5Bearish = isSenario5Happend && IsBearish(dir); // if (isSenario5Happend) { signalProvider = X121SMC_XWZ_PROVIDER_XWPVZ; } } // // Senario 6: // --------------------------------------------- // --------------------------------------------- bool useSenario6 = false; bool isSenario6Happend = false; bool isSenario6Bullish = false; bool isSenario6Bearish = false; if (!isSenario1Happend && !isSenario2Happend && !isSenario3Happend && !isSenario4Happend && !isSenario5Happend && useSenario6) { } // // Summarize All Senario(s) Conditions ... // isBullish = // isSenario1Bullish || isSenario2Bullish || isSenario3Bullish || isSenario4Bullish || isSenario5Bullish || isSenario6Bullish // ; // isBearish = // isSenario1Bearish || isSenario2Bearish || isSenario3Bearish || isSenario4Bearish || isSenario5Bearish || isSenario6Bearish // ; // // Check All Conditions ... result = box.IsValid() && HasDirection(dir) && (isBullish || isBearish); // if (!result) { box.Clean(); } // cPraser.Clean(); // return result; } /** * Detect a Signal Priority forDynamic Risk Reward ratio ... * * @param priority: ENUM_X121SMC_XWZ_PRIORITY member, holds Specified position Priority ... * @param forDir: ENUM_X_DIRECTION member, Specified Position Direction for Priority ... * @param barIndex: int ... * @param forPeriod: ENUM_TIMEFRAMES member ... * * @return ( bool ) */ bool DetectPriority( ENUM_X121SMC_XWZ_PRIORITY &priority, ENUM_X_DIRECTION forDir, int barIndex = 0, ENUM_TIMEFRAMES forPeriod = NULL // ) { // bool result = false; // priority = X121SMC_XWZ_PRIORITY_NONE; // if (barIndex < 0) { barIndex = 0; } // if (!IsValid(forPeriod)) { forPeriod = period; } // result = IsValid() && HasDirection(forDir); if (!result) { return result; } // bool isBullish = IsBullish(forDir); // XOHCL bar; result = bar.Init( symbol, forPeriod, barIndex // ); if (!result) { // bar.Clean(); return result; } // if (bar.high < supplyZone.Upper() && bar.low > supplyZone.Lower()) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_NONE : X121SMC_XWZ_PRIORITY_STRONG_HIGH; } else if (bar.high < supplyZone.Lower() && bar.low > quarter1) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_WEAK : X121SMC_XWZ_PRIORITY_HIGH; } else if (bar.high < quarter1 && bar.low > quarter2) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_LOW : X121SMC_XWZ_PRIORITY_REGULAR; } else if (bar.high < quarter2 && bar.low > quarter3) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_REGULAR : X121SMC_XWZ_PRIORITY_LOW; } else if (bar.high < quarter3 && bar.low > demandZone.Upper()) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_HIGH : X121SMC_XWZ_PRIORITY_WEAK; } else if (bar.high < demandZone.Upper() && bar.low > demandZone.Lower()) { // priority = isBullish ? X121SMC_XWZ_PRIORITY_STRONG_HIGH : X121SMC_XWZ_PRIORITY_NONE; } // result = priority != X121SMC_XWZ_PRIORITY_NONE && priority != X121SMC_XWZ_PRIORITY_WEAK; // bar.Clean(); // return result; } /** * Draw Working Zne and all of * it's Collections and Conditions ... * * @param drawSupplyZone: boolean ... * @param drawDemandZone: boolean ... * @param drawWaitingBoxes: boolean ... */ void Draw( XCPOIDrawer *drawer, bool drawSupplyZone = false, bool drawDemandZone = false, bool drawWaitingBoxes = false, bool drawTrend = false // ) { // if (drawer == NULL) { return; } // int count = 0; bool has = false; bool isCreated = false; // ulong chartID = drawer.ChartIdentification(); int subWindow = drawer.SubWindowIdentification(); color bullishColor = drawer.BarBullishColor(); color bearishColor = drawer.BarBearishColor(); // // Supply Zone ... if (drawSupplyZone) { // has = HasSupplyZone(); if (has) { // XCSupplyZoneObject *iObj; isCreated = drawer.CreateSupplyZone( supplyZone, iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } // // Demand Zone ... if (drawDemandZone) { // has = HasDemandZone(); if (has) { // XCDemandZoneObject *iObj; isCreated = drawer.CreateDemandZone( demandZone, iObj // ); // if (isCreated) { mWorkingZoneObjects.Add(iObj); } } } // // // // // Quarters ... has = IsValid(); if (has) { // double zoneUpper = supplyZone.Upper(); double upper = supplyZone.Lower(); // double lower = demandZone.Upper(); double zoneLower = demandZone.Lower(); // string prefix = "X121WZone_" + symbol + "_" + ToString(period); // // Zone Upper ... CChartObjectHLine *zoneUpperLine; zoneUpperLine = new CChartObjectHLine(); isCreated = zoneUpperLine.Create( chartID, prefix + "_ZoneTop", subWindow, zoneUpper // ); if (isCreated) { // zoneUpperLine.Color(clrRed); // mWorkingZoneObjects.Add(zoneUpperLine); } // // Zone Lower ... CChartObjectHLine *zoneLowerLine; zoneLowerLine = new CChartObjectHLine(); isCreated = zoneLowerLine.Create( chartID, prefix + "_ZoneDown", subWindow, zoneLower // ); if (isCreated) { // zoneLowerLine.Color(clrRed); // mWorkingZoneObjects.Add(zoneLowerLine); } // // Upper ... CChartObjectHLine *upperLine; upperLine = new CChartObjectHLine(); isCreated = upperLine.Create( chartID, prefix + "_Upper", subWindow, upper // ); if (isCreated) { // upperLine.Color(clrLime); // mWorkingZoneObjects.Add(upperLine); } // // Lower ... CChartObjectHLine *lowerLine; lowerLine = new CChartObjectHLine(); isCreated = lowerLine.Create( chartID, prefix + "_Lower", subWindow, lower // ); if (isCreated) { // lowerLine.Color(clrLime); // mWorkingZoneObjects.Add(lowerLine); } // // Quarters ... // // Quarter 1 ... CChartObjectHLine *q1Line; q1Line = new CChartObjectHLine(); isCreated = q1Line.Create( chartID, prefix + "_Q1", subWindow, quarter1 // ); if (isCreated) { // q1Line.Color(clrYellow); // mWorkingZoneObjects.Add(q1Line); } // // Quarter 2 ... CChartObjectHLine *q2Line; q2Line = new CChartObjectHLine(); isCreated = q2Line.Create( chartID, prefix + "_Q2", subWindow, quarter2 // ); if (isCreated) { // q2Line.Color(clrYellow); // mWorkingZoneObjects.Add(q2Line); } // // Quarter 3 ... CChartObjectHLine *q3Line; q3Line = new CChartObjectHLine(); isCreated = q3Line.Create( chartID, prefix + "_Q3", subWindow, quarter3 // ); if (isCreated) { // q3Line.Color(clrYellow); // mWorkingZoneObjects.Add(q3Line); } } // // Waiting Zones ... if (drawWaitingBoxes) { // has = HasWaitingBoxes(); if (has) { // count = CountWaitingBoxes(); for (int i = 0; i < count; i++) { // XCBaseObject *objects[]; has = drawer.DrawSignalBox( waitingBoxes[i], objects // ); if (has) { // int objectsCount = ArraySize(objects); for (int i = 0; i < objectsCount; i++) { mWorkingZoneObjects.Add(objects[i]); } } Clean(objects); } } } // // Draw Trend if Exists ... if (drawTrend) { // // Check Trend Exists ... has = support.IsValid() && HasDirection(trend) && resistance.IsValid(); if (has) { // // Draw Support ... XCBoxObject *supportObject; has = drawer.DrawBox( support, supportObject // ); if (has) { mWorkingZoneObjects.Add(supportObject); } // // Draw Resistance ... XCBoxObject *resistanceObject; has = drawer.DrawBox( resistance, resistanceObject // ); if (has) { mWorkingZoneObjects.Add(resistanceObject); } } } // } // }; // // XWZ Signal Conditions ... struct X121SMCStrategyXWZSignalConditions { // // Props ... // string symbol; ENUM_TIMEFRAMES period; // double sl; double reward; double amountPercent; ENUM_X_DIRECTION dir; ENUM_X_POSITION_TYPES type; // // Setup Props ... // datetime setupTime; datetime triggerTime; // double pivot; double point; double sls[]; double targets[]; // XBoxZone signalBox; // ENUM_X121SMC_XWZ_PRIORITY priority; ENUM_X121SMC_XWZ_PROVIDERS provider; // // Constructor ... X121SMCStrategyXWZSignalConditions() { Clean(); } // // Tools ... /** * Cleaning Up ... */ void Clean() { // sl = 0; // dir = X_DIRECTION_NONE; type = X_POSITION_TYPE_NONE; // symbol = NULL; period = NULL; setupTime = NULL; triggerTime = NULL; // ExtensionClean(); // ZeroMemory(this); } /** * Check Condition is Setting Up ... * * @param dir: ENUM_X_DIRECTION member, Setting Up Direction ... * * @return ( bool ) */ bool IsSetuped() { // bool result = false; // result = IsValid(setupTime) && HasDirection(dir); if (!result) { return result; } // return result; } /** * Calculate Setup Age ... * * @return ( int ) */ int GetSetupAge() { // int result = 0; // if (!IsSetuped()) { return result; } // result = (int)(TimeCurrent() - setupTime) / PeriodSeconds(period); // return result; } /** * Detect How we Can Trigger Signal ... * * @return ( bool ) */ bool CanTrigger() { // bool result = false; // result = // sl > 0 && IsValid(symbol) && IsValid(period) && IsValid(triggerTime) && type != X_POSITION_TYPE_ALL && type != X_POSITION_TYPE_NONE // ; // return result; } // // Extensions ... /** * Clean Additional Properties ... */ void ExtensionClean() { // pivot = 0; point = 0; // reward = 0; amountPercent = 0; // Clean(sls); Clean(targets); signalBox.Clean(); // provider = X121SMC_XWZ_PROVIDER_NONE; } // // // // void UpdateTo(datetime value = NULL) { // value = NormalizeTime(value); // int count = 0; bool has = false; } // }; // // Extension Functions ... //