diff --git a/Classes/x-saherelm.x-trade-manager.class.mq5 b/Classes/x-saherelm.x-trade-manager.class.mq5 index 980e5360..32ea0a25 100644 --- a/Classes/x-saherelm.x-trade-manager.class.mq5 +++ b/Classes/x-saherelm.x-trade-manager.class.mq5 @@ -24,6 +24,7 @@ #include "../Classes/x-saherelm.x-alert.class.mq5" #include "../Classes/x-saherelm.x-data.collector.class.mq5" #include "../Classes/x-saherelm.x-guard.class.mq5" +#include "../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../Classes/x-saherelm.x-trade.class.mq5" // @@ -41,6 +42,9 @@ class XCTradeManager : public XCBase XTimeTracker timeTracker; XCDataCollector *collector; + // + XCPOIDrawer *drawer; + // // Constructor ... XCTradeManager( @@ -54,6 +58,9 @@ class XCTradeManager : public XCBase guard = _guard; trader = _trader; + // + drawer = new XCPOIDrawer(); + // allowTrade = true; allowLongs = true; @@ -104,6 +111,10 @@ class XCTradeManager : public XCBase ZeroMemory(alert); ZeroMemory(trader); + // + delete drawer; + ZeroMemory(drawer); + // delete collector; ZeroMemory(collector); @@ -851,10 +862,7 @@ class XCTradeManager : public XCBase * * @return ( bool ) */ - bool Execute( - XSignal &signal, - string conditions // - ) + bool Execute(XSignal &signal) { // bool result = false; @@ -921,26 +929,6 @@ class XCTradeManager : public XCBase // if (result) { - // - // Draw Signal ... - // if (drawSignal) - // { - // // - // XCSignalObject *iObj; - // isExists = drawer.DrawSignal( - // signal, - // iObj // - // ); - - // // - // if (isExists) - // { - // // - // mObjects.Add(iObj); - // ZeroMemory(iObj); - // } - // } - // // Create Symbol Info Struct ... XTradeSymbolInfo iSymbolInfo; @@ -986,11 +974,11 @@ class XCTradeManager : public XCBase // iTrade.signal = signal; - iTrade.conditions = conditions; iTrade.positionID = positionID; iTrade.commission = commission; iTrade.signaledAt = signal.time; iTrade.executedAt = TimeCurrent(); + iTrade.conditions = signal.conditions; // AddRef( @@ -1054,6 +1042,45 @@ class XCTradeManager : public XCBase return result; } + /** + * Handle Signal Recieved ... + * + * @param signal: XSignal + */ + void HandleSignal(XSignal &signal) + { + // + // Validate Signal ... + if (!signal.IsValid()) + { + return; + } + + // + // Check Signal ... + ENUM_X_SIGNAL_EXECUTION_RESULT signalExecutionResult; + bool canExecute = CheckSignal( + signal, + signalExecutionResult // + ); + if (canExecute) { + bool isExecuted = Execute(signal); + } + + // + // Draw Signal Object ... + XCSignalObject *signalObj; + bool has = drawer.DrawSignal( + signal, + signalObj, + 4 // + ); + if (has) + { + mObjects.Add(signalObj); + } + } + /** * Handle Position Take Profit ... * @@ -2169,6 +2196,9 @@ class XCTradeManager : public XCBase // // Props ... + // + CArrayObj mObjects; + // bool allowTrade; bool allowLongs; diff --git a/Documents/BKP/tmp-trade_symbol.info.mq5 b/Documents/BKP/tmp-trade_symbol.info.mq5 new file mode 100644 index 00000000..c60afe97 --- /dev/null +++ b/Documents/BKP/tmp-trade_symbol.info.mq5 @@ -0,0 +1,143 @@ +` +// +// an Structure for Holds an Specified Symbols +// Positions Info ... +struct XTradeSymbolInfo +{ + // + // Properties ... + + // + string symbol; // Trading Symbol + + // + int longs; // All Long Trades + int shorts; // All Short Trades + + // + int trades; // All Trades + + // + int losses; // All Loosing Trades + int profits; // All Winning Trades + + // + datetime managedStart; // Managed Start Time + + // + int managedSLs; // Managed SL(s) + int managedTPs; // Managed TP(s) + int managedTrades; // Managed Trades + + // + double managedBalance; // Managed Start Balance + double managedProfits; // Managed Profit(s) + + // + // Constructor ... + XTradeSymbolInfo() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + + // + longs = 0; + shorts = 0; + + // + trades = 0; + + // + losses = 0; + profits = 0; + + // + managedStart = NULL; + + // + managedSLs = 0; + managedTPs = 0; + managedTrades = 0; + + // + managedBalance = 0; + managedProfits = 0; + + // + ZeroMemory(this); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = IsSpecifiedValid(symbol); + + // + return result; + } + + // + bool IsSameAs(XTradeSymbolInfo &item) + { + // + bool result = false; + + // + result = IsValid() && + item.IsValid() && + symbol == item.symbol; + + // + return result; + } + + // + string GetRestrictionDescription( + ENUM_XTRADE_RESTRICTION_PERIOD period // + ) + { + // + string result = NULL; + + // + if (!IsValid() || + !HasRestrictions(period)) + { + return result; + } + + // + result += + "-------------------" + "\n" + + "Restrictions: " + "\n" + + "-------------------" + "\n" + + "Symbol: " + ToXString(symbol) + "\n" + + "Period: " + ToXString(period) + "\n" + + "Start: " + ToFormatString(managedStart) + "\n" + + "Balance: " + ToXString(managedBalance) + "\n" + + "-------------------" + "\n" + + "Trades: " + ToXString(managedTrades) + "\n" + + "SL: " + ToXString(managedSLs) + "\n" + + "TP: " + ToXString(managedTPs) + "\n" + + "Profit: " + ToXString(managedProfits) + "\n" + + ""; + + // + return result; + } +}; diff --git a/Experts/x-saherelm.xom1.ea.mq5 b/Experts/x-saherelm.xom1.ea.mq5 index 86d4d859..bb5ac6ba 100644 --- a/Experts/x-saherelm.xom1.ea.mq5 +++ b/Experts/x-saherelm.xom1.ea.mq5 @@ -35,6 +35,11 @@ input long eaMagicNumber = 1694056; // Magic Number input int eaSlippage = 10; // Slippgae input string eaLogSuffix = ""; // Log Suffix +// +// Symbols +// [Symbol|period|(ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00)] +input string eaSymbolConfiguration; // Symbol Configurations + // // Management ... // eaSessions => (ST_04:00_08:30),(TL_10:30_12:00),(NY_16:00_20:00) @@ -140,6 +145,10 @@ int OnInit() // // Setting All Inputs to Expert Adviser Class ... + // + // Symbols ... + eaExpert.eaSymbolConfiguration = eaSymbolConfiguration; + // // Management ... eaExpert.eaAllowGuards = eaAllowGuards; @@ -197,6 +206,7 @@ int OnInit() // // Attach Event Handlers ... + eaExpert.AddOnSignalEventHandler(OnSignalTriggered); eaExpert.AddOnDealsChangedEventHandler(OnDealsChanged); eaExpert.AddOnStopLossEventHandler(OnStopLossTriggered); eaExpert.AddOnOrdersChangedEventHandler(OnOrdersChanged); @@ -283,6 +293,16 @@ void OnChartEvent( // // Event Listeners ... +/** + * Trigger OnSignal Event ... + * + * @param signal: XSignal + */ +void OnSignalTriggered(XSignal &signal) +{ + eaExpert.HandleOnSignalTriggered(signal); +} + /** * Handle StopLoss Triggered Positions ... * diff --git a/Libraries/x-saherelm.x-trade.lib.mq5 b/Libraries/x-saherelm.x-trade.lib.mq5 index 480dc2ba..f8c20d2b 100644 --- a/Libraries/x-saherelm.x-trade.lib.mq5 +++ b/Libraries/x-saherelm.x-trade.lib.mq5 @@ -2702,149 +2702,6 @@ struct XOnTradeHandlerState } }; -// -// an Structure for Holds an Specified Symbols -// Positions Info ... -struct XTradeSymbolInfo -{ - // - // Properties ... - - // - string symbol; // Trading Symbol - - // - int longs; // All Long Trades - int shorts; // All Short Trades - - // - int trades; // All Trades - - // - int losses; // All Loosing Trades - int profits; // All Winning Trades - - // - datetime managedStart; // Managed Start Time - - // - int managedSLs; // Managed SL(s) - int managedTPs; // Managed TP(s) - int managedTrades; // Managed Trades - - // - double managedBalance; // Managed Start Balance - double managedProfits; // Managed Profit(s) - - // - // Constructor ... - XTradeSymbolInfo() - { - Clean(); - } - - // - // Tools ... - - // - // Cleanup ... - void Clean() - { - // - symbol = NULL; - - // - longs = 0; - shorts = 0; - - // - trades = 0; - - // - losses = 0; - profits = 0; - - // - managedStart = NULL; - - // - managedSLs = 0; - managedTPs = 0; - managedTrades = 0; - - // - managedBalance = 0; - managedProfits = 0; - - // - ZeroMemory(this); - } - - // - // Validate ... - bool IsValid() - { - // - bool result = false; - - // - result = IsSpecifiedValid(symbol); - - // - return result; - } - - // - bool IsSameAs(XTradeSymbolInfo &item) - { - // - bool result = false; - - // - result = IsValid() && - item.IsValid() && - symbol == item.symbol; - - // - return result; - } - - // - string GetRestrictionDescription( - ENUM_XTRADE_RESTRICTION_PERIOD period // - ) - { - // - string result = NULL; - - // - if (!IsValid() || - !HasRestrictions(period)) - { - return result; - } - - // - result += - "-------------------" + "\n" + - "Restrictions: " + "\n" + - "-------------------" + "\n" + - "Symbol: " + ToXString(symbol) + "\n" + - "Period: " + ToXString(period) + "\n" + - "Start: " + ToFormatString(managedStart) + "\n" + - "Balance: " + ToXString(managedBalance) + "\n" + - "-------------------" + "\n" + - "Trades: " + ToXString(managedTrades) + "\n" + - "SL: " + ToXString(managedSLs) + "\n" + - "TP: " + ToXString(managedTPs) + "\n" + - "Profit: " + ToXString(managedProfits) + "\n" + - ""; - - // - return result; - } -}; - // // an Structure for Describe aTrading Session ... struct XTradeSession @@ -2929,18 +2786,37 @@ struct XTradeSession // // an Structure for Describe an Specified Symbols // Trading Sessions ... -struct XSymbolSessions +struct XSymbolTradeConfig { // // Propeties ... // - string symbol; // Trading Symbol - XTradeSession sessions[]; // Trading Sessions + int longs; // All Long Trades + int shorts; // All Short Trades + int trades; // All Trades + int losses; // All Loosing Trades + int profits; // All Winning Trades + string symbol; // Trading Symbol + int managedSLs; // Managed SL(s) + int managedTPs; // Managed TP(s) + int managedTrades; // Managed Trades + int maxAllowedTPs; // Max Allowed TP(s) in Restrictions Period + int maxAllowedSLs; // Max Allowed SL(s) in Restrictions Period + int maxAllowedTrades; // Max Allowed Trades in Restrictions Period + datetime managedStart; // Managed Start Time + double managedBalance; // Managed Start Balance + double managedProfits; // Managed Profit(s) + ENUM_TIMEFRAMES period; // Trading Period + int maxAllowedPositions; // Max Allowed Same Time Trades + double maxAllowedSpread; // Max Allowed Spread For Trade + XTradeSession sessions[]; // Trading Sessions + string closeAllOpenTradesAt; // Close All Open Trades per Day At Specified Time + ENUM_XTRADE_RESTRICTION_PERIOD restrictionsPeriod; // Trade Restrictions Period // // Constructor ... - XSymbolSessions() + XSymbolTradeConfig() { Clean(); } @@ -2954,12 +2830,84 @@ struct XSymbolSessions { // symbol = NULL; + period = NULL; SpecifiedClean(sessions); + // + longs = 0; + shorts = 0; + trades = 0; + losses = 0; + profits = 0; + + // + managedStart = NULL; + + // + managedSLs = 0; + managedTPs = 0; + managedTrades = 0; + + // + managedBalance = 0; + managedProfits = 0; + + // + maxAllowedTPs = 0; + maxAllowedSLs = 0; + maxAllowedTrades = 0; + maxAllowedSpread = 25; + maxAllowedPositions = 5; + closeAllOpenTradesAt = ""; + restrictionsPeriod = XTRADE_RESTRICATION_NONE; + // ZeroMemory(this); } + // + // Initial ... + bool Init( + string _symbol = NULL, + ENUM_TIMEFRAMES _period = NULL, + string _sessionsDescriptor = NULL, + double _maxAllowedSpread = 25, + int _maxAllowedPositions = 5, + string _closeAllOpenTradesAt = NULL, + int _maxAllowedTPs = 0, + int _maxAllowedSLs = 0, + ENUM_XTRADE_RESTRICTION_PERIOD _restrictionsPeriod = XTRADE_RESTRICATION_NONE // + ) + { + // + bool result = false; + + // + // Normalize Symbol ... + _symbol = NormalizeSymbol(_symbol); + _period = NormalizePeriod(_period); + + // + symbol = _symbol; + period = _period; + maxAllowedTPs = _maxAllowedTPs; + maxAllowedSLs = _maxAllowedSLs; + maxAllowedSpread = _maxAllowedSpread; + restrictionsPeriod = _restrictionsPeriod; + maxAllowedPositions = _maxAllowedPositions; + closeAllOpenTradesAt = _closeAllOpenTradesAt; + + // + // Parse Sessions ... + ParseSessions(_sessionsDescriptor); + + // + result = IsValid(); + + // + return result; + } + // // Validate ... bool IsValid() @@ -3019,6 +2967,96 @@ struct XSymbolSessions return result; } + // + // Parse Sessions ... + void ParseSessions(string descriptor) + { + // + if (!IsSpecifiedValid(descriptor)) + { + return; + } + + // + bool has = false; + string _sessions[]; + int sessionsCount = 0; + + // + // Extract Per Symbol Sessions ... + sessionsCount = SplitContent( + _sessions, + descriptor, + "," // + ); + + // + // Try to Extract Start and End Times Series ... + has = IsValidSize(sessionsCount); + if (!has) + { + return; + } + + // + // Iterate Sessions ... + for (int i = 0; i < sessionsCount; i++) + { + // + // Ignore unused Cases and Extracts only Content ... + string iSessionDescriptorStr = ExtractString(_sessions[i]); + has = IsSpecifiedValid(iSessionDescriptorStr); + if (has) + { + // + // Extract Session Descriptor Data ... + string parts[]; + int partsCount = SplitContent( + parts, + iSessionDescriptorStr, + "_" // + ); + has = IsValidSize(partsCount) && partsCount == 3; + if (has) + { + // + string iName = parts[0]; + string iStart = parts[1]; + string iEnd = parts[2]; + has = IsSpecifiedValid(iName) && + IsSpecifiedValid(iStart) && + IsSpecifiedValid(iEnd); + if (has) + { + // + // Set Active Session Per Symbols ... + XTradeSession session; + + // + session.end = iEnd; + session.name = iName; + session.start = iStart; + + // + AddRef( + session, + sessions // + ); + + // + session.Clean(); + } + } + + // + SpecifiedClean(parts); + } + } + + // + SpecifiedClean(_sessions); + } + // }; diff --git a/XOM1EA/Classes/xom1ea.expert.class.mq5 b/XOM1EA/Classes/xom1ea.expert.class.mq5 index e42e1e6c..a8183d1a 100644 --- a/XOM1EA/Classes/xom1ea.expert.class.mq5 +++ b/XOM1EA/Classes/xom1ea.expert.class.mq5 @@ -48,6 +48,10 @@ class XCXOM1EAExpert : public XCBase int eaSlippage; // Slippgae string eaLogSuffix; // Log Suffix + // + // Symbol Configurations ... + string eaSymbolConfiguration; // Symbol Configurations ... + // // Management ... bool eaAllowGuards; // Allow Guards @@ -94,7 +98,7 @@ class XCXOM1EAExpert : public XCBase bool eaReportProtector; // Report Protector Actions bool eaReportRestrictions; // Report Restrictions bool eaReportAfterTradesBalance; // Report Balance after a Trade Finished - + // // Collector ... bool eaSaveTrades; // Save Trades @@ -117,6 +121,25 @@ class XCXOM1EAExpert : public XCBase // // Tools / Actions / Handlers ... + // + // Signal Event Handlers ... + + // + void AddOnSignalEventHandler(TOnSignal handler) + { + // + if (handler == NULL) + { + return; + } + + // + Add( + handler, + mOnSignalEventHandlers // + ); + } + // // Trade Event Handlers ... @@ -463,7 +486,7 @@ class XCXOM1EAExpert : public XCBase eaTrade.AddOnTradeStateChangedEventHandler(mTradeStateChangedEventHandlers[i]); } } - + // // Postion Partially Close Event Handlers ... count = ArraySize(mOnPartialCloseEventHandlers); @@ -536,6 +559,28 @@ class XCXOM1EAExpert : public XCBase eaMaxAllowedTrades // ); + // + // Parse Symbols ... + string symbols[]; + ENUM_TIMEFRAMES periods[]; + if (!IsSpecifiedValid(eaSymbolConfiguration)) + { + // + Add( + _Symbol, + symbols // + ); + + // + Add( + _Period, + periods // + ); + } + else + { + } + // // Here we Apply Symbols,Periods and Configs ... @@ -552,7 +597,12 @@ class XCXOM1EAExpert : public XCBase // // Make Instance Signaller Class ... + + // XCXOM1SignallerBase *iDZoneSignaller = NULL; + + // + // Define Signaller ... iDZoneSignaller = new XCXOM1SignallerBase( "XDZN", "XAUUSDb", @@ -561,6 +611,19 @@ class XCXOM1EAExpert : public XCBase iDZoneSignallerConfig); if (iDZoneSignaller != NULL) { + // + // Attach Signaller OnSignal Event Handlers ... + count = ArraySize(mOnSignalEventHandlers); + has = IsValidSize(count); + if (has) + { + // + for (int i = 0; i < count; i++) + { + iDZoneSignaller.AddOnSignalEventHandler(mOnSignalEventHandlers[i]); + } + } + // // Register Signaller ... Add( @@ -671,6 +734,13 @@ class XCXOM1EAExpert : public XCBase { } + // + // Signal Event Handler ... + void HandleOnSignalTriggered(XSignal &signal) + { + eaTradeManager.HandleSignal(signal); + } + // // Trade Event Handlers ... @@ -870,6 +940,9 @@ class XCXOM1EAExpert : public XCBase TOnPositionsChanged mPositionsChangedEventHandlers[]; TOnTradeStateChanged mTradeStateChangedEventHandlers[]; + // + TOnSignal mOnSignalEventHandlers[]; // Signal Recieved Event Handlers ... + // XCXOM1SignallerBase *eaSignallers[]; // All Registered Signallers ... }; diff --git a/XOM1EA/Classes/xom1ea.signaller.class.mq5 b/XOM1EA/Classes/xom1ea.signaller.class.mq5 index 7772bd12..b07c309d 100644 --- a/XOM1EA/Classes/xom1ea.signaller.class.mq5 +++ b/XOM1EA/Classes/xom1ea.signaller.class.mq5 @@ -145,6 +145,44 @@ class XCXOM1SignallerBase ZeroMemory(mHelper); } + // + // Signal Event Handlers ... + + // + void AddOnSignalEventHandler(TOnSignal handler) + { + // + if (handler == NULL) + { + return; + } + + // + Add( + handler, + mOnSignalEventHandlers // + ); + } + + // + void NotifyOnSignalEvent(XSignal &signal) + { + // + int count = ArraySize(mOnSignalEventHandlers); + bool has = IsValidSize(count) && signal.IsValid(); + if (!has) + { + return; + } + + // + // Calling Event Handlers ... + for (int i = 0; i < count; i++) + { + mOnSignalEventHandlers[i](signal); + } + } + // // Actions ... @@ -329,7 +367,7 @@ class XCXOM1SignallerBase iDir, iReason, iConditions.bars[pIdx].time, // From ... - iConditions.bars[cIdx].time // To + iConditions.bars[zIdx].time // To ); if (has) { @@ -339,6 +377,10 @@ class XCXOM1SignallerBase iZone, zones // ); + + // + // Prepare Signal ... + PrepareSignal(iZone); } // @@ -379,6 +421,10 @@ class XCXOM1SignallerBase double iUpper = GetMax(iValues); double iLower = GetMin(iValues); + // + double iZoneUpper = MathMax(iFibUpper, iFibLower); + double iZoneLower = MathMin(iFibUpper, iFibLower); + // has = isFastCrossedOverSlow || isFastCrossedUnderSlow; @@ -386,10 +432,6 @@ class XCXOM1SignallerBase // Validate Cross Between Zone ... if (has) { - // - double iZoneUpper = MathMax(iFibUpper, iFibLower); - double iZoneLower = MathMin(iFibUpper, iFibLower); - // // Validate MA Place ... has = iFast >= iZoneLower && @@ -471,13 +513,13 @@ class XCXOM1SignallerBase symbol, period, name, // Signaller Name ... - iUpper, - iLower, + iZoneUpper, + iZoneLower, iPrice, iDir, iReason, iConditions.bars[pIdx].time, // From ... - iConditions.bars[cIdx].time // To + iConditions.bars[zIdx].time // To ); if (has) { @@ -487,6 +529,10 @@ class XCXOM1SignallerBase iZone, zones // ); + + // + // Prepare Signal ... + PrepareSignal(iZone); } // @@ -518,6 +564,9 @@ class XCXOM1SignallerBase // XCXOM1Helper *mHelper; // Indicator Helper ... + // + TOnSignal mOnSignalEventHandlers[]; // Signal Recieved Event Handlers ... + // int mProcessedTicksCount; // Prcoessed Ticks Count ... datetime mLastCheckedBarTime; // Last Checked Bar Time ... @@ -551,12 +600,12 @@ class XCXOM1SignallerBase // zones[i].UpdateByBarIndex(barIndex); // - drawer.DrawZone( - zones[i], - true, // Draw Price ... - true, // Draw Middle ... - true // Draw From ... - ); + // drawer.DrawZone( + // zones[i], + // true, // Draw Price ... + // true, // Draw Middle ... + // true // Draw From ... + // ); } } @@ -588,6 +637,75 @@ class XCXOM1SignallerBase // } } + + /** + * Converts iZone to Signal and Notify Signal ... + * + * @param iZone: XOM1Zone + */ + void PrepareSignal(XOM1Zone &zone) + { + // + // Validate Zone ... + if (!zone.IsValid()) + { + return; + } + + // + // Create Signal ... + XSignal signal; + + // + signal.time = zone.to; + signal.provider = name; + signal.symbol = zone.symbol; + signal.period = zone.period; + signal.mode = X_ORDER_MODE_MARKET; + signal.conditions = "XConditions"; + signal.comment = ToXString(zone.reason); + signal.type = zone.IsBullish() + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + // Get Entry ... + signal.entry = GetXEntry(zone.symbol, zone.dir); + + // + // Calculate SL ... + double providedSL = zone.IsBullish() + ? zone.lower + : zone.upper; + signal.sl = providedSL; + + // + // Calculate Risk ... + double risk = MathAbs(signal.entry - signal.sl); + + // + // Calculate Reward ... + double r2r = 2; + double reward = risk * r2r; + + // + // Calculate TP ... + double providedTP = zone.IsBullish() + ? signal.entry + reward + : signal.entry - reward; + signal.tp = providedTP; + + // + // Calculate Targets ... + // TODO: Handle this ... + + // + // Set Min Volume ... + signal.volume = 0.01; + + // + NotifyOnSignalEvent(signal); + } }; // \ No newline at end of file