//////////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 XEMPTY5 Signal Provider Library // -------------------------------------------------------- // Name: XEMPTY5SignalProvider // Description: XEMPTY5 based signal provider ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict #define XEMPTY5ProviderName "XEMPTY5" // // START Inputs ... // #include "x-saherelm.xempty5.provider.inputs.lib.mq5"; // // END Inputs ... // // // Include Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5" // // Include Logger Library ... #include "../Libraries/x-saherelm.log.lib.mq5" // // Include Alert Library ... #include "../Libraries/x-saherelm.alert.lib.mq5" // // Include Draw Library ... #include "../Libraries/x-saherelm.draw.lib.mq5" // // Include Class Libraries ... #include "../Classes/x-saherelm.class.lib.mq5" // // START Global Definitions: Variables, Properties and etc ... // // XCGuard *xEMPTY5Guard; XCTrade *xEMPTY5Trader; XCReporter *xEMPTY5Reporter; XCCollector *xEMPTY5Collector; XCAccountInfo *xEMPTY5AccountInfo; XCVolumeManager *xEMPTY5VolumeManager; // #include "x-saherelm.xempty5.provider.indicators.lib.mq5" // // Controlling Variables ... bool xEMPTY5MEnableProvider = false; bool xEMPTY5MAllowLongTrades = false; bool xEMPTY5MAllowShortTrades = false; // double xEMPTY5Deposit = 0; double xEMPTY5Balance = 0; double xEMPTY5MinReward = 0; double xEMPTY5FreeMargin = 0; double xEMPTY5BalanceForOpenTrades = 0; double xEMPTY5FreeMarginForOpenTrades = 0; // // Guard ... double xEMPTY5CriticalDrawDown = 0; double xEMPTY5MaxAllowedDrawDown = 0; // double xEMPTY5MaxDrawUp = 0; double xEMPTY5MaxDrawDown = 0; // int NOT_ENOUGH_MONEY_ERROR = 4756; const string XEMPTY5_SUPPORT_ID = "SP"; // // END Global Definitions: Variables, Properties and etc ... // // // START Provided Functions ... // // // Initial Library if required ... bool XEMPTY5InitSignalProviderLibrary() { // bool result = false; // if (!xEMPTY5EnableProvider) { return result; } // // Controlling Variables ... xEMPTY5MEnableProvider = xEMPTY5EnableProvider; xEMPTY5MAllowLongTrades = xEMPTY5AllowLongTrades; xEMPTY5MAllowShortTrades = xEMPTY5AllowShortTrades; // // Validate Inputs ... result = XEMPTY5ValidateInputs(); if (!result) { return result; } // // Init Indicators ... result = XEMPTY5InitIndicators(); if (!result) { return result; } // xEMPTY5Reporter = new XCReporter(); xEMPTY5Collector = new XCCollector(); xEMPTY5AccountInfo = new XCAccountInfo(); // // Calculate Account Deposit ... xEMPTY5Deposit = xEMPTY5AccountInfo.GetInitialBalance(); // // Prepare Min Reward ... if (xEMPTY5MinRewardInPips > 0) { xEMPTY5MinReward = PipsToPrice(xEMPTY5MinRewardInPips); } // // Calculate Min Balance for Trades ... if (xEMPTY5BalanceFactorForOpenTrades > 0) { xEMPTY5BalanceForOpenTrades = xEMPTY5BalanceFactorForOpenTrades * xEMPTY5Deposit; } // // Claculate Min Free Marging for Trades ... if (xEMPTY5FreeMarginFactorForOpenTrades > 0) { xEMPTY5FreeMarginForOpenTrades = xEMPTY5FreeMarginFactorForOpenTrades * xEMPTY5Deposit; } // // Calculate Init Time Critical DrawDown Value ... if (xEMPTY5CriticalDrawDownFactor > 0) { xEMPTY5CriticalDrawDown = xEMPTY5CriticalDrawDownFactor * xEMPTY5Deposit; } // // Calculate Init Time Max Allowed DrawDown Value ... if (xEMPTY5MaxAllowedDrawDownFactor > 0) { xEMPTY5MaxAllowedDrawDown = xEMPTY5MaxAllowedDrawDownFactor * xEMPTY5Deposit; } // // Instant Volume Manager ... xEMPTY5VolumeManager = new XCVolumeManager( xEMPTY5StaticVolumeFactor, xEMPTY5StaticVolumeMethod, xEMPTY5VolumeMultiplier, xEMPTY5ApplyVolumeMultiplierFactor, xEMPTY5MaxSupportedVolumePerTradeFactor, xEMPTY5IncreasedMaxSupportedVolumeRate); // // Make XCTrader instance ... xEMPTY5Trader = new XCTrade( XEMPTY5ProviderName, _Symbol, xEMPTY5Slippage, xEMPTY5MagicNumber, xEMPTY5UseVirtualTPSl, xEMPTY5MaxAllowedTrades, xEMPTY5FreeMarginForOpenTrades, xEMPTY5BalanceForOpenTrades); // // Instantiate Account Guard ... xEMPTY5Guard = new XCGuard( // // Old Trades ... xEMPTY5MaxAllowedTradeAge, xEMPTY5OldTradesAction, // // Critical DrawDown ... xEMPTY5CriticalDrawDownFactor, xEMPTY5CriticalGuardAction, // // Max Allowed DrawDown ... xEMPTY5MaxAllowedDrawDownFactor, xEMPTY5MaxAllowedGuardAction, xEMPTY5GuardStopoutFiredAfterTouches, // // xEMPTY5GuardSupportMethod X_SUPPORT_DO_NOTHING // ); // // Reset Calculations Buffers and Variables ... XEMPTY5ResetCollectors(); // XEMPTY5UpdateReports(); // result = true; // // Logging State ... XEMPTY5IssueInitializationSucceedAlert(); // return result; } // // DeInitial Library if required ... void XEMPTY5DeinitSignalProviderLibrary(const int reason) { // // Release Handlers ... XEMPTY5ReleaseIndicators(); // // Logging State ... XEMPTY5IssueDeinitializationSucceedAlert(); } // // this is a Globally Function which do all of // checkings and positions handling ... void XEMPTY5SignalProviderHandleTick() { // // Check Provider is Enable or Not ... if (!xEMPTY5MEnableProvider) { return; } // XEMPTY5SignalProviderDoControlState(); // // Reading Indicator Buffers ... XEMPTY5HandleReadingBuffers(); if (xEMPTY5CalculatedBars < xEMPTY5MaxLengthOfInputs) { return; } // // Handle Open Trades ... XEMPTY5HandleOpenTrades(); // // Handle Close Trades ... XEMPTY5HandleCloseTrades(); // // DrawDown and DrawUp ... XEMPTY5HandleCalculateDrawDownUp(); } // // Do Control Checks here ... void XEMPTY5SignalProviderDoControlState() { // // Update account Balance ... xEMPTY5Balance = xEMPTY5AccountInfo.GetBalance(); xEMPTY5FreeMargin = xEMPTY5AccountInfo.GetFreeMargin(); // // Check Provider is Enable or Not ... if (!xEMPTY5MEnableProvider) { return; } // // Protect Account by Guarding Maximum Drawdown ... // TODO: add Guard Result here ... string guardMessage = ""; XGuardHandlerResult guardHandlerResult; bool isGuarded = xEMPTY5Guard.Guard( guardHandlerResult, guardMessage, xEMPTY5Trader, _Period); if (isGuarded) { // // Criticals ... int criticalsCount = ArraySize(guardHandlerResult.criticals); if (criticalsCount > 0) { // for (int i = 0; i < criticalsCount; i++) { // XSignal iSignal = guardHandlerResult.criticals[i]; // XEMPTY5OnGuard( iSignal, X_GUARDED_CRITICAL, guardMessage); } } // // Maxes ... int maxesCount = ArraySize(guardHandlerResult.maxes); if (maxesCount > 0) { // for (int i = 0; i < maxesCount; i++) { // XSignal iSignal = guardHandlerResult.maxes[i]; // XEMPTY5OnGuard( iSignal, X_GUARDED_MAX, guardMessage, guardHandlerResult.isStopOut); } } // // Olds ... int oldsCount = ArraySize(guardHandlerResult.olds); if (oldsCount > 0) { // for (int i = 0; i < oldsCount; i++) { // XSignal iSignal = guardHandlerResult.olds[i]; // XEMPTY5OnGuard( iSignal, X_GUARDED_OLD, guardMessage); } } } // // Signal Protection ... XSignal protectSupports[]; bool isSupported = xEMPTY5Guard.ProtectSignals( protectSupports, xEMPTY5Trader); if (isSupported) { // LogMessage("Guard do Support Trdae ..."); } // // Handling Signals ... XTraderHandlerResult signalHandlerResult; xEMPTY5Trader.HandleSignals( signalHandlerResult, false // Ignore Risk Free Trdaes ); // // Handle Sl Reports ... int handledSLsCount = ArraySize(signalHandlerResult.sl); if (handledSLsCount > 0) { // for (int i = 0; i < handledSLsCount; i++) { // XSignal iSignal = signalHandlerResult.sl[i]; XEMPTY5OnSL(iSignal); } } // // Handle TP Reports ... int handledTPsCount = ArraySize(signalHandlerResult.tp); if (handledTPsCount > 0) { // for (int i = 0; i < handledTPsCount; i++) { // XSignal iSignal = signalHandlerResult.tp[i]; XEMPTY5OnTP(iSignal); } } // // Handle RFs as TP Reports ... int handledRFsCount = ArraySize(signalHandlerResult.rf); if (handledRFsCount > 0) { // for (int i = 0; i < handledRFsCount; i++) { // XSignal iSignal = signalHandlerResult.rf[i]; XEMPTY5OnRF(iSignal); } } } // // Handle Trades when OnTrade Event Hnadler Calls ... void XEMPTY5SignalProviderHandleTrade() { // // Check Provider Enabled ... if (!xEMPTY5MEnableProvider) { return; } // // Handle OnTrade Event ... XOnTradeHandlerResult result = {}; xEMPTY5Trader.HandleOnTradeEvent( result); // // Detected TP or SL ... if (result.hasNewDeal) { // XDeal last = xEMPTY5Trader.GetLastDeal(); // if (last.reason == DEAL_REASON_SL) { xEMPTY5Reporter.AddTradeSLInReports(); } else if (last.reason == DEAL_REASON_TP) { xEMPTY5Reporter.AddTradeTPInReports(); } } } // // Handle Open Trades ... void XEMPTY5HandleOpenTrades() { // // Check Can Trade ... bool canTrade = xEMPTY5MAllowLongTrades || xEMPTY5MAllowShortTrades; if (!canTrade) { return; } // // Check Max Open Trades ... int openSignals = xEMPTY5Trader.Count(); bool canOpenPositions = openSignals < xEMPTY5MaxAllowedTrades; if (!canOpenPositions) { return; } // // Check Signals Exists ... XProvidedSignal longSignalInfo; XProvidedSignal shortSignalInfo; bool hasLongSignal = XEMPTY5CanOpenLongTrade(longSignalInfo); bool hasShortSignal = XEMPTY5CanOpenShortTrade(shortSignalInfo); if (!hasLongSignal && !hasShortSignal) { return; } // // Update Reports ... XEMPTY5UpdateReports(); // xEMPTY5WaitUntilNextCandle = true; // // Open Long Trades ... if ( // hasLongSignal && xEMPTY5MAllowLongTrades) { // bool isOpened = XEMPTY5OpenLongPosition(longSignalInfo); } // // Open Short Trades ... if ( // hasShortSignal && xEMPTY5MAllowShortTrades) { // bool isOpened = XEMPTY5OpenShortPosition(shortSignalInfo); } } // // Handle Close Trades ... void XEMPTY5HandleCloseTrades() { // // Force Close Long Trades ... bool isClosedLongTrades = false; bool canCloseLongTrades = XEMPTY5CanCloseLongTrade(); if (xEMPTY5MAllowLongTrades && canCloseLongTrades) { // ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG; // XSignal closed[]; xEMPTY5Trader.CloseSignals( closed, type); // int closedTradesCount = ArraySize(closed); isClosedLongTrades = closedTradesCount > 0; if (isClosedLongTrades) { // for (int i = 0; i < closedTradesCount; i++) { // XSignal iSignal = closed[i]; XEMPTY5OnFC(iSignal); } } } // // Force Close Short Trades ... bool isClosedShortTrades = false; bool canCloseShortTrades = XEMPTY5CanCloseShortTrade(); if (xEMPTY5MAllowShortTrades && canCloseShortTrades) { // ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT; // XSignal closed[]; xEMPTY5Trader.CloseSignals( closed, type); // int closedTradesCount = ArraySize(closed); isClosedShortTrades = closedTradesCount > 0; if (isClosedShortTrades) { // for (int i = 0; i < closedTradesCount; i++) { // XSignal iSignal = closed[i]; XEMPTY5OnFC(iSignal); } } } } // // Open Long Position ... bool XEMPTY5OpenLongPosition( XProvidedSignal &info // Retrieve Signal Additional Info on this Object ) { // bool result = false; // // Calculate Required Data for Position ... double entry = GetEntry(_Symbol, X_SIGNAL_LONG); double sl = info.sl > 0 ? info.sl : 0; // entry - (200 * _Point); // info.sl > 0 ? info.sl : 0; double tp = info.tp > 0 ? info.tp : entry + xEMPTY5MinReward; double riskFreeRate = xEMPTY5RiskFreeRate; double riskFreeStep = xEMPTY5RiskFreeStepInPips; double volume = XEMPTY5CalculateVolume(ArraySize(info.signallers)); // XSignal signal = {}; signal = xEMPTY5Trader.GenerateSignal( X_SIGNAL_LONG, tp, sl, volume, riskFreeStep, riskFreeRate); bool isValidSignal = IsValid( signal, xEMPTY5MagicNumber); if (!isValidSignal) { return result; } // int signalsCount = xEMPTY5Trader.Count(); bool isCross = signalsCount >= 1; if (isCross) { // // Handle Cross Signals ... XEMPTY5HnadleCrossSignal(signal); } // // Retrieve Can Execute Signal or not ... bool canExecuteSignal = !isCross // || // ( // isCross && xEMPTY5CrossSignalsMethod != X_CROSS_SIGNAL_DO_NOTHING // ); if (!canExecuteSignal) { return result; } // // Execute Signal ... ENUM_EXECUTION_SIGNAL_RESULT executionResult = xEMPTY5Trader.ExecuteSignal( signal, false, // Ignore Number of Trades ... true // Check Account Conditions ... ); result = executionResult == X_TRADER_SUCCEED_EXECUTION; if (result) { // // Update Reports ... string providers[]; ArrayCopy( providers, info.signallers ); // XSignal tSignal = xEMPTY5Trader.GetSignal(signal.ticket); // XEMPTY5OnSignal( tSignal, providers); } else { XEMPTY5IssueSignalExecutionError(executionResult); } // return result; } // // Open Short Position ... bool XEMPTY5OpenShortPosition( XProvidedSignal &info // Retrieve Signal Additional Info on this Object ) { // bool result = false; // // Calculate Required Data for Position ... double entry = GetEntry(_Symbol, X_SIGNAL_SHORT); double sl = info.sl > 0 ? info.sl : 0; // entry + (200 * _Point); // info.sl > 0 ? info.sl : 0; double tp = info.tp > 0 ? info.tp : entry - xEMPTY5MinReward; double riskFreeRate = xEMPTY5RiskFreeRate; double riskFreeStep = xEMPTY5RiskFreeStepInPips; double volume = XEMPTY5CalculateVolume(ArraySize(info.signallers)); // XSignal signal = {}; signal = xEMPTY5Trader.GenerateSignal( X_SIGNAL_SHORT, tp, sl, volume, riskFreeStep, riskFreeRate); bool isValidSignal = IsValid( signal, xEMPTY5MagicNumber); if (!isValidSignal) { return result; } // int signalsCount = xEMPTY5Trader.Count(); bool isCross = signalsCount >= 1; if (isCross) { // // Handle Cross Signals ... XEMPTY5HnadleCrossSignal(signal); } // // Retrieve Can Execute Signal or not ... bool canExecuteSignal = !isCross // || // ( // isCross && xEMPTY5CrossSignalsMethod != X_CROSS_SIGNAL_DO_NOTHING // ); if (!canExecuteSignal) { return result; } // // Execute Signal ... ENUM_EXECUTION_SIGNAL_RESULT executionResult = xEMPTY5Trader.ExecuteSignal( signal, false, // Ignore Number of Trades ... true // Check Account Conditions ... ); result = executionResult == X_TRADER_SUCCEED_EXECUTION; if (result) { string providers[]; ArrayCopy( providers, info.signallers ); // XSignal tSignal = xEMPTY5Trader.GetSignal(signal.ticket); // XEMPTY5OnSignal( tSignal, providers); } else { XEMPTY5IssueSignalExecutionError(executionResult); } // return result; } // // Apply Cross Signal Actions ... void XEMPTY5HnadleCrossSignal( XSignal &signal // Specified Signal ... ) { // // Check Cross Signal Handling Enabled ... if (xEMPTY5CrossSignalsMethod == X_CROSS_SIGNAL_DO_NOTHING) { return; } // // First We have to Change Cross Signals Comment ... string comment = xEMPTY5Trader.GenerateSignalComment( signal, true); // signal.comment = comment; // // If Every thing is Regular, prevent any changes here ... if (xEMPTY5CrossSignalsMethod == X_CROSS_SIGNAL_REGULAR) { return; } // // Retrieve Max in Drawdown Signal ... XSignal maxInDDSignal = xEMPTY5Trader.GetMaxInDrawdownSignal(); // // Validate Signal ... bool isValidSignal = maxInDDSignal.ticket > 0 && maxInDDSignal.symbol == signal.symbol && IsValid(maxInDDSignal, xEMPTY5MagicNumber); if (!isValidSignal) { return; } // double volume = signal.volume; bool isDirectional = maxInDDSignal.type == signal.type; // // Prevent any changes on Regular Conditions ... bool isRegular = isDirectional ? ( // xEMPTY5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_REGULAR || xEMPTY5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_REGULAR_INDIRECTION_IMPORTANT // ) : ( // xEMPTY5CrossSignalsMethod == X_CROSS_SIGNAL_INDIRECTION_REGULAR || xEMPTY5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_IMPORTANT_INDIRECTION_REGULAR // ); if (isRegular) { return; } // // Important Act needs to Multiply volume by 2 ... volume *= 2; // // Set Volume of signal ... signal.volume = volume; } // // Calculate Usefull data ... void XEMPTY5HandleCalculateDrawDownUp() { // XSignal signals[]; xEMPTY5Trader.GetSignals(signals); int signalsCount = ArraySize(signals); if (signalsCount <= 0) { return; } // double profit = 0; double volume = 0; XCollector collector = {}; double maxAllowedVolume = xEMPTY5VolumeManager.GetMaxAllowedVolume(); for (int i = 0; i < signalsCount; i++) { // XSignal iSignal = signals[i]; // profit += iSignal.profit; // volume = volume == 0 || volume < iSignal.volume ? iSignal.volume : volume; } // if (profit < 0) { // xEMPTY5MaxDrawDown = xEMPTY5MaxDrawDown == 0 || xEMPTY5MaxDrawDown > MathAbs(profit) ? MathAbs(profit) : xEMPTY5MaxDrawDown; // // Update Buffers ... datetime time = iTime(_Symbol, _Period, 0); // // Calculate Max Allowed Drawdown ... // collector.time = time; collector.volume = volume; collector.maxDrawDown = xEMPTY5MaxDrawDown; collector.maxAllowedVolume = maxAllowedVolume; collector.minBalanceForOpenTrade = xEMPTY5Trader.GetMinBalanceForOpenTrades(); } else { // xEMPTY5MaxDrawUp = xEMPTY5MaxDrawUp == 0 || xEMPTY5MaxDrawUp < profit ? profit : xEMPTY5MaxDrawUp; } // // Update Collector ... xEMPTY5Collector.Add(collector); // // Update Reports ... xEMPTY5Reporter.UpdateMaxDrawUpInReports(xEMPTY5MaxDrawUp); xEMPTY5Reporter.UpdateMaxDrawDownInReports(xEMPTY5MaxDrawDown); xEMPTY5Reporter.UpdateMaxSameTimeTradesInReports(signalsCount); } // // START Event Handlers ... // // // Runs When a Signal Successfully Executed ... void XEMPTY5OnSignal( XSignal &signal, // Specified Signal string &providers[] // Signal Providers ) { // // Issue Propper Alert ... XEMPTY5IssueSignalExecutionAlert( signal, providers); // // Add Signal To Supports on Guard ... xEMPTY5Guard.AddSupport(signal); // // Update Reports ... xEMPTY5Reporter.AddSignalToReports( signal, providers); } // // Runs when a Position Got Take Profit ... void XEMPTY5OnTP( XSignal &signal // Specified Signal ) { // // Issue Propper Alert ... XEMPTY5IssueTPAlert(signal); // // Remove Signal From Guard Protector ... xEMPTY5Guard.Remove(signal.ticket); xEMPTY5Guard.RemoveSupport(signal.ticket); // // Update Reports ... xEMPTY5Reporter.AddTradeTPInReports(); XEMPTY5UpdateReports(); } // // Runs when a Position Got Stop Loss ... void XEMPTY5OnSL( XSignal &signal // Specified Signal ) { // // Issue Propper Alert ... XEMPTY5IssueSLAlert(signal); // // Remove Signal From Guard Protector ... xEMPTY5Guard.Remove(signal.ticket); xEMPTY5Guard.RemoveSupport(signal.ticket); // // Update Reports ... xEMPTY5Reporter.AddTradeSLInReports(); XEMPTY5UpdateReports(); } // // Runs when a Position Risk Free ... void XEMPTY5OnRF( XSignal &signal // Specified Signal ) { // // Issue Propper Alert ... XEMPTY5IssueRFAlert(signal); // // Remove Signal From Guard Protector ... // since RiskFree Signals has SL ... xEMPTY5Guard.Remove(signal.ticket); xEMPTY5Guard.RemoveSupport(signal.ticket); // // Update Reports ... xEMPTY5Reporter.AddTradeSLInReports(); XEMPTY5UpdateReports(); } // // Runs when a Position Force Closed ... void XEMPTY5OnFC( XSignal &signal // Specified Signal ) { // // Issue Propper Alert ... XEMPTY5IssueFCAlert(signal); // // Remove Signal From Guard Protector ... xEMPTY5Guard.Remove(signal.ticket); xEMPTY5Guard.RemoveSupport(signal.ticket); // // Update Reports ... xEMPTY5Reporter.AddTradeSLInReports(); XEMPTY5UpdateReports(); } // // Runs when a Position Guarded ... void XEMPTY5OnGuard( XSignal &signal, // Specified Signal ENUM_X_GUARD_REASONS reason, // Reason of Guard Applied string message, // Guard Returned Message bool isStopOut = false // Specified StopOut Fired or not ) { // // Chekc StopOut ... if (isStopOut) { // LogMessage(message); // xEMPTY5MEnableProvider = false; } // // Issue Propper Alert ... XEMPTY5IssueGuardAlert(signal, reason, isStopOut); // // Update Reports ... xEMPTY5Reporter.AddTradeSLInReports(); XEMPTY5UpdateReports(); } // // END Event Handlers ... // // // END Provided Functions ... // // // START Private Functions ... // // // START Volume Baseed Functions ... // // // Calculating Volume for Tradings ... double XEMPTY5CalculateVolume( double forceMultiplier = 0 // some times we get more than one signal at the same time, here we increase volume using this ... ) { // // Check Open Trades ... int openSignals = xEMPTY5Trader.Count(); // double result = xEMPTY5VolumeManager.CalculateVolume( openSignals, _Symbol); // result *= forceMultiplier; // // Normalize Volume ... result = NormalizeVolume(result, _Symbol, 2); // return result; } // // END Volume Baseed Functions ... // // // START Report/Collect and Guard Functions ... // // // Update Report Info ... void XEMPTY5UpdateReports() { // double staticVolume = xEMPTY5VolumeManager.GetStaticVolume(); string staticVolumeCalculationMethod = EnumToString(xEMPTY5StaticVolumeMethod); double maxAllowedVolume = xEMPTY5VolumeManager.GetMaxAllowedVolume(); double volumeIncreaseMultiplier = xEMPTY5VolumeManager.GetVolumeMultiplier(); double balanceGowingToApplyMultiplier = xEMPTY5VolumeManager.GetIncreaseMultiplierBalance(); double balanceGrowingToIncreaseMaxAllowedVolume = xEMPTY5VolumeManager.GetIncreaseMaxAllowedVolumeBalance(); // // Update Reports Volume Info ... xEMPTY5Reporter.UpdateReportsVolumeInfo( staticVolume, staticVolumeCalculationMethod, maxAllowedVolume, volumeIncreaseMultiplier, balanceGowingToApplyMultiplier, balanceGrowingToIncreaseMaxAllowedVolume); // // Calculate Max Allowed Drawdown ... double minBalanceForTradeBasedOnBalance = xEMPTY5Trader.GetMinBalanceForOpenTrades(); xEMPTY5Reporter.UpdateMinBalanceForOpenTradesInReports(minBalanceForTradeBasedOnBalance); } // // Reset XEMPTY5 Info Buffers ... void XEMPTY5ResetCollectors() { // // Reset Calculations Buffers and Variables ... xEMPTY5MaxDrawUp = 0; xEMPTY5MaxDrawDown = 0; // xEMPTY5Trader.Reset(); xEMPTY5Reporter.Reset(); xEMPTY5Collector.Reset(); xEMPTY5VolumeManager.ResetForceVolumeMultiplier(); } // // END Report/Collect and Guard Functions ... // // // START Alert Functions ... // // // Send Alert ... void XEMPTY5IssueAlert(string message) { // // Validate Args ... if (StringLen(message) <= 0) { return; } // if (xEMPTY5EnableAlerts) { SendAlert(message); } else { LogMessage(message); } } // // Send Take Profit Alert on Specific Signal ... void XEMPTY5IssueTPAlert( XSignal &signal // Specified Signal ) { // string message = ""; // message = xEMPTY5Trader.GenerateSignalTPComment(signal); // XEMPTY5IssueAlert(message); } // // Send Stop Loss Alert on Specific Signal ... void XEMPTY5IssueSLAlert( XSignal &signal // Specified Signal ) { // string message = ""; // message = xEMPTY5Trader.GenerateSignalSLComment(signal); // XEMPTY5IssueAlert(message); } // // Send Force Close Alert on Specific Signal ... void XEMPTY5IssueFCAlert( XSignal &signal // Specified Signal ) { // string message = ""; // message = xEMPTY5Trader.GenerateSignalForceCloseComment(signal); // XEMPTY5IssueAlert(message); } // // Send Risk Free Alert on Specific Signal ... void XEMPTY5IssueRFAlert( XSignal &signal // Specified Signal ) { // string message = ""; // message = xEMPTY5Trader.GenerateSignalRFComment(signal, 0); // XEMPTY5IssueAlert(message); } // // Send Guard Alert on Specific Signal ... void XEMPTY5IssueGuardAlert( XSignal &signal, // Specified Signal ENUM_X_GUARD_REASONS reason, // Specified Guard Reason bool isStopOut = false // Specified StopOut Fired or not ) { // string message = ""; // message = xEMPTY5Guard.GenerateGuardedSignalComment( signal, reason); // XEMPTY5IssueAlert(message); } // // Send Initialization Succeed Alert ... void XEMPTY5IssueInitializationSucceedAlert() { // string message = "Initializion of (" + XEMPTY5ProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ..."; XEMPTY5IssueAlert(message); } // // Send De Initialization Succeed Alert ... void XEMPTY5IssueDeinitializationSucceedAlert() { // string message = "De Initializion of (" + XEMPTY5ProviderName + " Provider" + ") Succeeded ..."; XEMPTY5IssueAlert(message); } // // Send Signal Successfully Execution Alert ... void XEMPTY5IssueSignalExecutionAlert( XSignal &signal, // Specified Signal string &providers[] // Signal Providers ) { // string message = xEMPTY5Trader.ToString(signal); // string providersMsg = ToString(providers); if (StringLen(providersMsg) > 0) { message += ", Providers: " + providersMsg; } // XEMPTY5IssueAlert(message); } // // Send Signal Execution Alert ... void XEMPTY5IssueSignalExecutionError(int error) { // string message = GetSignalExecutionError(error); if (StringLen(message) == 0) { return; } // XEMPTY5IssueAlert(message); } // // END Alert Functions ... // // // END Private Functions ... //