From 9393c9ecfea10c78e0b15414e14d0dee4ccc6c84 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Wed, 18 Sep 2024 21:13:23 +0330 Subject: [PATCH] Implement Position Protector ... need to test BE Hedge ... --- .vscode/vscode-kanban.json | 2 +- .../x-saherelm.x121.xtrade.handler.class.mq5 | 522 ++++++++++++++---- Experts/x-saherelm.x121.ea.mq5 | 36 ++ Libraries/x-saherelm.common.lib.mq5 | 155 +++++- Libraries/x-saherelm.xtrade.lib.mq5 | 7 +- Strategies/x-saherelm.xch.che.strategy.mq5 | 10 +- Strategies/x-saherelm.xch.strategy.mq5 | 10 +- 7 files changed, 623 insertions(+), 119 deletions(-) diff --git a/.vscode/vscode-kanban.json b/.vscode/vscode-kanban.json index 81cfaeaa..08744163 100644 --- a/.vscode/vscode-kanban.json +++ b/.vscode/vscode-kanban.json @@ -38,7 +38,7 @@ }, "creation_time": "2024-09-16T23:16:09.221Z", "description": { - "content": "- [] Conditions for In Profit;\n- [] Conditions for In DrawDown;", + "content": "- [x] Conditions for In Profit;\n- [] Conditions for In DrawDown;", "mime": "text/markdown" }, "id": "93", diff --git a/Classes/x-saherelm.x121.xtrade.handler.class.mq5 b/Classes/x-saherelm.x121.xtrade.handler.class.mq5 index bb05fd2b..f4940de1 100644 --- a/Classes/x-saherelm.x121.xtrade.handler.class.mq5 +++ b/Classes/x-saherelm.x121.xtrade.handler.class.mq5 @@ -54,8 +54,10 @@ struct X121TradeData string conditions; // Signal Conditions // - int trailStep; // Trail Step - bool partiallyClosed; // Partially Closed or not + int trailStep; // Trail Step + int protectionStep; // Protection Step + double lastProtectedVolume; // Last Protected Volume + bool partiallyClosed; // Partially Closed or not // // Constructor ... @@ -195,7 +197,9 @@ struct X121TradeData // trailStep = 0; + protectionStep = 0; partiallyClosed = false; + lastProtectedVolume = 0; // signal.Clean(); @@ -1107,6 +1111,18 @@ class X121SCTradeHandler : public XSCBaseAlert mAllowTrailStopInProfits = value; } + // + bool OnlyTrailUnprotectedPositions() + { + return mOnlyTrailUnprotectedPositions; + } + + // + void OnlyTrailUnprotectedPositions(bool value) + { + mOnlyTrailUnprotectedPositions = value; + } + // double TrailStopStepsInPoint() { @@ -1146,13 +1162,13 @@ class X121SCTradeHandler : public XSCBaseAlert } // - double PartialCloseOnSpecificPoint() + double PartialCloseOnSpecificPointOfProfit() { - return mPartialCloseOnSpecificPoint; + return mPartialCloseOnSpecificPointOfProfit; } // - void PartialCloseOnSpecificPoint(double value) + void PartialCloseOnSpecificPointOfProfit(double value) { // if (value < 0) @@ -1161,17 +1177,17 @@ class X121SCTradeHandler : public XSCBaseAlert } // - mPartialCloseOnSpecificPoint = value; + mPartialCloseOnSpecificPointOfProfit = value; } // - double PartialCloseVolume() + double PartialCloseVolumeInProfit() { - return mPartialCloseVolume; + return mPartialCloseVolumeInProfit; } // - void PartialCloseVolume(double value) + void PartialCloseVolumeInProfit(double value) { // if (value < 0) @@ -1180,7 +1196,79 @@ class X121SCTradeHandler : public XSCBaseAlert } // - mPartialCloseVolume = value; + mPartialCloseVolumeInProfit = value; + } + + // + // In Drawdown Positions Protecting ... + + // + bool AllowRecoverInDrawdowns() + { + return mAllowRecoverInDrawdowns; + } + + // + void AllowRecoverInDrawdowns(bool value) + { + mAllowRecoverInDrawdowns = value; + } + + // + double RecoveryMultiplier() + { + return mRecoveryMultiplier; + } + + // + void RecoveryMultiplier(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mRecoveryMultiplier = value; + } + + // + double PartialCloseOnSpecificPointOfDrawdown() + { + return mPartialCloseOnSpecificPointOfDrawdown; + } + + // + void PartialCloseOnSpecificPointOfDrawdown(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mPartialCloseOnSpecificPointOfDrawdown = value; + } + + // + double PartialCloseVolumeInDrawdown() + { + return mPartialCloseVolumeInDrawdown; + } + + // + void PartialCloseVolumeInDrawdown(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mPartialCloseVolumeInDrawdown = value; } // @@ -1772,20 +1860,6 @@ class X121SCTradeHandler : public XSCBaseAlert return result; } - // - // TODO: - // Here we can apply Same type or Opposit Type - // Signals behaviour ... - // also check For Market Open ... - - // - // Check Market ... - // TODO: Fix this ... - // result = mSymbolSession.CanTrade(signal.symbol); - // if (!result) { - // return result; - // } - // return result; } @@ -2054,15 +2128,15 @@ class X121SCTradeHandler : public XSCBaseAlert XPosition iPosition = iProtected.main; // - double iSymbolPoint = GetPoints(iPosition.symbol); - double iDistance = MathAbs(iPosition.profit) * iSymbolPoint; - - // + double iDistance = MathAbs(iPosition.GetProfitInPoint()); bool isDistancePassed = iDistance >= requiredDistance; if (isDistancePassed) { // - bool isProtected = HandlePositionProtecting(iPosition); + bool isProtected = HandlePositionProtecting( + iPosition, + iProtected.supports // + ); if (isProtected) { protectedPositions++; @@ -2200,6 +2274,7 @@ class X121SCTradeHandler : public XSCBaseAlert // int minOpenPositions = MinimumOpenPositionsForHEHedge(); double heMinProfitPerVolumeStep = HedgeHEMinProfitPerVolumeStep(); + double beMinProfitPerVolumeStep = HedgeBEMinProfitPerVolumeStep(); // // Check HE Hedge Conditions ... @@ -2271,21 +2346,58 @@ class X121SCTradeHandler : public XSCBaseAlert // // Check BE Hedge Conditions ... bool allowBEHedge = positionsCount >= 1 && - supportsCount >= 1; + supportsCount >= 1 && + beMinProfitPerVolumeStep > 0; if (allowBEHedge) { // // Implement BE Hedge ... // - // Check BE Conditions ... - result = supportsCount > 0; + // Check Profits ... + result = profits > 0; if (!result) { return result; } // + // Calculate Required Profit ... + double volumeSteps = volumes / minVolumeStep; + double minRequiredProfit = (volumeSteps * beMinProfitPerVolumeStep) + + commissions + (-1 * swaps); + + // + // Check Profits Satisfied Required Profit's For Hedge or not ... + result = profits >= minRequiredProfit; + if (!result) + { + return result; + } + + // + int flatPositionsCount = ArraySize(flatPositions); + result = IsValidSize(flatPositionsCount); + if (!result) + { + return result; + } + + // + string comment = "EQM BE Hedge ..."; + int closed = mTrader.Close( + flatPositions, + comment // + ); + + // + result = closed > 0; + if (result) + { + // + string message = "EQM BE Hedge Close (" + ToString(flatPositionsCount) + ") Positions by: " + ToString(profits); + Alert(message); + } // return result; @@ -2298,7 +2410,10 @@ class X121SCTradeHandler : public XSCBaseAlert /** * Handle Protecting Position ... */ - bool HandlePositionProtecting(XPosition &position) + bool HandlePositionProtecting( + XPosition &position, // Main Position + XPosition &supports[] // Supports + ) { // bool result = false; @@ -2322,6 +2437,9 @@ class X121SCTradeHandler : public XSCBaseAlert bool isLong = IsLong(position.type); bool isInProfit = position.profit > 0; + // + int supportsCount = ArraySize(supports); + // int zIndex = 0; int cIndex = zIndex + 1; @@ -2394,6 +2512,15 @@ class X121SCTradeHandler : public XSCBaseAlert tmpLSW, false // ); + bool hasBullishTrend = + // + isBullishTrend + // + || + // + isBullishTrend1 + // + ; // // Bearish ... @@ -2410,6 +2537,15 @@ class X121SCTradeHandler : public XSCBaseAlert tmpLSW, false // ); + bool hasBearishTrend = + // + isBearishTrend + // + || + // + isBearishTrend1 + // + ; // // Define Conditions ... @@ -2426,35 +2562,38 @@ class X121SCTradeHandler : public XSCBaseAlert // TODO: Check Volume if Required ... // - bool isTicksBullish = - ( - // - ticks[0].last > ticks[1].last && - ticks[1].last > ticks[2].last && - ticks[2].last > ticks[3].last && - ticks[3].last > ticks[4].last - // - ); + bool isTicksBullishForLong = + // + GetTickExit(ticks[0], POSITION_TYPE_BUY, position.symbol) > GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) && + GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) > GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) && + GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) > GetTickExit(ticks[3], POSITION_TYPE_BUY, position.symbol) + // + ; // - bool isTicksBearish = - ( - // - ticks[0].last < ticks[1].last && - ticks[1].last < ticks[2].last && - ticks[2].last < ticks[3].last && - ticks[3].last < ticks[4].last - // - ); + bool isTicksBearishForLong = + // + GetTickExit(ticks[0], POSITION_TYPE_BUY, position.symbol) < GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) && + GetTickExit(ticks[1], POSITION_TYPE_BUY, position.symbol) < GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) && + GetTickExit(ticks[2], POSITION_TYPE_BUY, position.symbol) < GetTickExit(ticks[3], POSITION_TYPE_BUY, position.symbol) + // + ; // - bool hasBearishDecision = + bool isTicksBullishForShort = // - cBar.IsBearishDecision() + GetTickExit(ticks[0], POSITION_TYPE_SELL, position.symbol) > GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) && + GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) > GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) && + GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) > GetTickExit(ticks[3], POSITION_TYPE_SELL, position.symbol) // - || + ; + + // + bool isTicksBearishForShort = // - pBar.IsBearishDecision() + GetTickExit(ticks[0], POSITION_TYPE_SELL, position.symbol) < GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) && + GetTickExit(ticks[1], POSITION_TYPE_SELL, position.symbol) < GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) && + GetTickExit(ticks[2], POSITION_TYPE_SELL, position.symbol) < GetTickExit(ticks[3], POSITION_TYPE_SELL, position.symbol) // ; @@ -2463,33 +2602,42 @@ class X121SCTradeHandler : public XSCBaseAlert // cBar.IsBullishDecision() // - || + ; + + // + bool hasBearishDecision = // - pBar.IsBullishDecision() + cBar.IsBearishDecision() // ; // bool hasBullishConditions = // - isTicksBullish && - (isBullishTrend || - isBullishTrend1) && - (hasBullishPower || - hasBullishPattern || - hasBullishPressure) + ( + // + hasBullishTrend && + hasBullishDecision && + (hasBullishPower || + hasBullishPattern || + hasBullishPressure) + // + ) // ; // bool hasBearishConditions = // - isTicksBearish && - (isBearishTrend || - isBearishTrend1) && - (hasBearishPower || - hasBearishPattern || - hasBearishPressure) + ( + // + hasBearishTrend && + hasBearishDecision && + (hasBearishPower || + hasBearishPattern || + hasBearishPressure) + // + ) // ; @@ -2504,16 +2652,16 @@ class X121SCTradeHandler : public XSCBaseAlert // // Do In Profit Protection Mechanism ... - // - // - [] Partial Close; - // - [] Specified Point of Profits; - // // Trail Stops ... // Remove Trailed Positions TP ... bool allowTrailStop = AllowTrailStopInProfits(); double trailStep = TrailStopStepsInPoint(); - if (allowTrailStop && trailStep > 0) + bool allowOnlyUnprotecteds = OnlyTrailUnprotectedPositions(); + bool isProtectionTrailPassed = !allowOnlyUnprotecteds + ? true + : supportsCount == 0; + if (allowTrailStop && trailStep > 0 && isProtectionTrailPassed) { // // Temp Vaiables ... @@ -2524,17 +2672,15 @@ class X121SCTradeHandler : public XSCBaseAlert { // // Check Conditions ... - canTrailStop = isTicksBullish && - (hasBullishDecision || - hasBullishConditions); + canTrailStop = isTicksBullishForLong && + hasBullishConditions; } else { // // Check Conditions ... - canTrailStop = isTicksBearish && - (hasBearishDecision || - hasBearishConditions); + canTrailStop = isTicksBearishForShort && + hasBearishConditions; } // @@ -2553,7 +2699,7 @@ class X121SCTradeHandler : public XSCBaseAlert double requiredProfit = lastTrailedStep == 0 ? ProtectorStartDistanceInPoint() - : lastTrailedStep * trailStep; + : ProtectorStartDistanceInPoint() + (lastTrailedStep * trailStep); // bool isProfitsPassed = profitInPoint > requiredProfit; @@ -2621,18 +2767,12 @@ class X121SCTradeHandler : public XSCBaseAlert } } } - - // - if (result) - { - return result; - } } // // Check Points of Profit and Do Partial Closing ... - double partialCloseVolume = PartialCloseVolume(); - double partialCloseProfitPoint = PartialCloseOnSpecificPoint(); + double partialCloseVolume = PartialCloseVolumeInProfit(); + double partialCloseProfitPoint = PartialCloseOnSpecificPointOfProfit(); if (partialCloseVolume > 0 && partialCloseProfitPoint > 0) { // @@ -2671,11 +2811,193 @@ class X121SCTradeHandler : public XSCBaseAlert else { // - if (isLong) + bool allowRecover = AllowRecoverInDrawdowns(); + double volumeMultiplier = RecoveryMultiplier(); + if (allowRecover && volumeMultiplier > 0) { + // + bool canRecover = false; + + // + // Temparory Requirement for Recover Signal ... + double sl = 0; + double tp = 0; + double entry = 0; + ENUM_POSITION_TYPE type = NULL; + ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; + double lastStep = mData[iDX].protectionStep; + double volume = lastStep <= 0 + ? position.volume * volumeMultiplier + : position.volume * ((lastStep + 1) * volumeMultiplier); + + // + // Long Recovery ... + if (isLong) + { + // + // Opposit Direction ... + canRecover = + // + isTicksBearishForShort && + hasBearishConditions + // + ; + if (canRecover) + { + // + sl = position.entry; + tp = position.sl; + type = POSITION_TYPE_SELL; + } + + // + // Same Direction ... + if (!canRecover) + { + // + canRecover = + // + isTicksBullishForLong && + hasBullishConditions + // + ; + if (canRecover) + { + // + sl = position.sl; + tp = position.entry; + type = POSITION_TYPE_BUY; + } + } + } + // + // Short Recovery ... + else + { + // + // Opposit Direction ... + canRecover = + // + isTicksBullishForLong && + hasBullishConditions + // + ; + if (canRecover) + { + // + sl = position.entry; + tp = position.sl; + type = POSITION_TYPE_BUY; + } + + // + // Same Direction ... + if (!canRecover) + { + // + canRecover = + // + isTicksBearishForShort && + hasBearishConditions + // + ; + if (canRecover) + { + // + sl = position.sl; + tp = position.entry; + type = POSITION_TYPE_SELL; + } + } + } + + // + if (canRecover) + { + // + XSignal signal; + entry = GetEntry( + position.symbol, + type // + ); + + // + // Prepare Signal ... + result = signal.Prepare( + position.symbol, + position.provider, + position.period, + type, + mode, + entry, + volume, + sl, + tp // + ); + + // + if (result) + { + // + // Generate Comment for Recover and Support ... + string comment = GenerateSupportTag(position.ticket); + + // + signal.comment = comment; + + // + ENUM_X_SIGNAL_EXECUTION_RESULT state; + result = ExecuteSignal( + signal, + state, + true // Support Signal need to Ignore Policies ... + ); + if (result) + { + // + mData[iDX].protectionStep++; + mData[iDX].lastProtectedVolume = volume; + + // + string message = "EQM Open " + (IsLong(type) ? "Long" : "Short") + " Recovery Position in Level: " + + ToString(lastStep + 1) + + " for (" + ToString(position.ticket) + ")"; + Alert(message); + } + } + } } - else + + // + // Check Points of Drawdown and Do Partial Closing ... + double partialCloseVolume = PartialCloseVolumeInDrawdown(); + double partialCloseDrawdownPoint = PartialCloseOnSpecificPointOfDrawdown(); + if (partialCloseVolume > 0 && partialCloseDrawdownPoint > 0) { + // + double profitPoints = position.GetProfitInPoint(); + if (profitPoints < 0 && MathAbs(profitPoints) >= partialCloseDrawdownPoint && !mData[iDX].partiallyClosed) + { + // + string comment = "EQM Partial Close ..."; + + // + // Do Partial Closing ... + result = mTrader.ClosePartial( + position.ticket, + partialCloseVolume, + comment // + ); + if (result) + { + // + mData[iDX].partiallyClosed = true; + + // + string message = "EQM Partially Closed " + ToString(partialCloseVolume) + " of (" + ToString(position.ticket) + ")"; + Alert(message); + } + } } } @@ -2715,11 +3037,19 @@ class X121SCTradeHandler : public XSCBaseAlert // // In Profit Positions Protecting ... - bool mAllowTrailStopInProfits; // Allow Trail Stops for In Profit Positions - double mTrailStopStepsInPoint; // Trail Stop Steps in Point - int mRmoveTPOnTrailStep; // Remove Position TP if Trailed specific times - double mPartialCloseOnSpecificPoint; // Partial Close Position on Specific Points of Profit - double mPartialCloseVolume; // Partial Close Volume + bool mAllowTrailStopInProfits; // Allow Trail Stops for In Profit Positions + bool mOnlyTrailUnprotectedPositions; // Only Trail UnProtected Positions + double mTrailStopStepsInPoint; // Trail Stop Steps in Point + int mRmoveTPOnTrailStep; // Remove Position TP if Trailed specific times + double mPartialCloseOnSpecificPointOfProfit; // Partial Close Position on Specific Points of Profit + double mPartialCloseVolumeInProfit; // Partial Close Volume + + // + // In Drawdown Positions Protecting ... + bool mAllowRecoverInDrawdowns; // Allow Recovery For In Drawdown Positions + double mRecoveryMultiplier; // Recovery Volume Multiplier + double mPartialCloseOnSpecificPointOfDrawdown; // Partial Close Position on Specific Points of Drawdown + double mPartialCloseVolumeInDrawdown; // Partial Close Volume // // Hedging Properties ... diff --git a/Experts/x-saherelm.x121.ea.mq5 b/Experts/x-saherelm.x121.ea.mq5 index fbe6dbc2..88f3a475 100644 --- a/Experts/x-saherelm.x121.ea.mq5 +++ b/Experts/x-saherelm.x121.ea.mq5 @@ -90,12 +90,31 @@ input double eaProtectorStartDistanceInPoint = 35; // Protector Start Distance i // // Protector > Hedging Properties ... +input group "Hedging"; input bool eaAllowHedge = false; // Allow Protector to Hedge Positions input double eaHedgeMinVolumeStep = 0.01; // Minimum Volume Step For Hedge input int eaMinimumOpenPositionsForHEHedge = 2; // Minimum Open Positions For HE Hedge input double eaHedgeHEMinProfitPerVolumeStep = 0.2; // Minimum Required Profit For HE Hedge Per Volume Step input double eaHedgeBEMinProfitPerVolumeStep = 0.05; // Minimum Required Profit For BE Hedge Per Volume Step +// +// Protector > In Profit Positions Protecting ... +input group "In Profit Positions Protecting"; +input bool eaAllowTrailStopInProfits = true; // Allow Trail Stops for In Profit Positions +input bool eaOnlyTrailUnprotectedPositions = true; // Only Trail UnProtected Positions +input double eaTrailStopStepsInPoint = 10; // Trail Stop Steps in Point +input int eaRmoveTPOnTrailStep = 0; // Remove Position TP if Trailed specific times +input double eaPartialCloseOnSpecificPointOfProfit = 0; // Partial Close Position on Specific Points of Profit +input double eaPartialCloseVolumeInProfit = 0; // Partial Close Volume + +// +// Protector > In Drawdown Positions Protecting ... +input group "In Drawdown Positions Protecting"; +input bool eaAllowRecoverInDrawdowns = true; // Allow Recovery For In Drawdown Positions +input double eaRecoveryMultiplier = 2; // Recovery Volume Multiplier +input double eaPartialCloseOnSpecificPointOfDrawdown = 0; // Partial Close Position on Specific Points of Drawdown +input double eaPartialCloseVolumeInDrawdown = 0; // Partial Close Volume + // // Alert ... input group "Alert"; @@ -465,6 +484,23 @@ bool InitialEA() eaTradeHandler.HedgeMinVolumeStep(eaHedgeMinVolumeStep); eaTradeHandler.MinimumOpenPositionsForHEHedge(eaMinimumOpenPositionsForHEHedge); eaTradeHandler.HedgeHEMinProfitPerVolumeStep(eaHedgeHEMinProfitPerVolumeStep); + eaTradeHandler.HedgeBEMinProfitPerVolumeStep(eaHedgeBEMinProfitPerVolumeStep); + + // + // In Profit Position Protecting ... + eaTradeHandler.AllowTrailStopInProfits(eaAllowTrailStopInProfits); + eaTradeHandler.OnlyTrailUnprotectedPositions(eaOnlyTrailUnprotectedPositions); + eaTradeHandler.TrailStopStepsInPoint(eaTrailStopStepsInPoint); + eaTradeHandler.RmoveTPOnTrailStep(eaRmoveTPOnTrailStep); + eaTradeHandler.PartialCloseOnSpecificPointOfProfit(eaPartialCloseOnSpecificPointOfProfit); + eaTradeHandler.PartialCloseVolumeInProfit(eaPartialCloseVolumeInProfit); + + // + // Protector > In Drawdown Positions Protecting ... + eaTradeHandler.AllowRecoverInDrawdowns(eaAllowRecoverInDrawdowns); + eaTradeHandler.RecoveryMultiplier(eaRecoveryMultiplier); + eaTradeHandler.PartialCloseOnSpecificPointOfDrawdown(eaPartialCloseOnSpecificPointOfDrawdown); + eaTradeHandler.PartialCloseVolumeInDrawdown(eaPartialCloseVolumeInDrawdown); // // TODO: Implement ... diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 5366c15f..170576c7 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -5187,7 +5187,10 @@ struct XLinearRegressionWorkStruct // // Constructor ... - XLinearRegressionWorkStruct() : dataSize(-1), period(-1) {} + XLinearRegressionWorkStruct() + : dataSize(-1), period(-1) + { + } }; // @@ -7257,7 +7260,9 @@ bool CalculateTPSLByPrice( return result; } -// +/** + * Retrieve Current Tick ... + */ bool GetTick( string mSymbol, MqlTick &tick // @@ -7266,6 +7271,140 @@ bool GetTick( return SymbolInfoTick(mSymbol, tick); } +/** + * Retrieve Tick Entry ... + */ +double GetTickEnty( + MqlTick &mTick, + ENUM_POSITION_TYPE type, + string mSymbol = NULL // +) +{ + // + double result = 0; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + result = + IsLong(type) + ? mTick.ask + : mTick.bid; + result = NormalizePrice(result, mSymbol); + + // + return result; +} + +/** + * Retrieve Tick Exit ... + */ +double GetTickExit( + MqlTick &mTick, + ENUM_POSITION_TYPE type, + string mSymbol = NULL // +) +{ + // + double result = 0; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + result = + IsLong(type) + ? mTick.bid + : mTick.ask; + result = NormalizePrice(result, mSymbol); + + // + return result; +} + +/** + * Calculate Momentum Changes based on Given Price + */ +double CalculateMomentum( + double currentPrice, + double previousPrice // +) +{ + // + double result = 0; + + // + return result; +} + +/** + * Detect Possible Momentum Changes + * Using MqlTick ... + */ +bool DetectMomentumChange( + ENUM_POSITION_TYPE type, + string mSymbol = NULL, + int mLength = 14 // +) +{ + // + bool result = false; + + // + mSymbol = NormalizeSymbol(mSymbol); + + // + MqlTick ticks[]; + int copied = CopyTicks( + mSymbol, + ticks, + COPY_TICKS_ALL, + 0, + mLength + 1 // + ); + + // + result = copied > mLength; + if (!result) + { + return result; + } + + // + double previousPrice = GetTickExit( + ticks[mLength], + type, + mSymbol // + ); + for (int i = mLength - 1; i >= 0; i--) + { + // + double currentPrice = GetTickExit( + ticks[i], + type, + mSymbol // + ); + + // + double momentum = CalculateMomentum( + currentPrice, + previousPrice // + ); + + // + if (fabs(momentum) > 1.0) + { + // + result = true; + break; + } + } + + // + return result; +} + // // Symbols ... @@ -8261,8 +8400,7 @@ double MAOnArray( { // // Mode SMA ... - case MODE_SMA: - { + case MODE_SMA: { // total = ArrayCopy(arr, array, 0, shift + ma_shift, period); if (ArrayResize(buf, total) < 0) @@ -8295,8 +8433,7 @@ double MAOnArray( // // Mode EMA ... - case MODE_EMA: - { + case MODE_EMA: { // if (ArrayResize(buf, total) < 0) { @@ -8328,8 +8465,7 @@ double MAOnArray( // // Mode SMMA ... - case MODE_SMMA: - { + case MODE_SMMA: { // if (ArrayResize(buf, total) < 0) { @@ -8372,8 +8508,7 @@ double MAOnArray( // // Mode LWMA ... - case MODE_LWMA: - { + case MODE_LWMA: { // if (ArrayResize(buf, total) < 0) { diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index ff2289f6..5985c04a 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -579,10 +579,13 @@ struct XPosition } // - double point = GetPoints(symbol); + double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); // Tick size + double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); // Tick value + double pointSize = SymbolInfoDouble(symbol, SYMBOL_POINT); // Point size + double pointValue = tickValue * pointSize / tickSize; // Point value // - result = profit * point; + result = profit / (volume * tickValue); // return result; diff --git a/Strategies/x-saherelm.xch.che.strategy.mq5 b/Strategies/x-saherelm.xch.che.strategy.mq5 index 13354665..f1b390f6 100644 --- a/Strategies/x-saherelm.xch.che.strategy.mq5 +++ b/Strategies/x-saherelm.xch.che.strategy.mq5 @@ -884,11 +884,11 @@ private: chhkInputs.ignoreShadows = true; // - chhkInputs.showCurrent = true; - chhkInputs.showShort = true; - chhkInputs.showMedium = true; - chhkInputs.showLong = true; - chhkInputs.showHind = true; + chhkInputs.showCurrent = false; + chhkInputs.showShort = false; + chhkInputs.showMedium = false; + chhkInputs.showLong = false; + chhkInputs.showHind = false; // chhkHelper = new XSCXCHHKHelper(); diff --git a/Strategies/x-saherelm.xch.strategy.mq5 b/Strategies/x-saherelm.xch.strategy.mq5 index b5acb34e..71bd18bb 100644 --- a/Strategies/x-saherelm.xch.strategy.mq5 +++ b/Strategies/x-saherelm.xch.strategy.mq5 @@ -1700,11 +1700,11 @@ private: chvlmInputs.hcPeriod = hcPeriod; // - chvlmInputs.showCurrent = true; - chvlmInputs.showShort = true; - chvlmInputs.showMedium = true; - chvlmInputs.showLong = true; - chvlmInputs.showHind = true; + chvlmInputs.showCurrent = false; + chvlmInputs.showShort = false; + chvlmInputs.showMedium = false; + chvlmInputs.showLong = false; + chvlmInputs.showHind = false; // chvlmHelper = new XSCXCHVLMHelper();