From 001c5f687e20d04d2b8546c4885798345d280816 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 14 Jun 2024 18:33:38 +0330 Subject: [PATCH] complete grid mechanism ... --- Classes/x-saherelm.x121.setup.class.mq5 | 8 +- Classes/x-saherelm.x121.setup.xea.mq5 | 266 ++++++++++++++++++++++-- Experts/x-saherelm.x121.ea.mq5 | 34 +-- 3 files changed, 279 insertions(+), 29 deletions(-) diff --git a/Classes/x-saherelm.x121.setup.class.mq5 b/Classes/x-saherelm.x121.setup.class.mq5 index 4bc46ced..4dfa25e6 100644 --- a/Classes/x-saherelm.x121.setup.class.mq5 +++ b/Classes/x-saherelm.x121.setup.class.mq5 @@ -2062,8 +2062,8 @@ struct X121SignalGenerator // bool IsConditionsValidForLong( - X121SetupConditions &conditions, - int verification = 4 // + X121SetupConditions &conditions, // Conditions + int verification = 4 // Number of Verifications ) { // @@ -2304,8 +2304,8 @@ struct X121SignalGenerator // bool IsConditionsValidForShort( - X121SetupConditions &conditions, - int verification = 4 // + X121SetupConditions &conditions, // Conditions + int verification = 4 // Number of Verifications ) { // diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index a97f0afe..eb7d2cf9 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -817,12 +817,63 @@ public: mUseSupport = value; } + // + bool UseGrid() + { + return mUseGrid; + } + + // + void UseGrid(bool value) + { + mUseGrid = value; + } + + // + double GridDistance() + { + return mGridDistance; + } + + // + void GridDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mGridDistance = value; + } + + // + double GridVolumeMultiplier() + { + return mGridVolumeMultiplier; + } + + // + void GridVolumeMultiplier(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mGridVolumeMultiplier = value; + } + // // Overrides ... // // Customize Token ... - string GetToken() override + string + GetToken() override { return GetSpecificToken(this); } @@ -1003,7 +1054,7 @@ public: // // Parse Conditions for Signal ... - bool cHasSignal = signalGenerator.HasSignal( + cHasSignal = signalGenerator.HasSignal( cConditions, cSignal, cPusher, @@ -1066,7 +1117,7 @@ public: // // Parse Conditions for Signal ... - bool sHasSignal = signalGenerator.HasSignal( + sHasSignal = signalGenerator.HasSignal( sConditions, sSignal, sPusher, @@ -1128,7 +1179,7 @@ public: // // Parse Conditions for Signal ... - bool mHasSignal = signalGenerator.HasSignal( + mHasSignal = signalGenerator.HasSignal( mConditions, mSignal, mPusher, @@ -1191,7 +1242,7 @@ public: // // Parse Conditions for Signal ... - bool lHasSignal = signalGenerator.HasSignal( + lHasSignal = signalGenerator.HasSignal( lConditions, lSignal, lPusher, @@ -1254,7 +1305,7 @@ public: // // Parse Conditions for Signal ... - bool hHasSignal = signalGenerator.HasSignal( + hHasSignal = signalGenerator.HasSignal( hConditions, hSignal, hPusher, @@ -1750,6 +1801,13 @@ public: } } } + + // + bool hasSignal = cHasSignal || sHasSignal || mHasSignal || lHasSignal || hHasSignal; + if (hasSignal) + { + Print("Signal Recieved ..."); + } } // @@ -1891,6 +1949,10 @@ public: // Handle Close All Positions on Specific Time ... DoEQMCloseOnSpecificTime(); + // + // Do EQM Grid if Provided ... + DoEQMGrid(); + // // if Returns true, Signal Execution failed ... return result; @@ -1986,7 +2048,6 @@ private: double mVolume; // Volume double mTPPoint; // TP Point double mSLPoint; // SL Point - bool mUseSupport; // Use Support Signals bool mIgnoreTP; // Ignore Calculated TP bool mIgnoreSL; // Ignore Calculated SL int mMaxAllowedTrades; // Max Alloed Positions @@ -1995,6 +2056,12 @@ private: int mReuiredSignalVerifications; // Required Verifications for Validate Signals bool mGetVerificationFromOtherTimeFrames; // Get Verifications from Other Time Frames + // + bool mUseSupport; // Use Support Signals + bool mUseGrid; // Use Grid Signals + double mGridDistance; // Grid Distance + double mGridVolumeMultiplier; // Grid Volume Multiplier + // XSignalInfo mSignalInfos[]; XSignalInfoCollector *mSignalCollector; @@ -2098,11 +2165,20 @@ private: // if (IsValid(deal.provider)) { - result = FindSignalInfoIndex( - deal.symbol, - deal.provider, - deal.period // - ); + // + ulong supTicket = ExtractSupportedTicket(deal.comment); + ulong supTicket1 = ExtractEQMSupportedTicket(deal.comment); + + // + if (supTicket <= 0 && supTicket1 <= 0) + { + // + result = FindSignalInfoIndex( + deal.symbol, + deal.provider, + deal.period // + ); + } } else { @@ -2167,6 +2243,30 @@ private: mSignalInfos[infoIDX].ticket = deal.positionId; mSignalInfos[infoIDX].commission = deal.commission; mSignalInfos[infoIDX].signal.positionId = deal.positionId; + + // + bool isLong = IsLong(mSignalInfos[infoIDX].signal.type); + double sEntry = mSignalInfos[infoIDX].signal.entry; + + // + // Setting Grid Data ... + if (mUseGrid) + { + // + mSignalInfos[infoIDX].ResetGrid(); + + // + double gDistancePrice = PointToPrice( + mGridDistance, + mSignalInfos[infoIDX].signal.symbol // + ); + + // + mSignalInfos[infoIDX].gVolume = mSignalInfos[infoIDX].volume * mGridVolumeMultiplier; + mSignalInfos[infoIDX].gEntry = isLong + ? sEntry - gDistancePrice + : sEntry + gDistancePrice; + } } else if (deal.entry == DEAL_ENTRY_OUT) { @@ -2527,6 +2627,148 @@ private: } } + // + // Do Gridding Mechanism ... + void DoEQMGrid() + { + // + if (!mUseGrid) + { + return; + } + + // + int infosCount = CountSignalInfos(); + if (!IsValidSize(infosCount)) + { + return; + } + + // + for (int i = 0; i < infosCount; i++) + { + // + // Check Signal Executed or not ... + if (mSignalInfos[i].ticket <= 0) + { + continue; + } + + // + // Check Specific Position not a Support Position ... + XPosition position; + bool hasPosition = mTrader.GetPosition( + mSignalInfos[i].ticket, + position // + ); + if (!hasPosition) + { + continue; + } + + // + // Check Position not a Support or EQM Support ... + ulong supParent = 0; + supParent = ExtractSupportedTicket(position.comment); + if (supParent > 0) + { + continue; + } + supParent = ExtractEQMSupportedTicket(position.comment); + if (supParent > 0) + { + continue; + } + + // + // Check Grid Data ... + if (mSignalInfos[i].gEntry <= 0 || mSignalInfos[i].gVolume <= 0) + { + continue; + } + + // + // Retrieve Type of Position ... + bool isLong = IsLong(mSignalInfos[i].signal.type); + + // + // Retrieve Cureent Entry Price based on Signal ... + double cEntry = GetEntry( + mSignalInfos[i].symbol, + mSignalInfos[i].signal.type // + ); + + // + // Check Price Distance passed or not ... + bool isPriceDistancePassedForGrid = + isLong + ? cEntry <= mSignalInfos[i].gEntry + : cEntry >= mSignalInfos[i].gEntry; + if (!isPriceDistancePassedForGrid) + { + continue; + } + + // + // Prepare Grid Signal ... + XSignal gSignal; + bool isPrepared = gSignal.Prepare( + mSignalInfos[i].signal.symbol, + mSignalInfos[i].signal.provider, + mSignalInfos[i].signal.period, + mSignalInfos[i].signal.type, + X_ORDER_MODE_MARKET, + mSignalInfos[i].gEntry, + mSignalInfos[i].gVolume, + 0, // SL ... + 0 // TP ... + ); + if (!isPrepared) + { + continue; + } + + // + // Add Support Tag ... + string comment = GenerateSupportTag(mSignalInfos[i].ticket); + gSignal.comment = comment; + + // + // Try to Execute Grid Signal ... + ENUM_X_SIGNAL_EXECUTION_RESULT gState; + int isExecuted = mTrader.ExecuteSignal( + gSignal, + gState, + ORDER_TIME_GTC, + NULL, + false // Ignore Policies ... + ); + if (isExecuted) + { + // + // Update Grid State of Signal Info ... + + // + double gDistancePrice = PointToPrice( + mGridDistance, + mSignalInfos[i].signal.symbol // + ); + + // + mSignalInfos[i].gVolume *= mGridVolumeMultiplier; + mSignalInfos[i].gEntry = isLong + ? mSignalInfos[i].gEntry - gDistancePrice + : mSignalInfos[i].gEntry + gDistancePrice; + + // + string message = XEQMSupportToken + " Execute Grid ..."; + + // + Alert(message); + } + } + } + // // Handle Close Trades on Specific Time ... void DoEQMCloseOnSpecificTime() diff --git a/Experts/x-saherelm.x121.ea.mq5 b/Experts/x-saherelm.x121.ea.mq5 index 9d98fb97..4bb45ac1 100644 --- a/Experts/x-saherelm.x121.ea.mq5 +++ b/Experts/x-saherelm.x121.ea.mq5 @@ -48,18 +48,21 @@ input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications // // Risk Management ... input group "Risk Management"; -input double x121EAVolume = 0.01; // Static Volume -input double x121EATPPoint = 60; // TP Point -input double x121EASLPoint = 300; // SL Point -input int x121EAMaxAllowedTrades = 1; // Max Allowed Positions -input bool x121EAIgnoreSL = true; // Ignore Calculated SL -input bool x121EAIgnoreTP = false; // Ignore Calculated TP -input bool x121EAUseSupport = false; // Use Support Signals -input double x121EAMinRequiredProfitPerTrade = 0; // Minimum Required Profit for Hedging -input double x121EAMinRequiredProfitPerVolumeFactor = 0; // Minimum Required Profit for Hedging Per Velume -input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge -input int x121EACloseOnSpecificTime = -1; // Close All Trades in Specific Time -input bool x121EACloseOnOpposit = false; // Close all Positions on Opposit +input double x121EAVolume = 0.01; // Static Volume +input double x121EATPPoint = 60; // TP Point +input double x121EASLPoint = 300; // SL Point +input int x121EAMaxAllowedTrades = 1; // Max Allowed Positions +input bool x121EAIgnoreSL = true; // Ignore Calculated SL +input bool x121EAIgnoreTP = false; // Ignore Calculated TP +input bool x121EAUseSupport = false; // Use Support Signals +input bool x121EAUseGrid = true; // Use Grid Signals +input double x121EAGridDistance = 50; // Grid Distance +input double x121EAGridVolumeMultiplier = 2; // Grid Volume Multiplier +input double x121EAMinRequiredProfitPerTrade = 1; // Minimum Required Profit for Hedging +input double x121EAMinRequiredProfitPerVolumeFactor = 0.1; // Minimum Required Profit for Hedging Per Velume +input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge +input int x121EACloseOnSpecificTime = -1; // Close All Trades in Specific Time +input bool x121EACloseOnOpposit = false; // Close all Positions on Opposit // // Alert ... @@ -174,7 +177,6 @@ bool InitialEA() x121EA.IgnoreTP(x121EAIgnoreTP); x121EA.AllowLong(x121EAAllowLong); x121EA.AllowShort(x121EAAllowShort); - x121EA.UseSupport(x121EAUseSupport); x121EA.CloseOnOpposit(x121EACloseOnOpposit); x121EA.MaxAllowedTrades(x121EAMaxAllowedTrades); x121EA.RestingAfterHedge(x121EARestingAfterHedge); @@ -184,6 +186,12 @@ bool InitialEA() x121EA.MinRequiredProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor); x121EA.GetVerificationFromOtherTimeFrames(x121EAGetVerificationFromOtherTimeFrames); + // + x121EA.UseGrid(x121EAUseGrid); + x121EA.UseSupport(x121EAUseSupport); + x121EA.GridDistance(x121EAGridDistance); + x121EA.GridVolumeMultiplier(x121EAGridVolumeMultiplier); + // // Configure Alert ... x121EA.SetAlertPrefix(ShortName);