/////////////////////////////////////////////////////// // // 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; // bool isAllowLong = AllowLong(); bool isAllowShort = AllowShort(); result = isAllowLong || isAllowShort; if (!result) { return result; ; } // // Start Calculations ... // string _symbol = GetSymbol(); ENUM_TIMEFRAMES _period = GetPeriod(); // double points = GetPoints(_symbol); double pip = GetPipPrice(_symbol); double pip2 = 2 * pip; double pip3 = 3 * pip; // int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 1; int ppIndex = pIndex + 1; // int loopback = 7; string symbol = _symbol; int dest = cIndex + loopback; datetime cTime = TimeCurrent(); ENUM_TIMEFRAMES period = _period; // // 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; } // // Reading Indicator's Conditions ... XCHVWAPConditions chvwapConditions; chvwapHelper.GetConditions( chvwapConditions, cIndex, loopback // ); // XZone supplyZone; int supplyZonesCount = ArraySize(_5MState.supplyZones); bool hasSupplyZoneOverCBar = IsValidSize(supplyZonesCount); if (hasSupplyZoneOverCBar) { // hasSupplyZoneOverCBar = false; for (int i = 0; i < supplyZonesCount; i++) { // XZone iZone = _5MState.supplyZones[i]; // if (!hasSupplyZoneOverCBar && iZone.lower > cBar.high) { // iZone.to = cTime; supplyZone = iZone; hasSupplyZoneOverCBar = true; // break; } } } // XZone demandZone; int demandZonesCount = ArraySize(_5MState.demandZones); bool hasDemandZoneUnderCBar = IsValidSize(demandZonesCount); if (hasDemandZoneUnderCBar) { // hasDemandZoneUnderCBar = false; for (int i = 0; i < demandZonesCount; i++) { // XZone iZone = _5MState.demandZones[i]; // if (!hasDemandZoneUnderCBar && iZone.upper < cBar.low) { // iZone.to = cTime; demandZone = iZone; hasDemandZoneUnderCBar = true; // break; } } } // XOHCL swingHigh; int swingHighsCount = ArraySize(_5MState.swingHighs); bool hasSwingHighOverCBar = IsValidSize(swingHighsCount); if (hasSwingHighOverCBar) { // hasSwingHighOverCBar = false; for (int i = 0; i < swingHighsCount; i++) { // XOHCL iBar = _5MState.swingHighs[i]; // if (!hasSwingHighOverCBar && iBar.high > cBar.high) { // swingHigh = iBar; hasSwingHighOverCBar = true; // break; } } } // XOHCL swingLow; int swingLowsCount = ArraySize(_5MState.swingLows); bool hasSwingLowUnderCBar = IsValidSize(swingLowsCount); if (hasSwingLowUnderCBar) { // hasSwingLowUnderCBar = false; for (int i = 0; i < swingLowsCount; i++) { // XOHCL iBar = _5MState.swingLows[i]; // if (!hasSwingLowUnderCBar && iBar.low < cBar.low) { // swingLow = iBar; hasSwingLowUnderCBar = true; // break; } } } // XOHCL bullishRejectionBar; XOHCL bearishRejectionBar; bool hasBullishRejectionBarUnderCBar = false; bool hasBearishRejectionBarOverCBar = false; int rejectionBarsCount = ArraySize(_5MState.rejectionBars); if (IsValidSize(rejectionBarsCount)) { // for (int i = 0; i < rejectionBarsCount; i++) { // XOHCL iBar = _5MState.rejectionBars[i]; // bool isBullish = iBar.GetLowShadow() > iBar.GetHighShadow(); bool isBearish = iBar.GetHighShadow() > iBar.GetLowShadow(); // if (isBullish && !hasBullishRejectionBarUnderCBar && iBar.high < cBar.low) { // bullishRejectionBar = iBar; hasBullishRejectionBarUnderCBar = true; } // if (isBearish && !hasBearishRejectionBarOverCBar && iBar.low > cBar.high) { // bearishRejectionBar = iBar; hasBearishRejectionBarOverCBar = true; } } } // bool isBullish = // ( // ( // // Common Conditions ... // // Check Has Swing Low Under CBar ... hasSwingLowUnderCBar && // // Check has a Demand Zone Under CBar ... hasDemandZoneUnderCBar && // // Check Candle is Strong ... cBar.IsBullishDecision() && // // Check Has a Bullish Rejection Bar Under CBar ... hasBullishRejectionBarUnderCBar && // ( // // First ... ( // cBar.open < chvwapConditions.s[0] && cBar.open < chvwapConditions.m[0] && cBar.open < chvwapConditions.l[0] && cBar.open < chvwapConditions.h[0] && // cBar.close > chvwapConditions.s[0] && cBar.close > chvwapConditions.m[0] && cBar.close > chvwapConditions.l[0] && cBar.close > chvwapConditions.h[0] // ) // || // // Seccend ... ( // chvwapConditions.s[0] > chvwapConditions.m[0] && chvwapConditions.m[0] > chvwapConditions.l[0] && chvwapConditions.l[0] > chvwapConditions.h[0] && // cBar.close > chvwapConditions.s[0] // ) // ) // ) // ); // bool isBearish = // ( // ( // // Common Conditions ... // // Check Has Swing High Over CBar ... hasSwingHighOverCBar && // // Check Has Supply Zone Over CBar ... hasSupplyZoneOverCBar && // // Check Candle is Strong ... cBar.IsBearishDecision() && // // Check Has a Bearish Rejection Bar Over CBar ... hasBearishRejectionBarOverCBar && // ( // // First ... ( // cBar.open > chvwapConditions.s[0] && cBar.open > chvwapConditions.m[0] && cBar.open > chvwapConditions.l[0] && cBar.open > chvwapConditions.h[0] && // cBar.close < chvwapConditions.s[0] && cBar.close < chvwapConditions.m[0] && cBar.close < chvwapConditions.l[0] && cBar.close < chvwapConditions.h[0] // ) // || // // Second ... ( // chvwapConditions.s[0] < chvwapConditions.m[0] && chvwapConditions.m[0] < chvwapConditions.l[0] && chvwapConditions.l[0] < chvwapConditions.h[0] && // cBar.close < chvwapConditions.s[0] // ) // ) // ) // ); // if (isBullish || isBearish) { // // Draw supply if Exists ... if (hasSupplyZoneOverCBar) { // XCSupplyZoneObject *iObj; bool isCreated = mPOIDrawer.CreateSupplyZone( supplyZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Draw Demand if Exists ... if (hasDemandZoneUnderCBar) { // XCDemandZoneObject *iObj; bool isCreated = mPOIDrawer.CreateDemandZone( demandZone, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Draw Swing High ... if (hasSwingHighOverCBar) { // XCSwingHighObject *iObj; bool isCreated = mPOIDrawer.CreateSwingHigh( swingHigh, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Draw Swing Low ... if (hasSwingLowUnderCBar) { // XCSwingLowObject *iObj; bool isCreated = mPOIDrawer.CreateSwingLow( swingLow, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Draw Bullish Rejection Bar ... if (hasBullishRejectionBarUnderCBar) { // XCBullishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBullishRejectionBar( bullishRejectionBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // // Draw Bearish Rejection Bar ... if (hasBearishRejectionBarOverCBar) { // XCBearishRejectionBarObject *iObj; bool isCreated = mPOIDrawer.CreateBearishRejectionBar( bearishRejectionBar, iObj // ); if (isCreated) { mDrawnObjects.Add(iObj); } } // Print(""); // hasLong = isBullish; // hasShort = isBearish; } // result = hasLong || hasShort; if (!result) { conditions.Clean(); } // // 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 slCandidates[]; // double selectedSL = hasLong ? GetMin(slCandidates) : GetMax(slCandidates); sl = hasLong ? selectedSL - pip3 : selectedSL + pip3; // // RISK Reward ... risk = hasLong ? entry - sl : sl - entry; reward = risk * r2r; tp = hasLong ? entry + reward : entry - reward; // 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 ... /** * 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 // ); } /** * Detect Direction of VWAP ... * * @return ( bool ) */ ENUM_X_DIRECTION DetectVWAPDirection() { // ENUM_X_DIRECTION result = 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(); // // Reading Indicator's Conditions ... XCHVWAPConditions chvwapConditions; chvwapHelper.GetConditions( chvwapConditions, cIndex, loopback // ); // 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 isBullishDirection = isBullishState && isBullishOrdered; // 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 isBearishDirection = isBearishState && isBearishOrdered; // if (isBullishDirection && !isBearishDirection) { result = X_DIRECTION_BULLISH; } else if ( isBearishDirection && !isBullishDirection) { result = X_DIRECTION_BEARISH; } // return result; } // }; //