diff --git a/Classes/x-saherelm.x-trade-manager.class.mq5 b/Classes/x-saherelm.x-trade-manager.class.mq5 index 2d42a1b9..e70ee377 100644 --- a/Classes/x-saherelm.x-trade-manager.class.mq5 +++ b/Classes/x-saherelm.x-trade-manager.class.mq5 @@ -529,28 +529,18 @@ class XCTradeManager : public XCBase // Do Collection Protectiong ... // - // TODO: Complete this ... - // // - // // Check Force Close ... - // if (IsValid(forceCloseAt)) - // { - // // - // datetime forceCloseTime = ParseDateTimeFromTimeString(forceCloseAt); - // bool canForceClose = IsTimeInRange( - // TimeCurrent(), - // forceCloseTime // - // ) && - // !isForceCloseAtTime; - // if (canForceClose) - // { - // // - // isForceCloseAtTime = HandleForceCloseTrades(ownPosition); + // Handle Force Close At Time ... + has = HandleForceCloseAtTime(); + if (has) + { + // + Clean(ownPosition); + Clean(ownLongPosition); + Clean(ownShortPosition); - // // - // // Prevent Moving Forward ... - // return; - // } - // } + // + return; + } // // Do Signle Protections ... @@ -860,10 +850,10 @@ class XCTradeManager : public XCBase * Check Allow Trade or not .. * * @param type: ENUM_POSITIO_TYPE - * + * * @return ( bool ) */ - bool AllowTrade(ENUM_POSITIO_TYPE type) + bool AllowTrade(ENUM_POSITION_TYPE type) { // bool result = false; @@ -878,35 +868,12 @@ class XCTradeManager : public XCBase // result = (IsLong(type) && allowLongs) || - (IsShort(typ) && allowShorts); + (IsShort(type) && allowShorts); // return result; } - /** - * Handle All Exists Symbol Configurations Restrictions ... - */ - void HandleRestrictions() - { - // - // Count Symbol Configurations ... - int count = ArraySize(symbolTradeConfigs); - bool has = IsValidSize(count); - if (!has) - { - return; - } - - // - // Handle Restrictions ... - datetime cTime = TimeCurrent(); - for (int i = 0; i < count; i++) - { - symbolTradeConfigs[i].HandleRestrictions(cTime); - } - } - /** * Execute Specified Signal ... * @@ -1063,6 +1030,39 @@ class XCTradeManager : public XCBase return result; } + /** + * Handle All Exists Symbol Configurations Restrictions ... + */ + void HandleRestrictions() + { + // + // Count Symbol Configurations ... + int count = ArraySize(symbolTradeConfigs); + bool has = IsValidSize(count); + if (!has) + { + return; + } + + // + // Handle Restrictions ... + datetime cTime = TimeCurrent(); + bool isNewDay = timeTracker.IsNewDay(); + for (int i = 0; i < count; i++) + { + // + // Reset Force Close At Time ... + if (isNewDay) + { + symbolTradeConfigs[i].isForceCloseAtTime = false; + } + + // + // Handle Restrictions ... + symbolTradeConfigs[i].HandleRestrictions(cTime); + } + } + /** * Handle Signal Recieved ... * @@ -1144,8 +1144,8 @@ class XCTradeManager : public XCBase // int configIdx = FindSymbolConfigurationIndex( - trades[idx].symbol, - tardes[idx].period // + trades[idx].signal.symbol, + trades[idx].signal.period // ); isExists = IsValidIndex(configIdx); if (isExists) @@ -1214,8 +1214,8 @@ class XCTradeManager : public XCBase // int configIdx = FindSymbolConfigurationIndex( - trades[idx].symbol, - tardes[idx].period // + trades[idx].signal.symbol, + trades[idx].signal.period // ); isExists = IsValidIndex(configIdx); if (isExists) @@ -1301,8 +1301,8 @@ class XCTradeManager : public XCBase // int configIdx = FindSymbolConfigurationIndex( - trades[idx].symbol, - tardes[idx].period // + trades[idx].signal.symbol, + trades[idx].signal.period // ); isExists = IsValidIndex(configIdx); if (isExists) @@ -1329,6 +1329,99 @@ class XCTradeManager : public XCBase RemoveTrade(idx); } + /** + * Handle All Symbols Config Force Close At Time ... + * + * @return ( bool ) + */ + bool HandleForceCloseAtTime() + { + // + bool result = false; + + // + // Check Symbol Config Exists ... + result = HasChild(symbolTradeConfigs); + if (!result) + { + return result; + } + + // + result = false; + int count = ArraySize(symbolTradeConfigs); + for (int i = 0; i < count; i++) + { + // + // Check Can Force Closed At ... + bool has = IsSpecifiedValid(symbolTradeConfigs[i].closeAllOpenTradesAt); + if (!has) + { + continue; + } + + // + // Parse Date ... + datetime forceCloseTime = ParseDateTimeFromTimeString(symbolTradeConfigs[i].closeAllOpenTradesAt); + has = IsTimeInRange( + TimeCurrent(), + forceCloseTime // + ) && + !symbolTradeConfigs[i].isForceCloseAtTime; + if (!has) + { + continue; + } + + // + // Selecting Positions ... + XTradeInfo iTrades[]; + int iTradesCount = FillSymbolConfigurationTrades( + symbolTradeConfigs[i], + iTrades // + ); + has = IsValidSize(iTradesCount); + if (!has) + { + // + SpecifiedClean(iTrades); + continue; + } + + // + // Converts Trades to Positions ... + XPosition iPositions[]; + int iPositionsCount = ToXPositions( + iTrades, + iPositions // + ); + has = IsValidSize(iPositionsCount); + if (!has) + { + // + SpecifiedClean(iTrades); + SpecifiedClean(iPositions); + continue; + } + + // + // Do Force Closing ... + has = HandleForceCloseTrades(iPositions); + if (has && !result) + { + result = true; + } + + // + // Cleanup Resources ... + SpecifiedClean(iTrades); + SpecifiedClean(iPositions); + } + + // + return result; + } + /** * Handle Position Partially Closed Event ... * @@ -1373,15 +1466,18 @@ class XCTradeManager : public XCBase string comment = "Force Close ..."; // - int closedsCount = trader.Close( - positions, - comment // - ); - result = IsValidSize(closedsCount); + int count = ArraySize(positions); + for (int i = 0; i < count; i++) + { + HandleForceClose(positions[i]); + } + + // + result = IsValidSize(count); if (result) { // - string message = prefix + "Force Close (" + ToXString(closedsCount) + ") Trades at Specified Time ..."; + string message = prefix + "Force Close (" + ToXString(count) + ") Trades at Specified Time ..."; HandleReportProtector(message); } @@ -1966,6 +2062,71 @@ class XCTradeManager : public XCBase return result; } + // + int FillSymbolConfigurationTrades( + XSymbolTradeConfig &config, + XTradeInfo &dest[] // + ) + { + // + int result = 0; + + // + SpecifiedClean(dest); + + // + // Check Trades ... + int count = ArraySize(trades); + if (!IsValidSize(count)) + { + return result; + } + + // + // Validate Config ... + if (!config.IsValid()) + { + return result; + } + + // + // Find Config ... + int idx = FindSymbolConfigurationIndex(config); + if (!IsValidIndex(idx)) + { + return result; + } + + // + bool has = false; + string symbol = symbolTradeConfigs[idx].symbol; + ENUM_TIMEFRAMES period = symbolTradeConfigs[idx].period; + for (int i = 0; i < count; i++) + { + // + has = + trades[i].signal.symbol == symbol && + trades[i].signal.period == period && + trades[i].positionID > 0; + if (!has) + { + continue; + } + + // + AddRef( + trades[i], + dest // + ); + } + + // + result = ArraySize(dest); + + // + return result; + } + // int FindSymbolConfigurationIndex( string symbol, @@ -2006,6 +2167,54 @@ class XCTradeManager : public XCBase // // Tools ... + // + int ToXPositions( + XTradeInfo &source[], + XPosition &dest[] // + ) + { + // + int result = 0; + + // + SpecifiedClean(dest); + + // + int count = ArraySize(source); + bool has = IsValidSize(count); + if (!has) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XPosition iPosition; + has = trader.GetPosition( + source[i].positionID, + iPosition); + if (has) + { + // + AddRef( + iPosition, + dest // + ); + } + + // + iPosition.Clean(); + } + + // + result = ArraySize(dest); + + // + return result; + } + // string EscapeString(string value) { diff --git a/Classes/x-saherelm.x-trade.class.mq5 b/Classes/x-saherelm.x-trade.class.mq5 index 788e38a4..62b0f9ff 100644 --- a/Classes/x-saherelm.x-trade.class.mq5 +++ b/Classes/x-saherelm.x-trade.class.mq5 @@ -2108,7 +2108,7 @@ class XCTrade : public XCBase // // Retrieve Specific Position by Index ... - bool GetPosition( + bool GetPositionByIndex( int index, // Specified Index XPosition &result // Hold's Result ) diff --git a/Libraries/x-saherelm.x-trade.lib.mq5 b/Libraries/x-saherelm.x-trade.lib.mq5 index 70397627..1d117128 100644 --- a/Libraries/x-saherelm.x-trade.lib.mq5 +++ b/Libraries/x-saherelm.x-trade.lib.mq5 @@ -2914,6 +2914,7 @@ struct XSymbolTradeConfig ENUM_TIMEFRAMES period; // Trading Period int maxAllowedPositions; // Max Allowed Same Time Trades double maxAllowedSpread; // Max Allowed Spread For Trade + bool isForceCloseAtTime; // a Flag for Determines Force Closed or not XTradeSession sessions[]; // Trading Sessions string closeAllOpenTradesAt; // Close All Open Trades per Day At Specified Time int restrictionsPeriodMultiplier; // Specified Restrictions Period Multiplier @@ -2964,6 +2965,7 @@ struct XSymbolTradeConfig maxAllowedSpread = 25; maxAllowedPositions = 5; closeAllOpenTradesAt = ""; + isForceCloseAtTime = false; restrictionsPeriod = XTRADE_RESTRICATION_NONE; // diff --git a/XOM1EA/Classes/xom1ea.expert.class.mq5 b/XOM1EA/Classes/xom1ea.expert.class.mq5 index 6cc7a96c..a4521836 100644 --- a/XOM1EA/Classes/xom1ea.expert.class.mq5 +++ b/XOM1EA/Classes/xom1ea.expert.class.mq5 @@ -668,6 +668,14 @@ class XCXOM1EAExpert : public XCBase */ void HandleOnTick() { + // + // Time Report ... + HandleTimeReport(); + + // + // Manage Trades ... + eaTradeManager.Manage(); + // int count = ArraySize(eaSignallers); bool has = IsValidSize(count); @@ -684,6 +692,10 @@ class XCXOM1EAExpert : public XCBase // Calling Process Ticks on Signaller ... eaSignallers[i].ProcessTick(0); } + + // + // Guard Implememnting ... + // TODO: Implement this ... } /**