From 6063d3be61b4e273a279f775cad729942643dad5 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sat, 22 Jun 2024 08:33:18 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x121.setup.class.mq5 | 49 ++++ Classes/x-saherelm.x121.setup.xea.mq5 | 328 +++++++++++++++++++++--- Classes/x-saherelm.xea.class.mq5 | 8 +- Experts/x-saherelm.x121.ea.mq5 | 189 ++++++++++++-- Libraries/x-saherelm.xtrade.lib.mq5 | 80 ++++++ 5 files changed, 597 insertions(+), 57 deletions(-) diff --git a/Classes/x-saherelm.x121.setup.class.mq5 b/Classes/x-saherelm.x121.setup.class.mq5 index 77b0c4ff..6560f2ec 100644 --- a/Classes/x-saherelm.x121.setup.class.mq5 +++ b/Classes/x-saherelm.x121.setup.class.mq5 @@ -69,6 +69,7 @@ enum ENUM_X121_SIGNAL_PROVIDER PROVIDER_XASCT = 16, PROVIDER_XVLM = 17, PROVIDER_XPVF = 18, + PROVIDER_XPVSAR = 19, }; // @@ -197,6 +198,10 @@ ENUM_X121_SIGNAL_PROVIDER FromString(string value) { result = PROVIDER_XPVF; } + else if (Contains(value, (EnumToString(PROVIDER_XPVSAR)))) + { + result = PROVIDER_XPVSAR; + } // return result; @@ -1422,6 +1427,24 @@ struct X121SignalGenerator provider = ToString(PROVIDER_XPVF); } + // + // XPVSAR ... + bool long19 = + // + // Starting Conditions ... + conditions.mcConditions.isSARSwitchedToBullish && + conditions.pvConditions.vales[zIndex] == conditions.mcConditions.psar[zIndex] && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish + // + ; + if (long19) + { + // + pusher += 2; + provider = ToString(PROVIDER_XPVSAR); + } + // result = // @@ -1500,6 +1523,10 @@ struct X121SignalGenerator // long18 // + || + // + long19 + // ) // ; @@ -2068,6 +2095,24 @@ struct X121SignalGenerator provider = ToString(PROVIDER_XPVF); } + // + // XPVSAR ... + bool short19 = + // + // Starting Conditions ... + conditions.mcConditions.isSARSwitchedToBearish && + conditions.pvConditions.peaks[zIndex] == conditions.mcConditions.psar[zIndex] && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish + // + ; + if (short19) + { + // + pusher += 2; + provider = ToString(PROVIDER_XPVSAR); + } + // result = // @@ -2146,6 +2191,10 @@ struct X121SignalGenerator // short18 // + || + // + short19 + // ) // ; diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index 2439a1ff..c9067778 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -2825,6 +2825,25 @@ public: mAllowShort = value; } + // + int DelayBetweenTwoSignal() + { + return mDelayBetweenTwoSignal; + } + + // + void DelayBetweenTwoSignal(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mDelayBetweenTwoSignal = value; + } + // int ReuiredSignalVerifications() { @@ -3318,6 +3337,44 @@ public: mForceCloseProfit = value; } + // + double MaxDrawdownForce() + { + return mMaxDrawdownForce; + } + + // + void MaxDrawdownForce(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxDrawdownForce = value; + } + + // + int MaxPositionsForce() + { + return mMaxPositionsForce; + } + + // + void MaxPositionsForce(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxPositionsForce = value; + } + // bool ForceState() { @@ -3349,6 +3406,18 @@ public: // // Tools ... + // + double GetBullishScore() + { + return mBullishScore; + } + + // + double GetBearishScore() + { + return mBearishScore; + } + // // Check Provider for any Guards ... bool CheckForGuard(XGuard &guards[]) override @@ -4187,10 +4256,18 @@ public: if (isSignalValid) { // - AddRef( - iSignal, - eSignals // - ); + // Check Delay Between Two Signals ... + bool isDelayPassed = IsSignalDelayPassed(iSignal); + + // + if (isDelayPassed) + { + // + AddRef( + iSignal, + eSignals // + ); + } } } @@ -4409,6 +4486,62 @@ protected: ); } + // + // Check Delay Between Two Signals ... + bool IsSignalDelayPassed( + XSignal &signal // + ) + { + // + bool result = false; + + // + // Check Signal Validation ... + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + // Check Delay Signals Allowed ... + int delay = DelayBetweenTwoSignal(); + result = delay <= 0; + if (result) + { + return result; + } + + // + // Retrieve Positions ... + // Based On Provider and Symbol and TimeFrame ... + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions, + signal.symbol, + signal.provider, + signal.period, + ToPositionType(signal.type), + true // Filter By Magic ... + ); + result = !IsValidSize(positionsCount); + if (result) + { + return result; + } + + // + XPosition youngest; + int youngestAge = GetYoungest( + youngest, + positions // + ); + result = youngestAge >= delay; + + // + return result; + } + // // Private ... private: @@ -4446,7 +4579,10 @@ private: // - Receive Signals with minimal Verifications; // - Increase Volume Size of in Profit Positions; // - etc ... - bool mForceState; // Determine in Force State or not + bool mForceState; // Determine in Force State or not + int mDelayBetweenTwoSignal; // Delay between two same signal + int mMaxPositionsForce; // Max Number of Positions For Guard Handling + double mMaxDrawdownForce; // Force Handling State on Drawdown for Guard // XTradeHandler *mTradeHandler; // Handle all Event which related to Signals and Positions @@ -4641,10 +4777,8 @@ private: } // - double profit = SpecifiedIsPositionsReadyForHedge( - positions, - 0.15, - 0.01 // + double profit = SpecifiedCalculatePositionsProfit( + positions // ); result = profit > hedgingProfit; @@ -4761,30 +4895,158 @@ private: return; } + // + double profits = SpecifiedCalculatePositionsProfit(positionsCount); + // // Checking Force Sate Conditions ... if (ForceState()) { // // Check Force State Hedging ... - // bool isHedged = DoEQMForceClose(); - // if (isHedged) - // { - // // - // ForceState(false); - // return; - // } + bool isHedged = DoEQMForceClose(); + if (isHedged) + { + // + ForceState(false); + return; + } - // // - // isHedged = DoEQMForceClose(5); - // if (isHedged) - // { - // // - // ForceState(false); - // return; - // } + // + // Handle Act Based On Drawdow ... + if (mMaxDrawdownForce > 0) + { + // + double drawdown = GetDrawdownPercent(); + if (drawdown > 5) + { + // + // Try to Hedge ... + if (profits > 0) + { + // + bool isHedged = DoEQMForceClose(profits); + if (isHedged) + { + // + ForceState(false); + return; + } + } - // // + // + // Close Max In Drawdown Position ... + int maxInDIDX = FindMaxDrawdownIndex(positions); + if (isValidIndex(maxInDIDX)) + { + // + string comment = XEQMSupportToken + " Max In D ..."; + + // + bool isClosed = mTrader.Close( + positions[maxInDIDX].ticket, + comment // + ); + if (isClosed) + { + // + string message = XEQMSupportToken + "Close " + ToString(positions[maxInDIDX].ticket) + " Due Max In Drawdown ..."; + + // + Alert(message); + } + + // + return; + } + + // + return; + } + } + + // + // Handle Act Based on Positions Count ... + if (mMaxPositionsForce > 0 && positionsCount > mMaxPositionsForce) + { + // + double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( + positions, + mMinRequiredProfitPerTrade, + mMinRequiredProfitPerVolumeFactor // + ); + + // + double halfProfit = requiredProfit / 2; + if (halfProfit > 0 && profit > halfProfit) + { + // + bool isHedged = DoEQMForceClose(halfProfit); + if (isHedged) + { + // + ForceState(false); + return; + } + } + + // + // Close Min In Profit Position ... + int minInPIDX = FindMinProfitIndex(positions); + if (IsValidIndex(minInPIDX)) + { + // + string comment = XEQMSupportToken + " Min In P ..."; + + // + bool isClosed = mTrader.Close( + positions[minInPIDX].ticket, + comment // + ); + if (isClosed) + { + // + string message = XEQMSupportToken + "Close " + ToString(positions[maxInDIDX].ticket) + " Due Min In Profit ..."; + + // + Alert(message); + + // + return; + } + } + + // + // Close Max In Drawdown Position ... + int maxInDIDX = FindMaxDrawdownIndex(positions); + if (isValidIndex(maxInDIDX)) + { + // + string comment = XEQMSupportToken + " Max In D ..."; + + // + bool isClosed = mTrader.Close( + positions[maxInDIDX].ticket, + comment // + ); + if (isClosed) + { + // + string message = XEQMSupportToken + "Close " + ToString(positions[maxInDIDX].ticket) + " Due Max In Drawdown ..."; + + // + Alert(message); + } + + // + return; + } + + // + return; + } + + // return; } @@ -4905,10 +5167,18 @@ private: if (isValid) { // - AddRef( - signal, - signals // - ); + // Check Delay Between Two Signals ... + bool isDelayPassed = IsSignalDelayPassed(signal); + + // + if (isDelayPassed) + { + // + AddRef( + signal, + signals // + ); + } } // diff --git a/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index ce0a253f..9a47a845 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -39,6 +39,10 @@ public: // // Props ... + // + // Trade Class Instance ... + XSCTrade *mTrader; + // // Constructor ... XSCBaseEA( @@ -580,10 +584,6 @@ protected: // // Props ... - // - // Trade Class Instance ... - XSCTrade *mTrader; - // // Check in Test Mode or not ... bool mIsInTestMode; diff --git a/Experts/x-saherelm.x121.ea.mq5 b/Experts/x-saherelm.x121.ea.mq5 index 09f1939d..cc049abb 100644 --- a/Experts/x-saherelm.x121.ea.mq5 +++ b/Experts/x-saherelm.x121.ea.mq5 @@ -46,6 +46,7 @@ input bool x121EAUseAllSymbols = false; input bool x121EAUseAllWatchListSymbols = false; // Use All WatchList Symbols input bool x121EAAllowLong = true; // Allow Long Trades input bool x121EAAllowShort = true; // Allow Short Trades +input int x121EADelayBetweenTwoSignal = 10; // Delay Between two Same Signals input int x121EAReuiredSignalVerifications = 5; // Required Verifications for Signals input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications from Other Time Frames @@ -102,9 +103,11 @@ input double x121EAMaxAllowedRecoveryVolume = 0.08; // Max Allowed Recovery Sign // input group "Hedging"; input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge +input double x121EAForceCloseProfit = 15; // Close All Positions Regardless of Policies when Profit Reached +input double x121EAMaxDrawdownForce = 5; // Max Drawdown Force State for Handling Guards +input int x121EAMaxPositionsForce = 15; // Max Number of Positions Force State for Handling Guards input double x121EAMinRequiredProfitPerTrade = 0.5; // Minimum Required Profit for Hedging input double x121EAMinRequiredProfitPerVolumeFactor = 0.01; // Minimum Required Profit for Hedging Per Volume -input double x121EAForceCloseProfit = 20; // Close All Positions Regardless of Policies when Profit Reached // // Alert ... @@ -122,6 +125,7 @@ input bool x121EATerminalAlerts = false; // Terminal Alerts // Local Variables ... // +string x121EAUsedSymbols[]; XSCX121SetupEA *x121EA; // @@ -170,7 +174,11 @@ void OnDeinit(const int reason) // On Tick Handler ... void OnTick() { + // x121EA.OnTick(); + + // + X121ReportState(); } // @@ -206,13 +214,13 @@ bool InitialEA() ); // - string symbols[]; + Clean(x121EAUsedSymbols); if (x121EAUseAllSymbols) { // Copy( allSymbols, - symbols // + x121EAUsedSymbols // ); } else if (x121EAUseAllWatchListSymbols) @@ -220,7 +228,7 @@ bool InitialEA() // Copy( watchListSymbols, - symbols // + x121EAUsedSymbols // ); } else if (IsValidSize(inputSymbolsCount)) @@ -228,7 +236,7 @@ bool InitialEA() // Copy( inputSymbols, - symbols // + x121EAUsedSymbols // ); } else @@ -236,10 +244,10 @@ bool InitialEA() // Add( _Symbol, - symbols // + x121EAUsedSymbols // ); } - int symbolsCount = ArraySize(symbols); + int symbolsCount = ArraySize(x121EAUsedSymbols); result = IsValidSize(symbolsCount); if (!result) { @@ -259,6 +267,7 @@ bool InitialEA() // Signals ... x121EA.AllowLong(x121EAAllowLong); x121EA.AllowShort(x121EAAllowShort); + x121EA.DelayBetweenTwoSignal(x121EADelayBetweenTwoSignal); x121EA.ReuiredSignalVerifications(x121EAReuiredSignalVerifications); x121EA.GetVerificationFromOtherTimeFrames(x121EAGetVerificationFromOtherTimeFrames); @@ -317,6 +326,8 @@ bool InitialEA() // Hedging ... x121EA.ForceCloseProfit(x121EAForceCloseProfit); x121EA.RestingAfterHedge(x121EARestingAfterHedge); + x121EA.MaxDrawdownForce(x121EAMaxDrawdownForce); + x121EA.MaxPositionsForce(x121EAMaxPositionsForce); x121EA.MinRequiredProfitPerTrade(x121EAMinRequiredProfitPerTrade); x121EA.MinRequiredProfitPerVolumeFactor(x121EAMinRequiredProfitPerVolumeFactor); @@ -333,7 +344,7 @@ bool InitialEA() // Configure Indicators ... X121SetupInputs setupInputsDefault; setupInputsDefault.Default(); - PreConfigureStyles(setupInputsDefault); + X121PreConfigureStyles(setupInputsDefault); // // Prepare Providers and Add them into mX121EA class ... @@ -341,7 +352,7 @@ bool InitialEA() { // // Requirements ... - string iSymbol = symbols[i]; + string iSymbol = x121EAUsedSymbols[i]; ENUM_TIMEFRAMES iHostPeriod = _Period; // @@ -370,25 +381,25 @@ bool InitialEA() } // -void PreConfigureStyles(X121SetupInputs &inputs) +void X121PreConfigureStyles(X121SetupInputs &inputs) { // // XPV ... - inputs.pvInputs.showPeaksAndVales = true; + inputs.pvInputs.showPeaksAndVales = false; inputs.pvInputs.showLevels = false; inputs.pvInputs.showConsolidations = false; - inputs.pvInputs.showFibo1Levels = true; - inputs.pvInputs.showFibo2Levels = true; - inputs.pvInputs.showFibo3Levels = true; - inputs.pvInputs.showFibo4Levels = true; - inputs.pvInputs.showFibo5Levels = true; + inputs.pvInputs.showFibo1Levels = false; + inputs.pvInputs.showFibo2Levels = false; + inputs.pvInputs.showFibo3Levels = false; + inputs.pvInputs.showFibo4Levels = false; + inputs.pvInputs.showFibo5Levels = false; // // XMC ... - inputs.mcInputs.showSar = true; - inputs.mcInputs.showFastMa = true; - inputs.mcInputs.showSlowMa = true; - inputs.mcInputs.showVerifierMa = true; + inputs.mcInputs.showSar = false; + inputs.mcInputs.showFastMa = false; + inputs.mcInputs.showSlowMa = false; + inputs.mcInputs.showVerifierMa = false; // // XHK ... @@ -398,9 +409,9 @@ void PreConfigureStyles(X121SetupInputs &inputs) // // XCHE ... inputs.cheInputs.showLongExit1Line = false; - inputs.cheInputs.showShortExit1Line = true; + inputs.cheInputs.showShortExit1Line = false; inputs.cheInputs.showLongExit2Line = false; - inputs.cheInputs.showShortExit2Line = true; + inputs.cheInputs.showShortExit2Line = false; // // XICH ... @@ -415,7 +426,7 @@ void PreConfigureStyles(X121SetupInputs &inputs) // // XSTR ... - inputs.strInputs.showTrends = true; + inputs.strInputs.showTrends = false; inputs.strInputs.fillTrends = false; // @@ -440,4 +451,134 @@ void PreConfigureStyles(X121SetupInputs &inputs) inputs.hullInputs.showDownZone = false; } -// \ No newline at end of file +// +void X121ReportState() +{ + // + string comment = NULL; + + // + comment = + ShortName + "\n" + + "------------" + "\n" + + "Trading Symbols: " + ToString(ArraySize(x121EAUsedSymbols)) + "\n" + "\n"; + + // + // Detect What we Want to Show as Comment ... + bool isInForceState = x121EA.ForceState(); + double bullishScore = 0; // x121EA.GetBullishScore(); + double bearishScore = 0; // x121EA.GetBearishScore(); + double drawDownPercent = x121EA.GetDrawdownPercent(); + + // + comment += + // + (bullishScore > 0 || bearishScore > 0 + ? "Scores:" + "\n" + + "------------" + "\n" + + "Bullish: " + ToString(bullishScore) + "\n" + + "Bearish: " + ToString(bearishScore) + "\n" + + "------------" + "\n" + : "") + + "Drawdown: " + ToString(drawDownPercent) + "%" + "\n" + + "------------" + "\n" + + "Force State: " + ToString(isInForceState) + "\n" + + // + "" + // + ; + + // + XPosition positions[]; + int positionsCount = x121EA.mTrader.GetPositions( + positions // + ); + if (IsValidSize(positionsCount)) + { + // + int longs = 0; + double longVolumes = 0; + double longProfits = 0; + + // + int shorts = 0; + double shortVolumes = 0; + double shortProfits = 0; + + // + // Retrieve Required Informations of Positions ... + CountPositions( + positions, + longs, + longProfits, + longVolumes, + shorts, + shortProfits, + shortVolumes // + ); + + // + comment += + // + "------------" + "\n" + + "Positions: " + "\n" + + "------------" + "\n" + + (longs <= 0 + ? "" + : "\n" + "Longs:" + "\n" + + "------------" + "\n" + + "Count: " + ToString(longs) + "\n" + + "Profits: " + ToString(longProfits) + "\n" + + "" + // + ) + + // + (shorts <= 0 + ? "" + : "\n" + "Shorts:" + "\n" + + "------------" + "\n" + + "Count: " + ToString(shorts) + "\n" + + "Profits: " + ToString(shortProfits) + "\n" + + "" + // + ) + + // + "" + // + ; + } + + // + if (positionsCount > 1 && x121EAMinRequiredProfitPerTrade > 0 && x121EAMinRequiredProfitPerVolumeFactor > 0) + { + // + double profit = SpecifiedCalculatePositionsProfit( + positions // + ); + double requiredProfitForHedge = SpecifiedCalculateRequiredProfitForHedge( + positions, + x121EAMinRequiredProfitPerTrade, + x121EAMinRequiredProfitPerVolumeFactor // + ); + + // + comment += + // + "\n" + "Hedging: " + "\n" + + "------------" + "\n" + + "Profits: " + ToString(profit) + "\n" + + "RequiredProft: " + ToString(requiredProfitForHedge) + "\n" + + // + "" + // + ; + } + + // + if (IsValid(comment)) + { + Comment(comment); + } +} + +// diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index 6c020205..9365b301 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -3266,6 +3266,46 @@ int FindMaxProfitIndex( return result; } +// +int FindMinProfitIndex( + XPosition &positions[] // Position Collection +) +{ + // + int result = -1; + + // + int positionsCount = ArraySize(positions); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + double min = 0; + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + if (iPosition.profit <= 0) + { + continue; + } + + // + if (min == 0 || + min > iPosition.profit) + { + // + result = i; + min = iPosition.profit; + } + } + + // + return result; +} + // int ExtractInProfitPositions( XPosition &positions[], // Position Collection @@ -3324,6 +3364,46 @@ int FindMaxDrawdownIndex( return result; } + // + double max = 0; + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + if (iPosition.profit >= 0) + { + continue; + } + + // + if (max == 0 || + max < iPosition.profit) + { + // + result = i; + max = iPosition.profit; + } + } + + // + return result; +} + +// +int FindMinDrawdownIndex( + XPosition &positions[] // Position Collection +) +{ + // + int result = -1; + + // + int positionsCount = ArraySize(positions); + if (!IsValidSize(positionsCount)) + { + return result; + } + // double min = 0; for (int i = 0; i < positionsCount; i++)