diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index cc53f016..1f8d9653 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -4401,6 +4401,25 @@ public: int maxAllowed = MaxAllowedTrades(); bool perDirection = UseMaxAllowedPerDirection(); + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + bool hasPositions = IsValidSize(positionsCount); + + // + double minProfitPerTrade = MinProfitPerTrade(); + double minProfitPerTradeVolumeFactor = minProfitPerTradeVolumeFactor(); + + // + XSymbolPositions symbolPositions[]; + int smybolPositionsCount = ExtractSymbolPositions( + positions, + symbolPositions, + minProfitPerTrade, + minProfitPerTradeVolumeFactor // + ); + bool hasSymbolPositions = IsValidSize(smybolPositionsCount); + // for (int i = 0; i < signalsCount; i++) { @@ -4408,10 +4427,47 @@ public: XSignal iSignal = tmpSignals[i]; // - bool isSignalValid = false; + bool isLong = IsLong(iSignal.type); // - isSignalValid = IsSignalDelayPassed(iSignal); + bool isSignalValid = false; + bool hasSameTypeSignal = false; + bool isFirstSymbolSignal = false; + + // + // Find Symbol Index ... + int symbolIDX = FindSymbolIndex( + iSignal.symbol, + symbolPositions // + ); + bool isValidSymbolIDX = IsValidIndex(symbolIDX); + if (!isValidSymbolIDX) + { + // + // We Sure it is First Signal of Smybol in a While ... + hasSameTypeSignal = false; + isFirstSymbolSignal = true; + } + else + { + // + // We Sure it isnt First Signal of Symbol at current State ... + isFirstSymbolSignal = false; + + // + // Check Has Same Type Signal or not ... + hasSameTypeSignal = + isLong + ? symbolPositions[symbolIDX].longs > 1 + : symbolPositions[symbolIDX].shorts > 1; + } + + // + // Check Signal Delay Passed ... + isSignalValid = IsSignalDelayPassed( + iSignal, + symbolPositions[symbolIDX] // + ); if (!isSignalValid) { continue; @@ -4422,22 +4478,12 @@ public: if (mCloseOnOpposit) { // - // Select Signal Opposit Positions ... - ENUM_X_POSITION_TYPES iOpposit = GetOppositPositionType(iSignal.type); - - // - XPosition iPositions[]; - int iPositionsCount = mTrader.GetPositions( - iPositions, - iSignal.symbol, - NULL, // All Providers ... - NULL, // All Periods ... - iOpposit // Opposit Positions ... - ); - - // - if (IsValidSize(iPositionsCount)) - { + int oppositCount = + isLong + ? symbolPositions[symbolIDX].CountShorts() + : symbolPositions[symbolIDX].CountLongs(); + bool hasOpposit = IsValidSize(oppositCount); + if (hasOpposit) { // string comment = "Close due Opposit ..."; @@ -4491,10 +4537,13 @@ public: } // - isSignalValid = - iSupportsCount <= 0 - ? iSymbolsPositionsCount < maxAllowed - : iSymbolsPositionsCount - iSupportsCount < maxAllowed; + isFirstOfSymbol = + + // + isSignalValid = + iSupportsCount <= 0 + ? iSymbolsPositionsCount < maxAllowed + : iSymbolsPositionsCount - iSupportsCount < maxAllowed; if (!isSignalValid) { continue; @@ -4507,7 +4556,6 @@ public: // // Only Accept Next Same Type when Previous in Profit ... - bool isSameTypeExists = false; if (isSignalValid) { // @@ -4599,6 +4647,7 @@ public: // // Multiply Signal Volume ... + // Create First Signal Opposit Protector ... if (isSignalValid) { // @@ -4647,6 +4696,9 @@ public: double volumeMultiplier = IncreaseNextSignalsVolumeMultiplier(); iSignal.volume = iSignal.volume * (multiplier * volumeMultiplier); } + + // + // } // @@ -4948,7 +5000,8 @@ protected: // // Check Delay Between Two Signals ... bool IsSignalDelayPassed( - XSignal &signal // + XSignal &signal, + XSymbolPositions &positions // ) { // @@ -4972,29 +5025,18 @@ protected: } // - // Retrieve Positions ... - // Based On Provider and Symbol and TimeFrame ... - XPosition positions[]; - int positionsCount = mTrader.GetPositions( - positions, - signal.symbol, - NULL, // signal.provider, - NULL, // signal.period, - ToPositionType(signal.type), - true // Filter By Magic ... + XPosition youngest; + int youngestAge = positions.GetYoungest( + youngest, + iSignal.type // ); - result = !IsValidSize(positionsCount); + result = !IsValidIndex(youngestAge); if (result) { return result; } // - XPosition youngest; - int youngestAge = GetYoungest( - youngest, - positions // - ); result = youngestAge >= delay; // diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index 557b2f7a..185066bb 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -2796,6 +2796,8 @@ struct XSymbolPositions XPosition longs[]; XPosition shorts[]; XPosition positions[]; + XPosition longSupports[]; + XPosition shortSupports[]; // bool forceHedge; @@ -3022,52 +3024,311 @@ struct XSymbolPositions } // -}; - -// -bool IsContainsSymbol( - string symbol, - int &_index, - XSymbolPositions &_items[] // -) -{ - // - bool result = false; - - // - _index = -1; - - // - result = IsValid(symbol); - if (!result) - { - return result; - } - - // - int itemsCount = ArraySize(_items); - result = IsValidSize(itemsCount); - if (!result) - { - return result; - } - - // - for (int i = 0; i < itemsCount; i++) + int GetOldest( + XPosition &_oldest, // + ENUM_POSITION_TYPE _type // + ) { // - result = _items[i].symbol == symbol; - if (result) + int result = -1; + + // + bool isLong = IsLong(_type); + + // + int count = + isLong + ? CountLongs() + : CountShorts(); + if (!IsValidSize(count)) + { + return result; + } + + // + if (isLong) { // - _index = i; - break; + result = GetOldest( + _oldest, + longs // + ); } + else + { + // + result = GetOldest( + _oldest, + shorts // + ); + } + + // + return result; } // - return result; -} + int GetYoungest( + XPosition &_youngest, // + ENUM_POSITION_TYPE _type // + ) + { + // + int result = -1; + + // + bool isLong = IsLong(_type); + + // + int count = + isLong + ? CountLongs() + : CountShorts(); + if (!IsValidSize(count)) + { + return result; + } + + // + if (isLong) + { + // + result = GetYoungest( + _youngest, + longs // + ); + } + else + { + // + result = GetYoungest( + _youngest, + shorts // + ); + } + + // + return result; + } + + // + int GetMaxInProfit( + XPosition _position, + ENUM_POSITION_TYPE _type // + ) + { + // + int result = -1; + + // + bool isLong = IsLong(_type); + + // + int count = + isLong + ? CountLongs() + : CountShorts(); + if (!IsValidSize(count)) + { + return result; + } + + // + if (isLong) + { + // + result = FindMaxProfitIndex( + longs // + ); + + // + if (IsValidIndex(result)) + { + _position = longs[result]; + } + } + else + { + // + result = FindMaxProfitIndex( + shorts // + ); + + // + if (IsValidIndex(result)) + { + _position = shorts[result]; + } + } + + // + return result; + } + + // + int GetMinInProfit( + XPosition _position, + ENUM_POSITION_TYPE _type // + ) + { + // + int result = -1; + + // + bool isLong = IsLong(_type); + + // + int count = + isLong + ? CountLongs() + : CountShorts(); + if (!IsValidSize(count)) + { + return result; + } + + // + if (isLong) + { + // + result = FindMinProfitIndex( + longs // + ); + + // + if (IsValidIndex(result)) + { + _position = longs[result]; + } + } + else + { + // + result = FindMinProfitIndex( + shorts // + ); + + // + if (IsValidIndex(result)) + { + _position = shorts[result]; + } + } + + // + return result; + } + + // + int GetMaxInDrawdown( + XPosition _position, + ENUM_POSITION_TYPE _type // + ) + { + // + int result = -1; + + // + bool isLong = IsLong(_type); + + // + int count = + isLong + ? CountLongs() + : CountShorts(); + if (!IsValidSize(count)) + { + return result; + } + + // + if (isLong) + { + // + result = FindMaxInDrawdownIndex( + longs // + ); + + // + if (IsValidIndex(result)) + { + _position = longs[result]; + } + } + else + { + // + result = FindMaxInDrawdownIndex( + shorts // + ); + + // + if (IsValidIndex(result)) + { + _position = shorts[result]; + } + } + + // + return result; + } + + // + int GetMinInDrawdown( + XPosition _position, + ENUM_POSITION_TYPE _type // + ) + { + // + int result = -1; + + // + bool isLong = IsLong(_type); + + // + int count = + isLong + ? CountLongs() + : CountShorts(); + if (!IsValidSize(count)) + { + return result; + } + + // + if (isLong) + { + // + result = FindMinInDrawdownIndex( + longs // + ); + + // + if (IsValidIndex(result)) + { + _position = longs[result]; + } + } + else + { + // + result = FindMinInDrawdownIndex( + shorts // + ); + + // + if (IsValidIndex(result)) + { + _position = shorts[result]; + } + } + + // + return result; + } + + // +}; // // TypeDefs ... @@ -3640,7 +3901,7 @@ int ExtractInProfitPositions( } // -int FindMaxDrawdownIndex( +int FindMaxInDrawdownIndex( XPosition &positions[] // Position Collection ) { @@ -3680,7 +3941,7 @@ int FindMaxDrawdownIndex( } // -int FindMinDrawdownIndex( +int FindMinInDrawdownIndex( XPosition &positions[] // Position Collection ) {