From 54160e7f99cea4b91ab779cfe2e945c17d32aad8 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 27 May 2024 17:41:32 +0330 Subject: [PATCH] last ... --- Classes/x-saherelm.x121.provider.class.mq5 | 31 +- Classes/x-saherelm.x121.xea.class.mq5 | 347 ++++++++++++++++++++- Classes/x-saherelm.x121.xmcycle.class.mq5 | 153 +++++++++ Classes/x-saherelm.xtrade.class.mq5 | 1 + Experts/x-test.x121ea.mq5 | 2 +- Libraries/x-saherelm.xtrade.lib.mq5 | 165 ++++++++++ 6 files changed, 677 insertions(+), 22 deletions(-) diff --git a/Classes/x-saherelm.x121.provider.class.mq5 b/Classes/x-saherelm.x121.provider.class.mq5 index 511f3252..7fc7b1d5 100644 --- a/Classes/x-saherelm.x121.provider.class.mq5 +++ b/Classes/x-saherelm.x121.provider.class.mq5 @@ -1522,7 +1522,8 @@ public: price, mSupportResistances, count, - step); + step // + ); // return result; @@ -4194,13 +4195,13 @@ private: // result = // - isCSMHKLong - // - || - // - isSSMHKLong - // - || + // isCSMHKLong + // // + // || + // // + // isSSMHKLong + // // + // || // isMSMHKLong // @@ -4810,13 +4811,13 @@ private: // result = // - isCSMHKShort - // - || - // - isSSMHKShort - // - || + // isCSMHKShort + // // + // || + // // + // isSSMHKShort + // // + // || // isMSMHKShort // diff --git a/Classes/x-saherelm.x121.xea.class.mq5 b/Classes/x-saherelm.x121.xea.class.mq5 index e92b26f2..c24a9343 100644 --- a/Classes/x-saherelm.x121.xea.class.mq5 +++ b/Classes/x-saherelm.x121.xea.class.mq5 @@ -396,6 +396,9 @@ public: // mAlert.Alert(message); + // + RemoveEQMOrders(); + // for (int i = 0; i < positionsCount; i++) { @@ -434,19 +437,282 @@ public: XSCPositionHolder *iHolder = mHolders[i]; // - XPosition iMaxInDP; - bool hasMaxInDP = iHolder.GetMaxInDrawdown(iMaxInDP); - if (!hasMaxInDP) + // We Can Select Multiple Positions for Place EQM Supports ... + + // + // Select Max In Drawdown Position and Protect it ... + XPosition iSelectedPosition; + bool iHasPosition = iHolder.GetMaxInDrawdown(iSelectedPosition); + if (iHasPosition) { + // + // Try to Protect Max In Drawdown Positions Position ... + PlaceEQMOrders(iSelectedPosition); + } + } + + // + } + + // + // Add Or Update EQM Orders ... + void PlaceEQMOrders(XPosition &position) + { + // + // TODO: Make It Configurable ... + int maxEQMCount = 5; + return; + + // + // Position Protection Senarioos ... + if (!position.IsValid()) + { + return; + } + + // + int descriptorIDX = FindDescriptorIndex(position); + if (descriptorIDX <= -1) + { + return; + } + + // + X121ProviderDescriptor descriptor = mDescriptors[descriptorIDX]; + + // + XOHCLSupRes slSupRes; + bool hasSupRes = descriptor + .provider + .GenerateSupRes( + slSupRes, + position.type, + 5 // + ); + + // + XDrawSpecifications supDrawSpecs; + supDrawSpecs.draw = true; + supDrawSpecs.rayRight = true; + supDrawSpecs.clr = clrLightGreen; + + //, + XDrawSpecifications resDrawSpecs; + resDrawSpecs.draw = true; + resDrawSpecs.rayRight = true; + resDrawSpecs.clr = clrLightCoral; + + // + // DrawSupRes( + // slSupRes, + // supDrawSpecs, + // resDrawSpecs // + // ); + + // + XSignal supports[]; + int supportsCount = GenerateEQMOrders( + supports, + position, + slSupRes // + ); + if (!IsValidSize(supportsCount)) + { + return; + } + + // + XOrder untriggeredOrders[]; + int untriggeredOrdersCount = mTrader.GetOrders( + untriggeredOrders, + position.symbol, + XEQMSupportToken, + position.period, + NULL, // All Types ... + ORDER_STATE_PLACED, + true // + ); + + // + XPosition triggereSupports[]; + int tiggeredSupportsCount = mTrader.GetPositions( + triggereSupports, + position.symbol, + XEQMSupportToken, + position.period, + NULL, // All Types ... + true // + ); + + // + if (untriggeredOrdersCount + + tiggeredSupportsCount >= + maxEQMCount) + { + return; + } + + // + XSignal filteredSignals[]; + for (int i = 0; i < supportsCount; i++) + { + // + XSignal iSupport = supports[i]; + + // + double sl; + iSupport.RegularSL(sl); + + // + double tp; + iSupport.RegularTP(tp); + + // + if (!IsValidSize(untriggeredOrdersCount) && !IsValidSize(tiggeredSupportsCount)) + { + // + AddRef( + iSupport, + filteredSignals // + ); + + // continue; } // - // Try to Protect a Position ... - ProtectPosition(iMaxInDP); + bool isOrdersPassed = true; + if (!IsValidSize(untriggeredOrdersCount)) + { + isOrdersPassed = true; + } + else + { + // + for (int j = 0; j < untriggeredOrdersCount; j++) + { + // + XOrder jOrder = untriggeredOrders[j]; + + // + bool isSame = + // + jOrder.symbol == iSupport.symbol && + jOrder.period == iSupport.period && + jOrder.openPrice == iSupport.entry && + jOrder.sl == sl && + jOrder.tp == tp + // + ; + if (isSame) + { + // + isOrdersPassed = false; + break; + } + } + } + + // + bool isPositionsPassed = true; + if (!IsValidSize(tiggeredSupportsCount)) + { + isPositionsPassed = true; + } + else + { + // + for (int j = 0; j < tiggeredSupportsCount; j++) + { + // + XPosition jPosition = triggereSupports[j]; + + // + bool isSame = + // + jPosition.symbol == iSupport.symbol && + jPosition.period == iSupport.period && + jPosition.entry == iSupport.entry && + jPosition.sl == sl && + jPosition.tp == tp + // + ; + if (isSame) + { + // + isPositionsPassed = false; + break; + } + } + } + + // + if (isOrdersPassed && + isPositionsPassed) + { + // + AddRef( + iSupport, + filteredSignals // + ); + } + } + int filteredSignalsCount = ArraySize(filteredSignals); + if (!IsValidSize(filteredSignalsCount)) + { + return; } // + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int placedOrders = mTrader.ExecuteSignals( + filteredSignals, + states, + ORDER_TIME_GTC, + NULL, + false // Ignore Policies ... + ); + if (placedOrders > 0) + { + // + string message = "EQM Placed (" + ToString(placedOrders) + ") Support Orders ..."; + + // + mAlert.Alert(message); + } + } + + // + void RemoveEQMOrders() + { + // + XOrder untriggeredOrders[]; + int untriggeredOrdersCount = mTrader.GetOrders( + untriggeredOrders, + NULL, + XEQMSupportToken, + NULL, + NULL, // All Types ... + ORDER_STATE_PLACED, + true // + ); + if (!IsValidSize(untriggeredOrdersCount)) + { + return; + } + + // + int canceleds = mTrader.CancelOrders( + untriggeredOrders // + ); + if (canceleds > 0) + { + // + string message = "EQM Cancel Support ..."; + + // + mAlert.Alert(message); + } } // @@ -479,7 +745,7 @@ public: // bool canManageState = // - true + iPosition.provider != XEQMSupportToken // ; @@ -1024,6 +1290,9 @@ public: // mAlert.Alert(message); + + // + RemoveEQMOrders(); } // @@ -1039,6 +1308,9 @@ public: // // Here i Have to Detect In DrawDown Positions ... + // + RemoveEQMOrders(); + // string mSymbols[]; XSCPositionHolder *mHolders[]; @@ -1101,6 +1373,9 @@ protected: { // // Here i Can Protect Position ... + // This Protect Include One Position in Market Mode ... + // If Provided ... + // the Positions Selection must passed Some conditions ... // string message = "For (" + position.symbol + ") Max In Drawdown Position is: (" + @@ -1130,6 +1405,66 @@ private: return ArraySize(mDescriptors); } + // + // Find Specifc Descriptor ... + int FindDescriptorIndex( + string symbol, + ENUM_TIMEFRAMES period // + ) + { + // + int result = -1; + + // + if (!IsValid(symbol) || + !IsValid(period)) + { + return result; + } + + // + int descriptorsCount = CountDescriptors(); + if (!IsValidSize(descriptorsCount)) + { + return result; + } + + // + for (int i = 0; i < descriptorsCount; i++) + { + // + X121ProviderDescriptor iDescriptor = mDescriptors[i]; + + // + bool isPassed = + // + iDescriptor.symbol == symbol && + iDescriptor.period == period + // + ; + if (isPassed) + { + // + result = i; + break; + } + } + + // + return result; + } + + template + int FindDescriptorIndex( + T &item // + ) + { + return FindDescriptorIndex( + item.symbol, + item.period // + ); + } + // // Trails Holding ... diff --git a/Classes/x-saherelm.x121.xmcycle.class.mq5 b/Classes/x-saherelm.x121.xmcycle.class.mq5 index 3d96ff89..166d35c0 100644 --- a/Classes/x-saherelm.x121.xmcycle.class.mq5 +++ b/Classes/x-saherelm.x121.xmcycle.class.mq5 @@ -5289,4 +5289,157 @@ struct X121MarketCycleDescriptor } }; +// +// Custom Draws ... + +// +// Custom Struct Draws ... +bool DrawSupRes( + XOHCLSupRes &item, // Struct item to Draw ... + XDrawSpecifications &supSpecs, // Supports specs ... + XDrawSpecifications &resSpecs, // Resistances specs ... + long chartID = 0, + int subWindow = 0, + string prefix = "SupRes" // +) +{ + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + datetime cTime = TimeCurrent(); + datetime pTime = TimeCurrent() - PeriodSeconds(PERIOD_M10); + + // + // Support ... + int supCount = item.CountSupports(); + bool canDrawSups = IsValidSize(supCount) && supSpecs.draw; + if (canDrawSups) + { + // + for (int i = 0; i < supCount; i++) + { + // + double iSup = item.sup[i]; + + // + string supName = prefix + "_" + "Sup_" + ToString(iSup); + + // + DrawTrendLine( + chartID, + supName, + subWindow, + pTime, + iSup, + cTime, + iSup, + supSpecs.clr, + supSpecs.style, + supSpecs.width, + supSpecs.back, + supSpecs.selection, + supSpecs.rayRight, + supSpecs.hidden, + supSpecs.zOrder // + ); + + // + if (IsValid(supSpecs.label)) + { + // + DrawText( + chartID, + supName + "_lbl", + subWindow, + cTime, + iSup, + supSpecs.label, + supSpecs.labelFont, + supSpecs.labelFontSize, + supSpecs.labelColor, + supSpecs.labelAngel, + supSpecs.labelAnchor, + supSpecs.back, + supSpecs.selection, + supSpecs.hidden, + supSpecs.zOrder // + ); + } + } + } + + // + // Resistance ... + int resCount = item.CountResistances(); + bool canDrawRess = IsValidSize(supCount) && supSpecs.draw; + if (canDrawRess) + { + // + for (int i = 0; i < resCount; i++) + { + // + double iRes = item.res[i]; + + // + string resName = prefix + "_" + "Res_" + ToString(iRes); + + // + DrawTrendLine( + chartID, + resName, + subWindow, + pTime, + iRes, + cTime, + iRes, + resSpecs.clr, + resSpecs.style, + resSpecs.width, + resSpecs.back, + resSpecs.selection, + resSpecs.rayRight, + resSpecs.hidden, + resSpecs.zOrder // + ); + + // + if (IsValid(resSpecs.label)) + { + // + DrawText( + chartID, + resName + "_lbl", + subWindow, + cTime, + iRes, + resSpecs.label, + resSpecs.labelFont, + resSpecs.labelFontSize, + resSpecs.labelColor, + resSpecs.labelAngel, + resSpecs.labelAnchor, + resSpecs.back, + resSpecs.selection, + resSpecs.hidden, + resSpecs.zOrder // + ); + } + } + } + + // + result = canDrawSups || canDrawRess; + + // + return result; +} + // \ No newline at end of file diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index c75db8b6..db02f9fb 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -514,6 +514,7 @@ public: // // Implementation ... +// // a Class For Manage Trades and Handle Trading Actions ... class XSCTrade : public XSCBase { diff --git a/Experts/x-test.x121ea.mq5 b/Experts/x-test.x121ea.mq5 index 3b97eb81..d977272b 100644 --- a/Experts/x-test.x121ea.mq5 +++ b/Experts/x-test.x121ea.mq5 @@ -195,7 +195,7 @@ bool InitialEA() Add(X110, signallers); Add(X121, signallers); Add(X128, signallers); - // Add(X92, signallers); + Add(X92, signallers); // GetAllX121SignalProviders(signallers); // diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index 904da6f4..8a8e9aff 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -3945,3 +3945,168 @@ string PrepareSLTrailTag( } // +// EQM Support Orders ... + +// +int GenerateEQMOrders( + XSignal &orders[], // Result + XPosition &position, // Supported Position + XOHCLSupRes &supRes, // Data Source + bool longs = true, + bool shorts = true // +) +{ + // + int result = 0; + + // + Clean(orders); + + // + if (!supRes.IsValid() || + !position.IsValid()) + { + return result; + } + + // + if (longs) + { + // + double longLevels[]; + + // + Copy( + supRes.res, + longLevels // + ); + + // + double minSup = GetMin( + supRes.sup // + ); + if (minSup > 0) + { + // + Add( + minSup, + longLevels // + ); + } + + // + ArraySort(longLevels); + + // + if (ArraySize(longLevels) > 2) + { + // + for (int i = 0; i < ArraySize(longLevels) - 2; i++) + { + // + double iSL = longLevels[i]; + double iEntry = longLevels[i + 1]; + double iTP = longLevels[i + 2]; + + // + XSignal iSignal; + bool isPrepared = iSignal.PrepareStopLong( + position.symbol, + XEQMSupportToken, + position.period, + iEntry, + position.volume, + X_SIGNAL_USE_NOTHING, + iSL, + iTP // + ); + if (isPrepared) + { + // + string comment = GenerateSupportTag(position.ticket); + iSignal.comment = comment; + + // + AddRef( + iSignal, + orders // + ); + } + } + } + } + + // + if (shorts) + { + // + double shortLevels[]; + + // + Copy( + supRes.sup, + shortLevels // + ); + + // + double maxRes = GetMax( + supRes.res // + ); + if (maxRes > 0) + { + // + Add( + maxRes, + shortLevels // + ); + } + + // + ArraySort(shortLevels); + ArrayReverse(shortLevels); + + // + if (ArraySize(shortLevels) > 2) + { + // + for (int i = 0; i < ArraySize(shortLevels) - 2; i++) + { + // + double iSL = shortLevels[i]; + double iEntry = shortLevels[i + 1]; + double iTP = shortLevels[i + 2]; + + // + XSignal iSignal; + bool isPrepared = iSignal.PrepareStopShort( + position.symbol, + XEQMSupportToken, + position.period, + iEntry, + position.volume, + X_SIGNAL_USE_NOTHING, + iSL, + iTP // + ); + if (isPrepared) + { + // + string comment = GenerateSupportTag(position.ticket); + iSignal.comment = comment; + + // + AddRef( + iSignal, + orders // + ); + } + } + } + } + + // + result = ArraySize(orders); + + // + return result; +}