From 812e46815165122e48adecf9f779054db80be355 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 9 Dec 2024 23:04:42 +0330 Subject: [PATCH] Fix Spread Passing for Signalling and Conditions Processing ... --- Documents/BKP/tmp.base.x121.mq5 | 153 +++++++++ Helpers/x-saherelm.x121.helper.mq5 | 24 +- Libraries/x-saherelm.common.lib.mq5 | 39 +-- .../Classes/x-121.smc.base.strategy.class.mq5 | 299 +++++++----------- .../x-121.smc.market.cycle.helper.class.mq5 | 134 +++++++- X121SMCEA/Experts/x-121.smc.expert.class.mq5 | 2 + .../x-121.smc.test.strategy.class.mq5 | 106 +++---- 7 files changed, 475 insertions(+), 282 deletions(-) create mode 100644 Documents/BKP/tmp.base.x121.mq5 diff --git a/Documents/BKP/tmp.base.x121.mq5 b/Documents/BKP/tmp.base.x121.mq5 new file mode 100644 index 00000000..8647e579 --- /dev/null +++ b/Documents/BKP/tmp.base.x121.mq5 @@ -0,0 +1,153 @@ + + /** + * Check Ticks is Bullish or not ... + * + * @return ( bool ) + */ + bool IsTicksBullish() + { + // + bool result = false; + + // + int start = -1; + int end = -1; + int requiredBullishTicks = 5; + CalculateTicksParams( + start, + end, + requiredBullishTicks // + ); + result = IsValidIndex(start) && + IsValidIndex(end); + if (!result) + { + return result; + } + + // + result = true; + for (int i = start + 1; i < end; i++) + { + // + XTick iTick = mTicks[i]; + XTick prevTick = mTicks[i - 1]; + + // + bool isBullish = iTick.bid >= prevTick.bid; + result = result && isBullish; + if (!result) + { + break; + } + } + + // + return result; + } + + /** + * Check Ticks is Bearish or not ... + * + * @return ( bool ) + */ + bool IsTicksBearish() + { + // + bool result = false; + + // + int start = -1; + int end = -1; + int requiredBearishTicks = 5; + CalculateTicksParams( + start, + end, + requiredBearishTicks // + ); + result = IsValidIndex(start) && + IsValidIndex(end); + if (!result) + { + return result; + } + + // + result = true; + for (int i = start + 1; i < end; i++) + { + // + XTick iTick = mTicks[i]; + XTick prevTick = mTicks[i - 1]; + + // + bool isBearish = iTick.bid <= prevTick.bid; + result = result && isBearish; + if (!result) + { + break; + } + } + + // + return result; + } + + /** + * Check Ticks Has Momentum or not ... + * + * @return ( bool ) + */ + bool IsTicksHasMomentum() + { + // + bool result = false; + + // + int start = -1; + int end = -1; + int requiredTicksForMomentum = 5; + CalculateTicksParams( + start, + end, + requiredTicksForMomentum // + ); + result = IsValidIndex(start) && + IsValidIndex(end); + if (!result) + { + return result; + } + + // + result = true; + int lastDiff = 0; + for (int i = start + 1; i < end; i++) + { + // + XTick iTick = mTicks[i]; + XTick prevTick = mTicks[i - 1]; + + // + int timeDiff = MathAbs((int)iTick.time - (int)prevTick.bid); + if (lastDiff <= 0) + { + lastDiff = timeDiff; + } + result = result && timeDiff >= lastDiff; + if (!result) + { + break; + } + + // + lastDiff = timeDiff; + } + + // + return result; + } + + +/////////////////////////////////////////////////////////////////////// + diff --git a/Helpers/x-saherelm.x121.helper.mq5 b/Helpers/x-saherelm.x121.helper.mq5 index 46fdce61..f41d4dca 100644 --- a/Helpers/x-saherelm.x121.helper.mq5 +++ b/Helpers/x-saherelm.x121.helper.mq5 @@ -527,8 +527,8 @@ struct X121Conditions bool isSarBearish; // - bool isSarSwitchedBullish; - bool isSarSwitchedBearish; + bool isSarSwitchedToBullish; + bool isSarSwitchedToBearish; // // XPV ... @@ -735,8 +735,8 @@ struct X121Conditions isSarBearish = false; // - isSarSwitchedBullish = false; - isSarSwitchedBearish = false; + isSarSwitchedToBullish = false; + isSarSwitchedToBearish = false; // // XPV ... @@ -904,8 +904,8 @@ struct X121Conditions // XSAR ... ToString("isSarBullish", isSarBullish, ignoreFalseConditions, separator) + ToString("isSarBearish", isSarBearish, ignoreFalseConditions, separator) + - ToString("isSarSwitchedBullish", isSarSwitchedBullish, ignoreFalseConditions, separator) + - ToString("isSarSwitchedBearish", isSarSwitchedBearish, ignoreFalseConditions, separator) + + ToString("isSarSwitchedToBullish", isSarSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSarSwitchedToBearish", isSarSwitchedToBearish, ignoreFalseConditions, separator) + // // XPV ... ToString("isNewPeak", isNewPeak, ignoreFalseConditions, separator) + @@ -3543,10 +3543,10 @@ class XCX121Helper : public XCBaseHelper bool isSarBearishPrev = conditions.sarBuffer[pIndex] > pBar.high; // - bool isSarSwitchedBullish = isSarBullish && - !isSarBullishPrev; - bool isSarSwitchedBearish = isSarBearish && - !isSarBearishPrev; + bool isSarSwitchedToBullish = isSarBullish && + !isSarBullishPrev; + bool isSarSwitchedToBearish = isSarBearish && + !isSarBearishPrev; // // XPV ... @@ -3710,8 +3710,8 @@ class XCX121Helper : public XCBaseHelper // Set ... conditions.isSarBullish = isSarBullish; conditions.isSarBearish = isSarBearish; - conditions.isSarSwitchedBullish = isSarSwitchedBullish; - conditions.isSarSwitchedBearish = isSarSwitchedBearish; + conditions.isSarSwitchedToBullish = isSarSwitchedToBullish; + conditions.isSarSwitchedToBearish = isSarSwitchedToBearish; conditions.isNewPeak = isNewPeak; conditions.isNewPeakOverLast = isNewPeakOverLast; conditions.isNewPeakUnderLast = isNewPeakUnderLast; diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 7104eba7..93a01551 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -215,6 +215,7 @@ struct XTick double bid; // Bid ... double ask; // Ask ... double spread; // Spread ... + long volume; // Volume ... // // Constructor ... @@ -233,13 +234,15 @@ struct XTick * @param _time: Time ... * @param _bid: Bid Price ... * @param _ask: Ask Price ... + * @param _volume: Tick Volume ... */ bool Init( string _symbol, datetime _time, double _bid, double _ask, - double _spread // + double _spread, + long _volume // ) { // @@ -293,6 +296,7 @@ struct XTick double _bid = GetBid(_symbol); double _ask = GetAsk(_symbol); double _spread = GetSpread(_symbol); + long _volume = iTickVolume(_symbol, PERIOD_M1, 0); // result = Init( @@ -300,39 +304,14 @@ struct XTick _time, _bid, _ask, - _spread // + _spread, + _volume // ); // return result; } - /** - * Init XTick for Specified Time ... - * - * @param _symbol: String, Symbol Representation ... - * @param _time: Datetime, Specified Time ... - * - * @return ( bool ) - */ - bool Init( - string _symbol, - datetime _time // - ) - { - // - bool result = false; - - // - // TODO: Complete this ... - - // - result = IsValid(); - - // - return result; - } - /** * Cleanup ... */ @@ -341,6 +320,7 @@ struct XTick // bid = 0; ask = 0; + volume = 0; time = NULL; symbol = NULL; } @@ -359,7 +339,8 @@ struct XTick result = IsValid(symbol) && IsValid(time) && bid > 0 && - ask > 0; + ask > 0 && + volume >= 0; // return result; diff --git a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 index 31b57720..710e0262 100644 --- a/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.base.strategy.class.mq5 @@ -235,6 +235,60 @@ class XCX121SMCBaseStrategy : public XCBaseAlert mMaxAllowedSpread = value; } + /** + * Get Min Required Ticks Verification for Spread Pass ... + * + * @return ( int ) + */ + int MinRequiredTicksForSpreadPass() + { + return mMinRequiredTicksForSpreadPass; + } + + /** + * Set Min Required Ticks Verification for Spread Pass ... + * + * @param value: Integer ... + */ + void MinRequiredTicksForSpreadPass(int value) + { + // + if (value < 100) + { + value = 100; + } + + // + mMinRequiredTicksForSpreadPass = value; + } + + /** + * Get Max Allowed Save Ticks ... + * + * @return ( int ) + */ + int MaxAllowedSaveTicks() + { + return mMaxAllowedSaveTicks; + } + + /** + * Set Max Allowed Save Ticks ... + * + * @param value: Integer ... + */ + void MaxAllowedSaveTicks(int value) + { + // + if (value < 150) + { + value = 150; + } + + // + mMaxAllowedSaveTicks = value; + } + /** * Get Long Signalling State ... * @@ -534,9 +588,9 @@ class XCX121SMCBaseStrategy : public XCBaseAlert bool result = false; // - int length = 5; double pointValue = GetPoints(mSymbol); double maxAllowedSpread = MaxAllowedSpread(); + int minRequiredTicksVerification = MinRequiredTicksForSpreadPass(); if (maxAllowedSpread > 0) { maxAllowedSpread *= pointValue; @@ -546,193 +600,51 @@ class XCX121SMCBaseStrategy : public XCBaseAlert maxAllowedSpread = 0; } + // + result = maxAllowedSpread <= 0 + ? true + : minRequiredTicksVerification > 0; + if (!result) + { + return result; + } + // int ticksCount = ArraySize(mTicks); - if (ticksCount <= length) - { - return result; - } - - // - int start = -1; - int end = -1; - CalculateTicksParams( - start, - end, - length + 1 // - ); - result = IsValidIndex(start) && - IsValidIndex(end); + result = ticksCount >= minRequiredTicksVerification; if (!result) { return result; } // - end -= 1; - double spreadAVG = 0; - for (int i = start; i < end; i++) - { - spreadAVG += mTicks[i].spread; - } - spreadAVG /= length; - - // - double lastSpread = mTicks[ticksCount - 1].spread; - - // - result = lastSpread <= spreadAVG && - (maxAllowedSpread <= 0 - ? true - : lastSpread <= maxAllowedSpread); - - // - return result; - } - - /** - * Check Ticks is Bullish or not ... - * - * @return ( bool ) - */ - bool IsTicksBullish() - { - // - bool result = false; - - // - int start = -1; - int end = -1; - int requiredBullishTicks = 5; - CalculateTicksParams( - start, - end, - requiredBullishTicks // - ); - result = IsValidIndex(start) && - IsValidIndex(end); - if (!result) - { - return result; - } - - // - result = true; - for (int i = start + 1; i < end; i++) + if (maxAllowedSpread > 0) { // - XTick iTick = mTicks[i]; - XTick prevTick = mTicks[i - 1]; - - // - bool isBullish = iTick.bid >= prevTick.bid; - result = result && isBullish; - if (!result) - { - break; - } - } - - // - return result; - } - - /** - * Check Ticks is Bearish or not ... - * - * @return ( bool ) - */ - bool IsTicksBearish() - { - // - bool result = false; - - // - int start = -1; - int end = -1; - int requiredBearishTicks = 5; - CalculateTicksParams( - start, - end, - requiredBearishTicks // - ); - result = IsValidIndex(start) && - IsValidIndex(end); - if (!result) - { - return result; - } - - // - result = true; - for (int i = start + 1; i < end; i++) - { - // - XTick iTick = mTicks[i]; - XTick prevTick = mTicks[i - 1]; - - // - bool isBearish = iTick.bid <= prevTick.bid; - result = result && isBearish; - if (!result) - { - break; - } - } - - // - return result; - } - - /** - * Check Ticks Has Momentum or not ... - * - * @return ( bool ) - */ - bool IsTicksHasMomentum() - { - // - bool result = false; - - // - int start = -1; - int end = -1; - int requiredTicksForMomentum = 5; - CalculateTicksParams( - start, - end, - requiredTicksForMomentum // - ); - result = IsValidIndex(start) && - IsValidIndex(end); - if (!result) - { - return result; - } - - // - result = true; - int lastDiff = 0; - for (int i = start + 1; i < end; i++) - { - // - XTick iTick = mTicks[i]; - XTick prevTick = mTicks[i - 1]; - - // - int timeDiff = MathAbs((int)iTick.time - (int)prevTick.bid); - if (lastDiff <= 0) - { - lastDiff = timeDiff; - } - result = result && timeDiff >= lastDiff; - if (!result) - { - break; + int end = -1; + int start = -1; + result = CalculateTicksParams( + start, + end, + minRequiredTicksVerification // + ); + if (!result) { + return result; } // - lastDiff = timeDiff; + for (int i = start; i < end; i++) + { + // + XTick iTick = mTicks[i]; + + // + result = iTick.spread <= maxAllowedSpread; + if (!result) + { + break; + } + } } // @@ -1475,14 +1387,18 @@ class XCX121SMCBaseStrategy : public XCBaseAlert // Props ... // - string mSymbol; // Trading Symbol ... - ENUM_TIMEFRAMES mPeriod; // Trading TimeFrame ... - bool mForceDisabled; // Force Disabled ... - bool mAllowLong; // Allow Long Signals - bool mAllowShort; // Allow Short Signals - double mR2R; // Risk/Rewar Ratio ... - double mVolume; // Static Volume Per Trades ... - double mMaxAllowedSpread; // Max Allowed Spread ... + string mSymbol; // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod; // Trading TimeFrame ... + bool mForceDisabled; // Force Disabled ... + bool mAllowLong; // Allow Long Signals + bool mAllowShort; // Allow Short Signals + double mR2R; // Risk/Rewar Ratio ... + double mVolume; // Static Volume Per Trades ... + + // + double mMaxAllowedSpread; // Max Allowed Spread ... + int mMinRequiredTicksForSpreadPass; // Min Required Ticks Verification for Spread Pass ... + int mMaxAllowedSaveTicks; // Max Allowed Save Ticks ... // long mChartID; // Chart ID ... @@ -1506,6 +1422,8 @@ class XCX121SMCBaseStrategy : public XCBaseAlert // R2R(1); Volume(0.01); + MaxAllowedSaveTicks(150); + MinRequiredTicksForSpreadPass(100); // ChartIdentification(0); @@ -1598,7 +1516,6 @@ class XCX121SMCBaseStrategy : public XCBaseAlert mVisionDetector.MaxNumberOfRequiredPOIs(poiRequired); mVisionDetector.Init(); - // } @@ -1636,7 +1553,7 @@ class XCX121SMCBaseStrategy : public XCBaseAlert void CleanupTicks() { // - int maxRequiredTicks = 50; + int maxRequiredTicks = MaxAllowedSaveTicks(); int ticksCount = ArraySize(mTicks); if (!IsValidSize(ticksCount) || ticksCount <= maxRequiredTicks) @@ -1686,12 +1603,15 @@ class XCX121SMCBaseStrategy : public XCBaseAlert * @param end: Integer Reference to End ... * @param numOfLastTicks: Integer Max Number of Required N Last Ticks ... */ - void CalculateTicksParams( + bool CalculateTicksParams( int &start, int &end, int numOfLastTicks = 5 // ) { + // + bool result = 0; + // start = -1; end = -1; @@ -1712,6 +1632,13 @@ class XCX121SMCBaseStrategy : public XCBaseAlert { end = count; } + + // + result = IsValidIndex(start) && + IsValidIndex(end); + + // + return result; } // diff --git a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 index ca1379a9..2a95cb75 100644 --- a/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 +++ b/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5 @@ -326,6 +326,16 @@ class XC121SMCCycleHelper : public XCBase // result = conditions.IsValid(); + // + if (result) + { + // + Calculate( + barIndex, + conditions // + ); + } + // return result; } @@ -361,6 +371,7 @@ class XC121SMCCycleHelper : public XCBase // double bid = GetBid(bar.symbol); + double ask = GetAsk(bar.symbol); // // Retrieve X121 Cnditions ... @@ -407,7 +418,9 @@ class XC121SMCCycleHelper : public XCBase // // Check Zone is Valid For Bar ... - bool isValid = bar.high < iZone.Lower(); + bool isValid = bar.high < iZone.Lower() && + ask < iZone.Lower() && + bid < iZone.Lower(); if (isValid) { // @@ -511,7 +524,9 @@ class XC121SMCCycleHelper : public XCBase // // Check Zone is Valid For Bar ... - bool isValid = bar.low > iZone.Upper(); + bool isValid = bar.low > iZone.Upper() && + ask > iZone.Upper() && + bid > iZone.Upper(); if (isValid) { // @@ -616,6 +631,121 @@ class XC121SMCCycleHelper : public XCBase protected: // + /** + * Calculate Requirements ... + * + * @param barIndex: Integer, Bar Index ... + * @param conditions: X121SMCCycleConditions instance ... + */ + void Calculate( + int barIndex, + X121SMCCycleConditions &conditions // + ) + { + // + int index = + barIndex <= 0 + ? 1 + : barIndex; + bool isInited = false; + string symbol = GetSymbol(); + + // + // Retrieve Bar ... + XOHCL bar; + isInited = GetBar(bar, index); + if (!isInited) + { + return; + } + + // + // Retrieve Previous Bar ... + XOHCL pBar; + int pIndex = index + 1; + isInited = GetBar(pBar, pIndex); + if (!isInited) + { + return; + } + + // + XTick xTick; + isInited = xTick.Init(symbol); + if (!isInited) + { + return; + } + + // + bool isSarAttached = + bar.close > conditions.x121Conditions.sarBuffer[0]; + if (isSarAttached) + { + Print("Sar Attached ..."); + } + + // // + // bool isSarBullish = + // conditions.x121Conditions.sarBuffer[index] < bar.low; + // bool isSarBullishPrev = + // conditions.x121Conditions.sarBuffer[pIndex] < pBar.low; + + // // + // bool isSarBearish = + // conditions.x121Conditions.sarBuffer[index] > bar.high; + // bool isSarBearishPrev = + // conditions.x121Conditions.sarBuffer[pIndex] > pBar.high; + + // // + // bool isSarSwitchedToBullish = + // isSarBullish && + // !isSarBullishPrev && + // isSarBearishPrev; + + // // + // bool isSarSwitchedToBearish = + // isSarBearish && + // !isSarBearishPrev && + // isSarBullishPrev; + + // // + // if (isSarSwitchedToBullish || + // isSarSwitchedToBearish) + // { + // Print("Sar Switched ..."); + // } + + // // + // bool isSarBullish = + // conditions.x121Conditions.sarBuffer[1] < xTick.ask && + // conditions.x121Conditions.sarBuffer[1] < xTick.bid && + // conditions.x121Conditions.isSarBullish; + + // // + // bool isSarBearish = + // conditions.x121Conditions.sarBuffer[1] > xTick.ask && + // conditions.x121Conditions.sarBuffer[1] > xTick.bid && + // conditions.x121Conditions.isSarBearish; + + // + // Detect Sar Changes ... + // bool isSarChanged = (isSarBullish && + // !isSarBearish) || + // (isSarBearish && + // !isSarBullish); + // if (isSarChanged) + // { + // Print("SarChaned"); + // } + + // + // Detect Peak Changes ... + + // + // Detect Vale Changes ... + } + // private: // diff --git a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 index d20f5815..67616d00 100644 --- a/X121SMCEA/Experts/x-121.smc.expert.class.mq5 +++ b/X121SMCEA/Experts/x-121.smc.expert.class.mq5 @@ -1000,6 +1000,8 @@ class XC121SMCExpert : public XCBaseExpert strategy.AllowLong(AllowLong()); strategy.AllowShort(AllowShort()); strategy.MaxAllowedSpread(20); + strategy.MaxAllowedSaveTicks(150); + strategy.MinRequiredTicksForSpreadPass(100); // if (Disabled()) diff --git a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 index 184ffd69..d42e8ff3 100644 --- a/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 +++ b/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5 @@ -123,15 +123,6 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy double pip = GetPipPrice(symbol); double pip2 = 2 * pip; - // - // Detect Conditions ... - result = DetectConditions(conditions); - if (!result) - { - conditions.Clean(); - return result; - } - // // Check Spread ... bool isSpreadPassed = IsSpreadPass(); @@ -146,6 +137,15 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy return result; } + // + // Detect Conditions ... + result = DetectConditions(conditions); + if (!result) + { + conditions.Clean(); + return result; + } + // // Combine all Signals Conditions ... selectedSL = conditions.sl; @@ -425,53 +425,53 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy } conditions.visionConditions.state = mVisionState; - // - // Detect Valid Supply and Demand Zones ... - XCSupplyZone *supplyZone; - XCDemandZone *demandZone; - result = mTriggerCycleHelper - .DetectValisSupplyZone( - cBar, - supplyZone, - demandZone // - ); - if (!result) - { - // - conditions.Clean(); - return result; - } + // // + // // Detect Valid Supply and Demand Zones ... + // XCSupplyZone *supplyZone; + // XCDemandZone *demandZone; + // result = mTriggerCycleHelper + // .DetectValisSupplyZone( + // cBar, + // supplyZone, + // demandZone // + // ); + // if (!result) + // { + // // + // conditions.Clean(); + // return result; + // } - // - supplyZone.To(cTime); - XCSupplyZoneObject *iSupplyZoneObj; - result = mPOIDrawer.CreateSupplyZone( - supplyZone, - iSupplyZoneObj // - ); - if (!result) - { - // - conditions.Clean(); - return result; - } + // // + // supplyZone.To(cTime); + // XCSupplyZoneObject *iSupplyZoneObj; + // result = mPOIDrawer.CreateSupplyZone( + // supplyZone, + // iSupplyZoneObj // + // ); + // if (!result) + // { + // // + // conditions.Clean(); + // return result; + // } - // - demandZone.To(cTime); - XCDemandZoneObject *iDemandZoneObj; - result = mPOIDrawer.CreateDemandZone( - demandZone, - iDemandZoneObj // - ); - if (!result) - { - // - conditions.Clean(); - return result; - } + // // + // demandZone.To(cTime); + // XCDemandZoneObject *iDemandZoneObj; + // result = mPOIDrawer.CreateDemandZone( + // demandZone, + // iDemandZoneObj // + // ); + // if (!result) + // { + // // + // conditions.Clean(); + // return result; + // } - // - Print("Supply and Demand Zone Created ..."); + // // + // Print("Supply and Demand Zone Created ..."); // if (!result)