From 8eab3ef9b6551233cabad6fa650a666d73024695 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sun, 16 Jun 2024 11:11:33 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x121.setup.cycle.class.mq5 | 12 - Classes/x-saherelm.x121.setup.xea.mq5 | 882 ++++++++++++++++-- Classes/x-saherelm.xczone.class.mq5 | 14 + Classes/x-saherelm.xea.class.mq5 | 2 +- Classes/x-saherelm.xtrade.class.mq5 | 528 +++++------ Documents/BKP/usefull.mq5 | 335 +++++++ Experts/x-saherelm.x121.ea.mq5 | 12 +- Libraries/x-saherelm.xtrade.lib.mq5 | 11 +- 8 files changed, 1398 insertions(+), 398 deletions(-) diff --git a/Classes/x-saherelm.x121.setup.cycle.class.mq5 b/Classes/x-saherelm.x121.setup.cycle.class.mq5 index d9bde2d1..3eab1737 100644 --- a/Classes/x-saherelm.x121.setup.cycle.class.mq5 +++ b/Classes/x-saherelm.x121.setup.cycle.class.mq5 @@ -524,18 +524,6 @@ public: // XSCZonesInput zInputs; zInputs.numberOfZones = numberOfZones; - zInputs.AddLevelColor( - 0.15, - clrYellow // - ); - zInputs.AddLevelColor( - 0.20, - clrOrange // - ); - zInputs.AddLevelColor( - 0.25, - clrRed // - ); // int length = 0; diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index 9a95918e..1ddc9c2f 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -1042,6 +1042,21 @@ public: mSave = value; } + // + // Support ... + + // + bool AllowSupport() + { + return mAllowSupport; + } + + // + void AllowSupport(bool value) + { + mAllowSupport = value; + } + // // Trailling Stop ... @@ -1625,6 +1640,15 @@ public: continue; } + // + // Only Trail Positions which they Hasnt any Support ... + bool hasSupport = mTrader.HasSupport(iPosition.ticket); + result = !hasSupport; + if (!result) + { + return result; + } + // // Find Positin Info Index ... int idx = FindIndex(iPosition.ticket); @@ -1715,6 +1739,686 @@ public: return result; } + // + int RequestForSupport( + XSignal &signals[], + XSCX121SetupCycles *&setups[] // Number of Setups + ) + { + // + int result = 0; + + // + Clean(signals); + + // + double supportDistance = 50; + + // + if (!AllowSupport()) + { + return result; + } + + // + // Validate Setups Count ... + int setupsCount = ArraySize(setups); + if (!IsValidSize(setupsCount)) + { + return result; + } + + // + // Implement Supporting Mechanism ... + + // + // Extracting In Drawdown Positions ... + XPosition positions[]; + int positionsCount = mTrader.GetInDrawdownPositions( + positions // + ); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + X121SignalGenerator signalGenerator; + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // Check Position is not Support Position ... + bool isSupport = IsSupport(iPosition.comment); + if (isSupport) + { + continue; + } + + // + // Find Related Setp ... + int idx = FindSetupIndex( + iPosition.symbol, + setups // + ); + if (!IsValidIndex(idx)) + { + continue; + } + + // + // Check Position must atleast 20 Point in drawdown ... + + // + double onePointPrice = PointToPrice( + 1, + iPosition.symbol // + ); + + // + double iExitPrice = GetExit( + iPosition.symbol, + iPosition.type // + ); + + // + double priceDiff = MathAbs(iPosition.entry - iExitPrice); + double priceDiffPoints = priceDiff / onePointPrice; + + // + bool isFarEnough = priceDiffPoints >= supportDistance; + if (!isFarEnough) + { + continue; + } + + // + // Now Check Position SUpports ... + XPosition iSupports[]; + int iSupportsCount = mTrader.GetSupports( + iPosition.ticket, + iSupports // + ); + bool isFirst = !IsValidSize(iSupportsCount); + bool canSupport = isFirst; // || iSupportsCount < 3; + if (!canSupport) + { + continue; + } + + // + // Now Check Signals For not Exists ... + int signalsCount = ArraySize(signals); + if (IsValidSize(signalsCount)) + { + // + bool isInserted = false; + for (int j = 0; j < signalsCount; j++) + { + // + isInserted = signals[j].positionId == iPosition.ticket; + if (isInserted) + { + break; + } + } + + // + if (isInserted) + { + continue; + } + } + + // + // First Try to Get Market State ... + + // + double bullishScore = 0; + double bearishScore = 0; + double tmpBullishScore = 0; + double tmpBearishScore = 0; + + // + // Max Verifications is 11 ... + int reqValidation = 6; + int longVerifications = 0; + int shortVerifications = 0; + + // + // Pushers ... + int longPushers = 0; + int shortPushers = 0; + int tmpLongPushers = 0; + int tmpShortPushers = 0; + + // + string tmpProvider; + string longProviders[]; + string shortProviders[]; + + // + double volumeOSC = 0; + + // + // Current ... + X121SetupConditions cConditions; + bool cHasConditions = setups[idx].GetConditions( + cConditions, + X_MARKET_CYCLE_UNKNOWN // + ); + if (!cHasConditions) + { + continue; + } + bool isCValidForLong = signalGenerator.IsConditionsValidForLong( + cConditions, + reqValidation // + ); + if (isCValidForLong) + { + longVerifications += reqValidation; + } + bool isCValidForShort = signalGenerator.IsConditionsValidForShort( + cConditions, + reqValidation // + ); + if (isCValidForShort) + { + shortVerifications += reqValidation; + } + bool cHasLongConditions = signalGenerator.HasLongConditions( + cConditions, + tmpLongPushers, + tmpProvider // + ); + if (cHasLongConditions) + { + // + AddSpecific( + tmpProvider, + longProviders // + ); + + // + longPushers += tmpLongPushers; + } + bool cHasShortConditions = signalGenerator.HasShortConditions( + cConditions, + tmpShortPushers, + tmpProvider // + ); + if (cHasShortConditions) + { + // + AddSpecific( + tmpProvider, + shortProviders // + ); + + // + shortPushers += tmpShortPushers; + } + volumeOSC += cConditions.vlmConditions.volume[1]; + cConditions.GenerateScore( + tmpBullishScore, + tmpBearishScore // + ); + bullishScore += tmpBullishScore; + bearishScore += tmpBearishScore; + + // + // Short ... + X121SetupConditions sConditions; + bool sHasConditions = setups[idx].GetConditions( + sConditions, + X_MARKET_CYCLE_SHORT // + ); + if (!sHasConditions) + { + continue; + } + bool isSValidForLong = signalGenerator.IsConditionsValidForLong( + sConditions, + reqValidation // + ); + if (isSValidForLong) + { + longVerifications += reqValidation; + } + bool isSValidForShort = signalGenerator.IsConditionsValidForShort( + sConditions, + reqValidation // + ); + if (isSValidForShort) + { + shortVerifications += reqValidation; + } + bool sHasLongConditions = signalGenerator.HasLongConditions( + sConditions, + tmpLongPushers, + tmpProvider // + ); + if (sHasLongConditions) + { + // + AddSpecific( + tmpProvider, + longProviders // + ); + + // + longPushers += tmpLongPushers; + } + bool sHasShortConditions = signalGenerator.HasShortConditions( + sConditions, + tmpShortPushers, + tmpProvider // + ); + if (sHasShortConditions) + { + // + AddSpecific( + tmpProvider, + shortProviders // + ); + + // + shortPushers += tmpShortPushers; + } + volumeOSC += sConditions.vlmConditions.volume[1]; + sConditions.GenerateScore( + tmpBullishScore, + tmpBearishScore // + ); + bullishScore += tmpBullishScore; + bearishScore += tmpBearishScore; + + // + // Medium ... + X121SetupConditions mConditions; + bool mHasConditions = setups[idx].GetConditions( + mConditions, + X_MARKET_CYCLE_MEDIUM // + ); + if (!mHasConditions) + { + continue; + } + XSCZones *mZones = setups[idx].GetZones( + X_MARKET_CYCLE_MEDIUM // + ); + bool isMValidForLong = signalGenerator.IsConditionsValidForLong( + mConditions, + reqValidation // + ); + if (isMValidForLong) + { + longVerifications += reqValidation; + } + bool isMValidForShort = signalGenerator.IsConditionsValidForShort( + mConditions, + reqValidation // + ); + if (isMValidForShort) + { + shortVerifications += reqValidation; + } + bool mHasLongConditions = signalGenerator.HasLongConditions( + mConditions, + tmpLongPushers, + tmpProvider // + ); + if (mHasLongConditions) + { + // + AddSpecific( + tmpProvider, + longProviders // + ); + + // + longPushers += tmpLongPushers; + } + bool mHasShortConditions = signalGenerator.HasShortConditions( + mConditions, + tmpShortPushers, + tmpProvider // + ); + if (mHasShortConditions) + { + // + AddSpecific( + tmpProvider, + shortProviders // + ); + + // + shortPushers += tmpShortPushers; + } + volumeOSC += mConditions.vlmConditions.volume[1]; + mConditions.GenerateScore( + tmpBullishScore, + tmpBearishScore // + ); + bullishScore += tmpBullishScore; + bearishScore += tmpBearishScore; + + // + // Long ... + X121SetupConditions lConditions; + bool lHasConditions = setups[idx].GetConditions( + lConditions, + X_MARKET_CYCLE_LONG // + ); + if (!lHasConditions) + { + continue; + } + XSCZones *lZones = setups[idx].GetZones( + X_MARKET_CYCLE_LONG // + ); + bool isLValidForLong = signalGenerator.IsConditionsValidForLong( + lConditions, + reqValidation // + ); + if (isLValidForLong) + { + longVerifications += reqValidation; + } + bool isLValidForShort = signalGenerator.IsConditionsValidForShort( + lConditions, + reqValidation // + ); + if (isLValidForShort) + { + shortVerifications += reqValidation; + } + bool lHasLongConditions = signalGenerator.HasLongConditions( + lConditions, + tmpLongPushers, + tmpProvider // + ); + if (lHasLongConditions) + { + // + AddSpecific( + tmpProvider, + longProviders // + ); + + // + longPushers += tmpLongPushers; + } + bool lHasShortConditions = signalGenerator.HasShortConditions( + lConditions, + tmpShortPushers, + tmpProvider // + ); + if (lHasShortConditions) + { + // + AddSpecific( + tmpProvider, + shortProviders // + ); + + // + shortPushers += tmpShortPushers; + } + volumeOSC += lConditions.vlmConditions.volume[1]; + lConditions.GenerateScore( + tmpBullishScore, + tmpBearishScore // + ); + bullishScore += tmpBullishScore; + bearishScore += tmpBearishScore; + + // + // Hind ... + X121SetupConditions hConditions; + bool hHasConditions = setups[idx].GetConditions( + hConditions, + X_MARKET_CYCLE_HIND // + ); + if (!hHasConditions) + { + continue; + } + XSCZones *hZones = setups[idx].GetZones( + X_MARKET_CYCLE_HIND // + ); + bool isHValidForLong = signalGenerator.IsConditionsValidForLong( + hConditions, + reqValidation // + ); + if (isHValidForLong) + { + longVerifications += reqValidation; + } + bool isHValidForShort = signalGenerator.IsConditionsValidForShort( + hConditions, + reqValidation // + ); + if (isHValidForShort) + { + shortVerifications += reqValidation; + } + bool hHasLongConditions = signalGenerator.HasLongConditions( + hConditions, + tmpLongPushers, + tmpProvider // + ); + if (hHasLongConditions) + { + // + AddSpecific( + tmpProvider, + longProviders // + ); + + // + longPushers += tmpLongPushers; + } + bool hHasShortConditions = signalGenerator.HasShortConditions( + hConditions, + tmpShortPushers, + tmpProvider // + ); + if (hHasShortConditions) + { + // + AddSpecific( + tmpProvider, + shortProviders // + ); + + // + shortPushers += tmpShortPushers; + } + volumeOSC += hConditions.vlmConditions.volume[1]; + hConditions.GenerateScore( + tmpBullishScore, + tmpBearishScore // + ); + bullishScore += tmpBullishScore; + bearishScore += tmpBearishScore; + + // + // Now We Have all required Data to Decide What Supports for + // Specified In DrawDown Position ... + + // + XSignal tmpSignal; + tmpSignal.Clean(); + + // + double longEntry = GetEntry( + iPosition.symbol, + POSITION_TYPE_BUY // + ); + double shortEntry = GetEntry( + iPosition.symbol, + POSITION_TYPE_SELL // + ); + double mVolume = iPosition.volume * 2; + double mSL = 0; + double mTP = 0; + + // + bool isLong = IsLong(iPosition.type); + + // + // Long Support ... + bool canLongSupport = + // + volumeOSC > 5 && + bullishScore > bearishScore && + ArraySize(longProviders) >= 2 && + bearishScore < bullishScore / 3.5 && + longVerifications > reqValidation * 3 + // + ; + if (canLongSupport) + { + // + bool isPrepared = tmpSignal.Prepare( + iPosition.symbol, + iPosition.provider, + iPosition.period, + POSITION_TYPE_BUY, + X_ORDER_MODE_MARKET, + longEntry, + mVolume // + ); + + // + if (isPrepared) + { + // + tmpSignal.positionId = iPosition.ticket; + string comment = GenerateSupportTag(iPosition.ticket); + tmpSignal.comment = comment; + + // + AddRef( + tmpSignal, + signals // + ); + + // + tmpSignal.Clean(); + } + } + + // + // Short Support ... + bool canShortSupport = + // + volumeOSC < -5 && + bearishScore > bullishScore && + ArraySize(shortProviders) >= 2 && + bullishScore < bearishScore / 3.5 && + shortVerifications > reqValidation * 3 + // + ; + if (canShortSupport) + { + // + bool isPrepared = tmpSignal.Prepare( + iPosition.symbol, + iPosition.provider, + iPosition.period, + POSITION_TYPE_SELL, + X_ORDER_MODE_MARKET, + shortEntry, + mVolume // + ); + + // + if (isPrepared) + { + // + tmpSignal.positionId = iPosition.ticket; + string comment = GenerateSupportTag(iPosition.ticket); + tmpSignal.comment = comment; + + // + AddRef( + tmpSignal, + signals // + ); + + // + tmpSignal.Clean(); + } + } + + // + // If no Support Presents ... + if (!canLongSupport && !canShortSupport) + { + // + // RemoveDraws("MED"); + // RemoveDraws("LON"); + // RemoveDraws("HND"); + AddHotLevelsToZones(mZones); + AddHotLevelsToZones(lZones); + AddHotLevelsToZones(hZones); + + // + // bool isDrawn = mZones.DrawZones(0, "MED"); + // if (isDrawn) + // { + // // + // isDrawn = false; + // RemoveDraws("MED"); + // } + + // // + // isDrawn = lZones.DrawZones(0, "LON"); + // if (isDrawn) + // { + // // + // isDrawn = false; + // RemoveDraws("LON"); + // } + + // // + // isDrawn = hZones.DrawZones(0, "HND"); + // if (isDrawn) + // { + // // + // isDrawn = false; + // RemoveDraws("HND"); + // } + + // // + // isDrawn = mZones.DrawZones(0, "MED"); + // isDrawn = lZones.DrawZones(0, "LON"); + // isDrawn = hZones.DrawZones(0, "HND"); + // if (isDrawn) + // { + // // + // isDrawn = false; + // // RemoveDraws("MED"); + // // RemoveDraws("LON"); + // // RemoveDraws("HND"); + // } + } + } + + // + result = ArraySize(signals); + + // + return result; + } + // int RequestForGrid(XSignal &signals[]) { @@ -1817,51 +2521,6 @@ public: return result; } - // - int RequestForProtect(XSignal &signals[]) - { - // - // Grid ... - XSignal grids[]; - int gridsCount = RequestForGrid(grids); - - // - // Recovery ... - XSignal recoveries[]; - int recoveriesCount = RequestForRecovery(recoveries); - - // - Clean(signals); - - // - if (IsValidSize(gridsCount)) - { - // - Copy( - grids, - signals, - false // - ); - } - - // - if (IsValidSize(recoveriesCount)) - { - // - Copy( - recoveries, - signals, - false // - ); - } - - // - int result = ArraySize(signals); - - // - return result; - } - // // Sync ... void Sync() @@ -1949,9 +2608,13 @@ protected: } } + // + // Supports ... + bool mAllowSupport; // Allow Support Signals + // // Stop Trailling ... - bool mAllowTrailStop; // Enable Trailling Stop Losses + bool mAllowTrailStop; // Enable Trailling Stop Losses double mFirstTrailDistance; // Start Trailling Distance double mFirstTrailPoint; // First Stop Trail double mNextTrailDistance; // Next Trailling Distance @@ -1968,6 +2631,57 @@ protected: bool mAllowRecovery; // Use Recovery System to Recovery Positions double mRecoveryDistance; // Recovery System Distance double mRecoveryVolumeMultiplier; // Recovery System Volume Multiplier + + // + int FindSetupIndex( + string symbol, + XSCX121SetupCycles *&setups[] // + ) + { + // + int result = 0; + + // + if (!IsValid(symbol)) + { + return result; + } + + // + for (int i = 0; i < ArraySize(setups); i++) + { + // + if (setups[i].GetSymbol() == symbol) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + void AddHotLevelsToZones( + XSCZones *zones // + ) + { + // + zones.AddLevelColor( + 0.25, + clrRed // + ); + zones.AddLevelColor( + 0.20, + clrOrange // + ); + zones.AddLevelColor( + 0.15, + clrYellow // + ); + } }; // @@ -2249,15 +2963,18 @@ public: } // - bool UseSupport() + // Support ... + + // + bool AllowSupport() { - return mUseSupport; + return mTradeInfoHandler.AllowSupport(); } // - void UseSupport(bool value) + void AllowSupport(bool value) { - mUseSupport = value; + mTradeInfoHandler.AllowSupport(value); } // @@ -3465,7 +4182,7 @@ private: // bool EnableProtection() { - return EnableGrid() || EnableRecovery() || EnableTrailling(); + return EnableGrid() || EnableRecovery() || EnableTrailling() || AllowSupport(); } // @@ -3708,7 +4425,7 @@ private: } // - // Handle Trailling ... + // Trailling ... if (EnableTrailling()) { // @@ -3724,14 +4441,63 @@ private: } // - XSignal signals[]; - int signalsCount = mTradeInfoHandler - .RequestForProtect(signals); - if (!IsValidSize(signalsCount)) + // Support ... + if (AllowSupport()) + { + // + XSignal supports[]; + int supportsCount = mTradeInfoHandler.RequestForSupport( + supports, + mSetups // + ); + if (IsValidSize(supportsCount)) + { + EQMExecuteSignals(supports); + } + } + + // + // Grid ... + if (EnableGrid()) + { + // + XSignal signals[]; + int signalsCount = mTradeInfoHandler + .RequestForGrid(signals); + if (IsValidSize(signalsCount)) + { + EQMExecuteSignals(signals); + } + } + + // + // Recovery ... + if (EnableRecovery()) + { + // + XSignal signals[]; + int signalsCount = mTradeInfoHandler + .RequestForRecovery(signals); + if (IsValidSize(signalsCount)) + { + EQMExecuteSignals(signals); + } + } + } + + // + void EQMExecuteSignals( + XSignal &signals[] // + ) + { + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signals)) { return; } + // // // Execute Supports ... ENUM_X_SIGNAL_EXECUTION_RESULT states[]; @@ -3742,7 +4508,9 @@ private: ); if (executed != signalsCount) { - Print("Error On Executing Support Signal ..."); + // + // TODO: Dow What We Want ... + // Print("Error On Executing Support Signal ..."); } } diff --git a/Classes/x-saherelm.xczone.class.mq5 b/Classes/x-saherelm.xczone.class.mq5 index 4b710f00..ade1cd0c 100644 --- a/Classes/x-saherelm.xczone.class.mq5 +++ b/Classes/x-saherelm.xczone.class.mq5 @@ -286,6 +286,20 @@ public: return Init(inputs); } + // + // Add Specified Level/Color ... + void AddLevelColor( + double level, + color clr // + ) + { + // + mInputs.AddLevelColor( + level, + clr // + ); + } + // void Calculate() { diff --git a/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index af9b9b8a..5ad4412a 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -1093,7 +1093,7 @@ protected: // // Check At Least One Support Positions Open For Hedging ... XPosition supports[]; - int supportsCount = ExtractSupportPositions( + int supportsCount = ExtractSupports( positions, supports // ); diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index 55809295..a6dd344d 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -2919,332 +2919,257 @@ public: } // - // XPosition Pack ... + // Support Functions ... // - // Extract specific Positions Pack ... - // in this senario there is no need to Position exists itself ... - bool GetPositionPack( - ulong ticket, // Specified Positions Ticket - string symbol, // Specified Position Symbol - ENUM_TIMEFRAMES period, // Specified Position Period - XPositionPack &pack // Hold Result + // Check a Position has Support or not ... + bool HasSupport( + ulong ticket, + bool forceOpen = true // ) { // bool result = false; // - pack.Clean(); - - // - XPosition position; - bool hasPosition = GetPosition( - ticket, - position - // - ); - if (hasPosition) - { - pack.position = position; - } - - // - XOrder supportOrders[]; - XPosition supportPositions[]; - - // - XOrder orders[]; - GetOrders( - orders, - symbol, // Specified Symbol - NULL, // All Providers - period, // Specified Period - NULL, // All Types - ORDER_STATE_PLACED, // Just UnTriggered Orders - true // Filter by Magic - ); - int ordersCount = ArraySize(orders); - - // - // Select Orders ... - if (ordersCount > 0) - { - // - for (int i = 0; i < ordersCount; i++) - { - // - XOrder iOrder = orders[i]; - - // - // Retrieve Order Supported Ticket ... - ulong parentTicket = ExtractSupportedTicket(iOrder.comment); - if (NotEmpty(parentTicket) && parentTicket == ticket) - { - // - AddRef( - iOrder, - supportOrders - // - ); - } - } - } - - // - int supportOrdersCount = ArraySize(supportOrders); - if (supportOrdersCount > 0) - { - // - pack.supportOrdersCount = supportOrdersCount; - - // - Copy( - supportOrders, - pack.supportOrders); - } - - // - XPosition positions[]; - GetPositions( - positions, - symbol, // Specified Symbol ... - NULL, // All Providers ... - period // Specified Period ... - ); - int positionsCount = ArraySize(positions); - - // - // Select Positions ... - if (positionsCount > 0) - { - // - for (int i = 0; i < positionsCount; i++) - { - // - XPosition iPosition = positions[i]; - - // - ulong parentTicket = ExtractSupportedTicket(iPosition.comment); - if (NotEmpty(parentTicket) && parentTicket == ticket) - { - // - AddRef( - iPosition, - supportPositions - // - ); - } - } - } - - // - int supportPositionsCount = ArraySize(supportPositions); - if (supportPositionsCount > 0) - { - // - pack.supportPositionsCount = supportPositionsCount; - - // - Copy( - supportPositions, - pack.supportPositions); - } - - // - result = pack.IsValid(); - - // - return result; - } - - // - // Close Position Pack ... - bool ClosePositionPack( - XPositionPack &pack, // Specified Position Pack - string comment, // Specified Close Comment - bool inProfit = false, // if it's true only close Pack if in profit - double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... - double minProfitPerVolumeFactor = 0 // Min Volume Factor ... - ) - { - // - bool result = false; - - // - ulong ticket = pack.ticket; - - // - XPosition positions[]; - - // - XPosition pPosition; - result = GetPosition( - ticket, - pPosition // - ); - if (result) - { - // - AddRef( - pPosition, - positions // - ); - } - - // - if (pack.supportPositionsCount > 0) - { - // - for (int i = 0; i < pack.supportPositionsCount; i++) - { - // - XPosition iPosition = pack.supportPositions[i]; - - // - AddRef( - iPosition, - positions // - ); - } - } - - // - // Force Close ... - if (!inProfit) - { - // - int closed = Close( - positions, - comment // - ); - - // - int cancelled = 0; - if (pack.supportOrdersCount > 0) - { - cancelled = CancelOrders(pack.supportOrders); - } - - // - result = (closed + cancelled) == (pack.supportPositionsCount + pack.supportOrdersCount + 1); - } - else - { - // - bool canHedge = SpecifiedIsPositionsReadyForHedge( - positions, - minProfitPerTrade, - minProfitPerVolumeFactor // - ); - if (canHedge) - { - // - int closed = Close( - positions, - comment // - ); - - // - int cancelled = 0; - if (pack.supportOrdersCount > 0) - { - cancelled = CancelOrders(pack.supportOrders); - } - - // - result = (closed + cancelled) == (pack.supportPositionsCount + pack.supportOrdersCount + 1); - } - else - { - result = false; - } - } - - // - return result; - } - bool ClosePositionPack( - ulong ticket, // Specified Position Pack - string symbol, // Specified Position Symbol - ENUM_TIMEFRAMES period, // Specified Position Period - string comment, // Specified Close Comment - bool inProfit = false, // if it's true only close Pack if in profit - double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... - double minProfitPerVolumeFactor = 0 // Min Volume Factor ... - ) - { - // - bool result = false; - - // - XPositionPack pack; - result = GetPositionPack( - ticket, - symbol, - period, - pack // - ); + result = ticket > 0; if (!result) { return result; } // - result = ClosePositionPack( - pack, - comment, - inProfit, - minProfitPerTrade, - minProfitPerVolumeFactor // + if (forceOpen) + { + // + result = IsOpen(ticket); + if (!result) + { + return result; + } + } + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + result = IsValidSize(positionsCount); + if (!result) + { + return result; + } + + // + // Extract Support Positions ... + XPosition supports[]; + int supportsCount = ExtractSupports( + positions, + supports // ); + result = IsValidSize(supportsCount); + if (!result) + { + return result; + } + + // + // Loop Through Supports ... + for (int i = 0; i < supportsCount; i++) + { + // + XPosition iSupport = supports[i]; + + // + ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); + ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); + + // + result = + // + (supportedTicket > 0 && ticket == supportedTicket) + // + || + // + (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) + // + ; + if (result) + { + break; + } + } // return result; } // - // Close Positions Pack ... - int ClosePositionsPack( - XPosition &positions[], // Positions ... - string comment, // Specified Close Comment - bool inProfit = false, // if it's true only close Pack if in profit - double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... - double minProfitPerVolumeFactor = 0 // Min Volume Factor ... + // Retrieve Specific Position's Supports ... + int GetSupports( + ulong ticket, + XPosition &dest[], // Result ... + bool forceOpen = true // ) { // int result = 0; // - int positionsCount = ArraySize(positions); - if (positionsCount <= 0) + Clean(dest); + + // + bool hasSupport = HasSupport( + ticket, + forceOpen // + ); + if (!hasSupport) { return result; } // - for (int i = 0; i < positionsCount; i++) + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + // Extract Support Positions ... + XPosition supports[]; + int supportsCount = ExtractSupports( + positions, + supports // + ); + if (!IsValidSize(supportsCount)) + { + return result; + } + + // + // Loop Through Supports ... + for (int i = 0; i < supportsCount; i++) { // - XPosition iPosition = positions[i]; + XPosition iSupport = supports[i]; // - bool isClosed = ClosePositionPack( - iPosition.ticket, - iPosition.symbol, - iPosition.period, - comment, - inProfit, - minProfitPerTrade, - minProfitPerVolumeFactor // - ); - if (isClosed) + ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); + ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); + + // + bool isOwn = + // + (supportedTicket > 0 && ticket == supportedTicket) + // + || + // + (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) + // + ; + if (isOwn) { - result++; + // + AddRef( + iSupport, + dest // + ); } } + // + result = ArraySize(dest); + + // + return result; + } + + // + // Retrieve Specific Position's Supports ... + int GetSupports( + ulong ticket, + XOrder &dest[], // Result ... + bool forceOpen = true // + ) + { + // + int result = 0; + + // + Clean(dest); + + // + bool hasSupport = HasSupport( + ticket, + forceOpen // + ); + if (!hasSupport) + { + return result; + } + + // + XOrder orders[]; + int ordersCount = GetOrders( + orders, + NULL, // All Symbols ... + NULL, // All Providers ... + NULL, // All Periods ... + X_POSITION_TYPE_ALL, // All Types ... + ORDER_STATE_PLACED, // Untriggere Orders ... + true // + ); + if (!IsValidSize(ordersCount)) + { + return result; + } + + // + // Extract Support Positions ... + XOrder supports[]; + int supportsCount = ExtractSupports( + orders, + supports // + ); + if (!IsValidSize(supportsCount)) + { + return result; + } + + // + // Loop Through Supports ... + for (int i = 0; i < supportsCount; i++) + { + // + XOrder iSupport = supports[i]; + + // + ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); + ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); + + // + bool isOwn = + // + (supportedTicket > 0 && ticket == supportedTicket) + // + || + // + (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) + // + ; + if (isOwn) + { + // + AddRef( + iSupport, + dest // + ); + } + } + + // + result = ArraySize(dest); + // return result; } @@ -3536,37 +3461,6 @@ protected: return result; } - // - // Extract Specific Deals Position's Pack ... - // this used when a Position SL or TP triggered and we want to close - // all it's Supported Packs ... - bool GetDealPack( - XDeal &deal, - XPositionPack &pack // - ) - { - // - bool result = false; - - // - ulong ticket = deal.positionId; - ENUM_TIMEFRAMES dealPeriod = GetDealPeriod(deal); - string dealSymbol = deal.symbol; - - // - // So We Have to Get Positions Pack ... - result = GetPositionPack( - ticket, - dealSymbol, - dealPeriod, - pack - // - ); - - // - return result; - } - // ENUM_TIMEFRAMES GetDealPeriod(XDeal &deal) { diff --git a/Documents/BKP/usefull.mq5 b/Documents/BKP/usefull.mq5 index e5288549..24cdf913 100644 --- a/Documents/BKP/usefull.mq5 +++ b/Documents/BKP/usefull.mq5 @@ -138,3 +138,338 @@ // return result; } + + +//////////////////////////////////////////////////////////////////////////////// + + + // + // XPosition Pack ... + + // + // Extract specific Positions Pack ... + // in this senario there is no need to Position exists itself ... + bool GetPositionPack( + ulong ticket, // Specified Positions Ticket + string symbol, // Specified Position Symbol + ENUM_TIMEFRAMES period, // Specified Position Period + XPositionPack &pack // Hold Result + ) + { + // + bool result = false; + + // + pack.Clean(); + + // + XPosition position; + bool hasPosition = GetPosition( + ticket, + position + // + ); + if (hasPosition) + { + pack.position = position; + } + + // + XOrder supportOrders[]; + XPosition supportPositions[]; + + // + XOrder orders[]; + GetOrders( + orders, + symbol, // Specified Symbol + NULL, // All Providers + period, // Specified Period + NULL, // All Types + ORDER_STATE_PLACED, // Just UnTriggered Orders + true // Filter by Magic + ); + int ordersCount = ArraySize(orders); + + // + // Select Orders ... + if (ordersCount > 0) + { + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + // Retrieve Order Supported Ticket ... + ulong parentTicket = ExtractSupportedTicket(iOrder.comment); + if (NotEmpty(parentTicket) && parentTicket == ticket) + { + // + AddRef( + iOrder, + supportOrders + // + ); + } + } + } + + // + int supportOrdersCount = ArraySize(supportOrders); + if (supportOrdersCount > 0) + { + // + pack.supportOrdersCount = supportOrdersCount; + + // + Copy( + supportOrders, + pack.supportOrders); + } + + // + XPosition positions[]; + GetPositions( + positions, + symbol, // Specified Symbol ... + NULL, // All Providers ... + period // Specified Period ... + ); + int positionsCount = ArraySize(positions); + + // + // Select Positions ... + if (positionsCount > 0) + { + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + ulong parentTicket = ExtractSupportedTicket(iPosition.comment); + if (NotEmpty(parentTicket) && parentTicket == ticket) + { + // + AddRef( + iPosition, + supportPositions + // + ); + } + } + } + + // + int supportPositionsCount = ArraySize(supportPositions); + if (supportPositionsCount > 0) + { + // + pack.supportPositionsCount = supportPositionsCount; + + // + Copy( + supportPositions, + pack.supportPositions); + } + + // + result = pack.IsValid(); + + // + return result; + } + + // + // Close Position Pack ... + bool ClosePositionPack( + XPositionPack &pack, // Specified Position Pack + string comment, // Specified Close Comment + bool inProfit = false, // if it's true only close Pack if in profit + double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... + double minProfitPerVolumeFactor = 0 // Min Volume Factor ... + ) + { + // + bool result = false; + + // + ulong ticket = pack.ticket; + + // + XPosition positions[]; + + // + XPosition pPosition; + result = GetPosition( + ticket, + pPosition // + ); + if (result) + { + // + AddRef( + pPosition, + positions // + ); + } + + // + if (pack.supportPositionsCount > 0) + { + // + for (int i = 0; i < pack.supportPositionsCount; i++) + { + // + XPosition iPosition = pack.supportPositions[i]; + + // + AddRef( + iPosition, + positions // + ); + } + } + + // + // Force Close ... + if (!inProfit) + { + // + int closed = Close( + positions, + comment // + ); + + // + int cancelled = 0; + if (pack.supportOrdersCount > 0) + { + cancelled = CancelOrders(pack.supportOrders); + } + + // + result = (closed + cancelled) == (pack.supportPositionsCount + pack.supportOrdersCount + 1); + } + else + { + // + bool canHedge = SpecifiedIsPositionsReadyForHedge( + positions, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + if (canHedge) + { + // + int closed = Close( + positions, + comment // + ); + + // + int cancelled = 0; + if (pack.supportOrdersCount > 0) + { + cancelled = CancelOrders(pack.supportOrders); + } + + // + result = (closed + cancelled) == (pack.supportPositionsCount + pack.supportOrdersCount + 1); + } + else + { + result = false; + } + } + + // + return result; + } + bool ClosePositionPack( + ulong ticket, // Specified Position Pack + string symbol, // Specified Position Symbol + ENUM_TIMEFRAMES period, // Specified Position Period + string comment, // Specified Close Comment + bool inProfit = false, // if it's true only close Pack if in profit + double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... + double minProfitPerVolumeFactor = 0 // Min Volume Factor ... + ) + { + // + bool result = false; + + // + XPositionPack pack; + result = GetPositionPack( + ticket, + symbol, + period, + pack // + ); + if (!result) + { + return result; + } + + // + result = ClosePositionPack( + pack, + comment, + inProfit, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + + // + return result; + } + + // + // Close Positions Pack ... + int ClosePositionsPack( + XPosition &positions[], // Positions ... + string comment, // Specified Close Comment + bool inProfit = false, // if it's true only close Pack if in profit + double minProfitPerTrade = 0, // Min Profit based On Volume Factor ... + double minProfitPerVolumeFactor = 0 // Min Volume Factor ... + ) + { + // + int result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = ClosePositionPack( + iPosition.ticket, + iPosition.symbol, + iPosition.period, + comment, + inProfit, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + if (isClosed) + { + result++; + } + } + + // + return result; + } diff --git a/Experts/x-saherelm.x121.ea.mq5 b/Experts/x-saherelm.x121.ea.mq5 index 6b832ccf..99218a41 100644 --- a/Experts/x-saherelm.x121.ea.mq5 +++ b/Experts/x-saherelm.x121.ea.mq5 @@ -49,17 +49,17 @@ input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications // Risk Management ... input group "Risk Management"; input double x121EAVolume = 0.01; // Static Volume -input double x121EATPPoint = 200; // TP Point -input double x121EASLPoint = 200; // SL Point +input double x121EATPPoint = 500; // TP Point +input double x121EASLPoint = 500; // SL Point input int x121EAMaxAllowedTrades = 1; // Max Allowed Positions input bool x121EAIgnoreSL = false; // Ignore Calculated SL input bool x121EAIgnoreTP = false; // Ignore Calculated TP input bool x121EAAllowTrailStop = true; // Enable Trailling Stop Losses input double x121EAFirstTrailDistance = 60; // Start Trailling Distance input double x121EAFirstTrailPoint = 50; // First Stop Trail -input double x121EANextTrailDistance = 10; // Next Trailling Distance -input double x121EANextTrailPoint = 5; // Next Trailling Step -input bool x121EAUseSupport = false; // Use Support Signals +input double x121EANextTrailDistance = 25; // Next Trailling Distance +input double x121EANextTrailPoint = 10; // Next Trailling Step +input bool x121EAAllowSupport = false; // Allow Support Signals input bool x121EAAllowGrid = false; // Allow Grid Signals input double x121EAGridDistance = 100; // Grid Distance input double x121EAGridVolumeMultiplier = 2; // Grid Volume Multiplier @@ -195,7 +195,7 @@ bool InitialEA() x121EA.GetVerificationFromOtherTimeFrames(x121EAGetVerificationFromOtherTimeFrames); // - x121EA.UseSupport(x121EAUseSupport); + x121EA.AllowSupport(x121EAAllowSupport); // // Grid System ... diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index cee54666..9f5fd2ba 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -4086,10 +4086,11 @@ ulong ExtractSupportedTicket(string value) } // -// Extract Support Positions ... -int ExtractSupportPositions( - XPosition &source[], - XPosition &dest[] // Result ... +// Extract Support ... +template +int ExtractSupports( + T &source[], + T &dest[] // Result ... ) { // @@ -4109,7 +4110,7 @@ int ExtractSupportPositions( for (int i = 0; i < sourceCount; i++) { // - XPosition iSource = source[i]; + T iSource = source[i]; // ulong isSupport = ExtractSupportedTicket(iSource.comment) > 0;