/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XSCXOBVGStrategy // 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.xosc.helper.mq5" #include "../Classes/x-saherelm.xstrategy.class.mq5" // string XOBVGStartegyToken = "XOBVG"; // class XSCXOBVGStrategy : public XSCBaseStrategy { // // Public ... public: // // Constructor(s) ... void XSCXOBVGStrategy( // // Base ... string _symbol, // Trading Symbol ENUM_TIMEFRAMES _period, // Trading TimeFrame ENUM_TIMEFRAMES _analyzingPeriod, // Analyzing Period double _volume, // Voluem double _r2r, // Risk/Reward Ratio int _slippage, // Trader Slippage long _magicNumber, // Trader Magic Number bool _useTPSLAsPoint = false, // Converts TP and SL by Provided Points bool _forceMaxTPSLAsPoint = false, // Force Max TP and SL by Provided Points double _tpPoint = 0, // TP As Point double _slPoint = 0, // SL As Point bool _allowLong = true, bool _allowShort = true, int _maxAllowedLongs = 0, int _maxAllowedShorts = 0 // ) : XSCBaseStrategy(_symbol, _period, _volume, _r2r, _slippage, _magicNumber, _useTPSLAsPoint, _forceMaxTPSLAsPoint, _tpPoint, _slPoint, _allowLong, _allowShort, _maxAllowedLongs, _maxAllowedShorts // ) { // mAnalyzingPeriod = _analyzingPeriod; // SetAlertPrefix(GetTag()); // PrepareRequirements(); // fvgUpper = 0; fvgLower = 0; isFVGTouched = false; // oBar.Clean(); oBullishOrderBlock.Clean(); oBearishOrderBlock.Clean(); } // // Deconstructor ... void ~XSCXOBVGStrategy() { delete oscHelper; } // // Getter / Setter (s) ... // ENUM_TIMEFRAMES AnalyzingPeriod() { return mAnalyzingPeriod; } // void AnalyzingPeriod(ENUM_TIMEFRAMES value) { mAnalyzingPeriod = value; } // // Overrides ... // // Customize Strategy Identifier ... string GetTag() override { return XOBVGStartegyToken; } // // Check Conditions For Signal ... bool HasSignal( XSignal &signal // ) override { // bool result = false; // signal.Clean(); // double sl = 0; double tp = 0; double risk = 0; double entry = 0; double reward = 0; double r2r = R2R(); ENUM_POSITION_TYPE type = POSITION_TYPE_BUY; ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; // bool hasLong = false; bool hasShort = false; // // For Trend ... XOHCL tmpHSW[]; XOHCL tmpLSW[]; // // For Verifications ... // bool useHammer = true; bool useMorningStar = false; bool useBullishEngulfing = true; bool useBullishMaurubozu = true; // bool useShootingStar = true; bool useEveningStar = false; bool useBearishEngulfing = true; bool useBearishMaurubozu = true; // // Bar On Trading Period ... XOHCL cBar; result = cBar.Init( mSymbol, mPeriod, 1 // ); if (!result) { return result; } // // 3 Bar LL and HH ... double ll3 = cBar.FindLowest( 3, MODE_LOW // ); double hh3 = cBar.FindHighest( 3, MODE_HIGH // ); // double atr = oscHelper.GetATR(1); // // Check OB Finder Bar ... result = oBar.IsValid(); if (!result) { // // Init OB Finder Bar ... result = oBar.Init( mSymbol, mAnalyzingPeriod, 1 // ); if (!result) { return result; } } // bool hasBullishOrderBlock = oBullishOrderBlock.IsValid(); bool hasBearishOrderBlock = oBearishOrderBlock.IsValid(); // // Here we Have to Check Order Block Age ... // if (hasBullishOrderBlock) { // int age = oBullishOrderBlock.Index(); result = age <= 26; if (!result) { // oBar.Clean(); oBullishOrderBlock.Clean(); fvgUpper = 0; fvgLower = 0; fvgTouchDate = NULL; isFVGTouched = false; // RemoveDraws(); // return result; } } // if (hasBearishOrderBlock) { // int age = oBearishOrderBlock.Index(); result = age <= 26; if (!result) { // oBar.Clean(); oBearishOrderBlock.Clean(); fvgUpper = 0; fvgLower = 0; fvgTouchDate = NULL; isFVGTouched = false; // RemoveDraws(); // return result; } } // hasBullishOrderBlock = oBullishOrderBlock.IsValid(); hasBearishOrderBlock = oBearishOrderBlock.IsValid(); result = // hasBullishOrderBlock // || // hasBearishOrderBlock // ; if (!result) { // // Detect Order Blocks ... hasBullishOrderBlock = oBar.HasBullishOrderBlock(oBullishOrderBlock); hasBearishOrderBlock = oBar.HasBearishOrderBlock(oBearishOrderBlock); // // Check OB Detected ... result = // hasBullishOrderBlock // || // hasBearishOrderBlock // ; if (!result) { // oBar.Clean(); oBullishOrderBlock.Clean(); oBearishOrderBlock.Clean(); // fvgUpper = 0; fvgLower = 0; fvgTouchDate = NULL; isFVGTouched = false; // return result; } } // // Long ... if (hasBullishOrderBlock) { // DrawBullishOrderBlock( oBullishOrderBlock, ChartID() // ); // // Detect an FVG Inside Order Block in Trading Period ... result = FindBullishFVGInsideOrderBlock(); if (!result) { // oBar.Clean(); oBullishOrderBlock.Clean(); fvgUpper = 0; fvgLower = 0; fvgTouchDate = NULL; isFVGTouched = false; // RemoveDraws(); // return result; } // // Now We Have to Waits Until Price reached the FVG ... if (!isFVGTouched) { // isFVGTouched = ll3 < fvgUpper; fvgTouchDate = TimeCurrent(); } // result = isFVGTouched; if (!result) { return result; } // // Now we Have to Wait for Pressure ... // bool isHammer = !useHammer ? false : cBar.IsHammer(); bool isMorningStar = !useMorningStar ? false : cBar.IsMorningStar(); bool isBullishMarubozu = !useBullishEngulfing ? false : cBar.IsBullishMarubozu(); bool isBullishEngulfing = !useBullishMaurubozu ? false : cBar.IsBullishEngulfing(); // bool isBullishTrend = oBar.HasBullishTrend( tmpHSW, tmpLSW, false // ); // hasLong = // true // isBullishTrend // && // ( // isHammer // || // isMorningStar // || // isBullishMarubozu // || // isBullishEngulfing // ) // ; result = hasLong; if (!result) { // // Check FVG Touch Date ... int cTimeSec = (int)TimeCurrent(); int tTimeSec = (int)fvgTouchDate; int periodSec = PeriodSeconds(mPeriod); int touchAge = (cTimeSec - tTimeSec) / periodSec; if (touchAge >= 10) { // oBar.Clean(); oBullishOrderBlock.Clean(); fvgUpper = 0; fvgLower = 0; fvgTouchDate = NULL; isFVGTouched = false; // RemoveDraws(); } // return result; } // type = POSITION_TYPE_BUY; sl = cBar.low - atr; } // // Short ... if (hasBearishOrderBlock) { // DrawBearishOrderBlock( oBearishOrderBlock, ChartID() // ); // // Detect an FVG Inside Order Block in Trading Period ... result = FindBearishFVGInsideOrderBlock(); if (!result) { // oBar.Clean(); oBearishOrderBlock.Clean(); fvgUpper = 0; fvgLower = 0; fvgTouchDate = NULL; isFVGTouched = false; // RemoveDraws(); // return result; } // // Now We Have to Waits Until Price reached the FVG ... if (!isFVGTouched) { // isFVGTouched = hh3 > fvgLower; fvgTouchDate = TimeCurrent(); } // result = isFVGTouched; if (!result) { return result; } // // Now we Have to Wait for Pressure ... // // Short ... bool isShootingStar = !useShootingStar ? false : cBar.IsShootingStar(); bool isEveningStar = !useEveningStar ? false : cBar.IsEveningStar(); bool isBearishEngulfing = !useBearishEngulfing ? false : cBar.IsBearishEngulfing(); bool isBearishMaurubozu = !useBearishMaurubozu ? false : cBar.IsBearishMarubozu(); // bool isBearishTrend = oBar.HasBearishTrend( tmpHSW, tmpLSW, false // ); // hasShort = // true // isBearishTrend // && // ( // isShootingStar // || // isEveningStar // || // isBearishEngulfing // || // isBearishMaurubozu // ) // ; result = hasShort; if (!result) { // // Check FVG Touch Date ... int cTimeSec = (int)TimeCurrent(); int tTimeSec = (int)fvgTouchDate; int periodSec = PeriodSeconds(mPeriod); int touchAge = (cTimeSec - tTimeSec) / periodSec; if (touchAge >= 10) { // oBar.Clean(); oBearishOrderBlock.Clean(); fvgUpper = 0; fvgLower = 0; fvgTouchDate = NULL; isFVGTouched = false; // RemoveDraws(); } // return result; } // type = POSITION_TYPE_SELL; sl = cBar.high + atr; } // result = hasLong || hasShort; if (!result) { return result; } // entry = GetEntry(mSymbol, type); CalculateTPSLByPrice( sl, tp, type, entry, r2r // ); // result = signal.Prepare( mSymbol, GetTag(), mPeriod, type, mode, entry, mVolume, sl, tp // ); // return result; } // // Protected ... protected: // // Props ... // ENUM_TIMEFRAMES mAnalyzingPeriod; // Analyzing Period // XOSCInputs oscInputs; XSCXOSCHelper *oscHelper; // // Private ... private: // // Props ... // XOHCL oBar; XOHCL oBullishOrderBlock; XOHCL oBearishOrderBlock; // double fvgUpper; double fvgLower; bool isFVGTouched; datetime fvgTouchDate; // void PrepareRequirements() { // oscInputs.Default(); oscHelper = new XSCXOSCHelper(); oscHelper.Init( mSymbol, mPeriod, oscInputs // ); } // bool FindBullishFVGInsideOrderBlock() { // bool result = false; // result = oBullishOrderBlock.IsValid(); if (!result) { return result; } // int totalBars = iBars( mSymbol, mPeriod // ); int maxAllowed = totalBars / 10; // for (int i = 0; i < maxAllowed; i++) { // XOHCL iBar; result = iBar.Init( mSymbol, mPeriod, i // ); if (!result) { break; } // result = iBar.HasBullishFVG( fvgUpper, fvgLower // ); if (!result) { continue; } // // Check FVG has Correlation by OB ... result = // // Full Inside ... (fvgUpper <= oBullishOrderBlock.high && fvgLower >= oBullishOrderBlock.low) // || // (fvgUpper > oBullishOrderBlock.high && fvgLower >= oBullishOrderBlock.low && fvgLower <= oBullishOrderBlock.high) // || // (fvgUpper > oBullishOrderBlock.low && fvgUpper <= oBullishOrderBlock.high && fvgLower < oBullishOrderBlock.low) // ; if (result) { // DrawBullishFVG( iBar, fvgUpper, fvgLower, ChartID() // ); // break; } } // return result; } // bool FindBearishFVGInsideOrderBlock() { // bool result = false; // result = oBearishOrderBlock.IsValid(); if (!result) { return result; } // int totalBars = iBars( mSymbol, mPeriod // ); int maxAllowed = totalBars / 10; // for (int i = 0; i < maxAllowed; i++) { // XOHCL iBar; result = iBar.Init( mSymbol, mPeriod, i // ); if (!result) { break; } // result = iBar.HasBearishFVG( fvgUpper, fvgLower // ); if (!result) { continue; } // // Check FVG has Correlation by OB ... result = // // Full Inside ... (fvgUpper <= oBearishOrderBlock.high && fvgLower >= oBearishOrderBlock.low) // || // (fvgUpper > oBearishOrderBlock.high && fvgLower >= oBearishOrderBlock.low && fvgLower <= oBearishOrderBlock.high) // || // (fvgUpper > oBearishOrderBlock.low && fvgUpper <= oBearishOrderBlock.high && fvgLower < oBearishOrderBlock.low) // ; if (result) { // DrawBearishFVG( iBar, fvgUpper, fvgLower, ChartID() // ); // break; } } // return result; } }; //