//////////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 XEU5 Signal Provider Library // -------------------------------------------------------- // Name: XEU5SignalProvider // Description: XEU5 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 XEU5ProviderName "XEU5" // // START Inputs ... // #include "x-saherelm.xeu5.provider.inputs.lib.mq5"; // // END Inputs ... // // // Include Common Library ... #include "x-saherelm.common.lib.mq5" // // Include Logger Library ... #include "x-saherelm.log.lib.mq5" // // Include Alert Library ... #include "x-saherelm.alert.lib.mq5" // // Include Draw Library ... #include "x-saherelm.draw.lib.mq5" // // Include Class Libraries ... #include "x-saherelm.class.lib.mq5" // // START Global Definitions: Variables, Properties and etc ... // // XCTrade *xEU5Trader; XCAccountInfo xEU5AccountInfo; // #include "x-saherelm.xeu5.provider.indicators.lib.mq5" // double xEU5Deposit = 0; double xEU5Balance = 0; double xEU5FreeMargin = 0; double xEU5RiskFreeTrades = 0; double xEU5MinRewardPerTrade = 0; double xEU5BalanceForOpenTrades = 0; double xEU5FreeMarginForOpenTrades = 0; double xEU5BaseRiskableMoneyPerTrade = 0; double xEU5MinRewardPerSupportTrades = 0; double xEU5SupportTradesPriceDistance = 0; // // END Global Definitions: Variables, Properties and etc ... // // // START Provided Functions ... // // // Initial Library if required ... bool XEU5InitSignalProviderLibrary() { // bool result = false; // // Validate Inputs ... result = XEU5ValidateInputs(); if (!result) { return result; } // // Init Indicators ... result = XEU5InitIndicators(); if (!result) { return result; } // // Calculate Account Deposit ... xEU5Deposit = xEU5AccountInfo.GetInitialBalance(); // // Calculate RiskFree Price Distance ... if (xEU5RiskFreeTradesInPips > 0 && xEU5RiskFreeRate > 0) { xEU5RiskFreeTrades = PipsToPrice(xEU5RiskFreeTradesInPips); } // // Calculate xEU5MinRewardPerTrade ... if (xEU5MinRewardPerTradeInPips > 0) { xEU5MinRewardPerTrade = PipsToPrice(xEU5MinRewardPerTradeInPips); } // // Calculate Min Balance for Trades ... if (xEU5BalanceFactorForOpenTrades > 0) { xEU5BalanceForOpenTrades = xEU5BalanceFactorForOpenTrades * xEU5Deposit; } // // Claculate Min Free Marging for Trades ... if (xEU5FreeMarginFactorForOpenTrades > 0) { xEU5FreeMarginForOpenTrades = xEU5FreeMarginFactorForOpenTrades * xEU5Deposit; } // // Calculate xEU5SupportTradesPriceDistance ... if (xEU5MaxAllowedSupportTrades > 0 && xEU5SupportTradesPriceDistanceInPips > 0 && xEU5MinRewardPerSupportTradesInPips > 0) { xEU5MinRewardPerSupportTrades = PipsToPrice(xEU5MinRewardPerSupportTradesInPips); xEU5SupportTradesPriceDistance = PipsToPrice(xEU5SupportTradesPriceDistanceInPips); } // // Calculate Base Riskable Money Per Trade ... if (xEU5MaxAllowedRiskPerTradesMultiplier > 0) { xEU5BaseRiskableMoneyPerTrade = (xEU5MaxAllowedRiskPerTradesMultiplier * xEU5Deposit); } // // Make XCTrader instance ... xEU5Trader = new XCTrade( XEU5ProviderName, _Symbol, xEU5Slippage, xEU5MagicNumber, xEU5MaxAllowedTrades, xEU5MaxAllowedSupportTrades, xEU5MinRewardPerTradeInPips, xEU5SupportTradesPriceDistanceInPips, xEU5FreeMarginForOpenTrades, xEU5BalanceForOpenTrades); // result = true; // // Logging State ... XEU5IssueInitializationSucceedAlert(); // return result; } // // DeInitial Library if required ... void XEU5DeinitSignalProviderLibrary(const int reason) { // // Release Handlers ... XEU5ReleaseIndicators(); // // Logging State ... XEU5IssueDeinitializationSucceedAlert(); } // // this is a Globally Function which do all of // checkings and positions handling ... void XEU5SignalProviderHandleTick() { // // Update account Balance ... xEU5Balance = xEU5AccountInfo.GetBalance(); xEU5FreeMargin = xEU5AccountInfo.GetFreeMargin(); // // Check Provider is Enable or Not ... if (!xEU5EnableProvider) { return; } // // Reading Indicator Buffers ... XEU5HandleReadingBuffers(); if (xEU5CalculatedBars < xEU5MaxLengthOfInputs) { return; } // // Handle Open Trades ... XEU5HandleOpenTrades(); // // Handle Close Trades ... XEU5HandleCloseTrades(); // // Handle Support Trades ... XEU5HandleSupportTrades(); } // // Handle Open Trades ... void XEU5HandleOpenTrades() { // // Check Can Trade ... bool canTrade = xEU5AllowLongTrades || xEU5AllowShortTrades; if (!canTrade) { return; } // // Check Max Open Trades ... int openPositions = xEU5Trader.Count(); int openTradeKinds = xEU5Trader.CountByKind( X_SIGNAL_UNKNOWN, X_KIND_TRADE); bool canOpenPositions = openTradeKinds < xEU5MaxAllowedTrades; if (!canOpenPositions) { return; } // // Check Signals Exists ... XTF_SIGNAL longSignalInfo = {}; XTF_SIGNAL shortSignalInfo = {}; bool hasLongSignal = XEU5CanOpenLongTrade(longSignalInfo); bool hasShortSignal = XEU5CanOpenShortTrade(shortSignalInfo); if (!hasLongSignal && !hasShortSignal) { return; } // // Open Long Trades ... if ( // hasLongSignal && xEU5AllowLongTrades) { // bool isOpened = XEU5OpenLongPosition(longSignalInfo); } // // Open Short Trades ... if ( // hasShortSignal && xEU5AllowShortTrades) { // bool isOpened = XEU5OpenShortPosition(shortSignalInfo); } } // // Handle Close Trades ... void XEU5HandleCloseTrades() { // // All Close Mechanism Handles Here ... // - Force Close; // - Partial Close; // - Risk Free Close; // - Virtual TP/SL Close; // // Force Close Long Trades ... bool canCloseLongTrades = XEU5CanCloseLongTrade(); if (xEU5AllowLongTrades && canCloseLongTrades) { // ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG; // XSignal closed[]; xEU5Trader.ClosePositionsByType( type, closed); // bool isClosed = ArraySize(closed) > 0; if (isClosed) { XEU5IssueForceCloseTradesAlert(type); } } // // Force Close Short Trades ... bool canCloseShortTrades = XEU5CanCloseShortTrade(); if (xEU5AllowShortTrades && canCloseShortTrades) { // ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT; // XSignal closed[]; xEU5Trader.ClosePositionsByType( type, closed); // bool isClosed = ArraySize(closed) > 0; if (isClosed) { XEU5IssueForceCloseTradesAlert(type); } } // // Close Risk Free Trades ... bool canRiskFree = xEU5RiskFreeTradesInPips > 0 && xEU5RiskFreeTrades > 0 && xEU5RiskFreeRate > 0; if (canRiskFree) { XSignal riskFrees[]; xEU5Trader.RiskFreeSignals(riskFrees); bool isRiskFree = ArraySize(riskFrees) > 0; if (isRiskFree) { XEU5IssueRiskFreeTradesAlert(); } } // XEU5HandleCloseInProfitTrades(); // XEU5HandleCloseMaxDrawDownTrades(); // XEU5HandleCloseTooOldTrades(); } // // Handle Supported Trades ... void XEU5HandleSupportTrades() { // bool canDoTrade = xEU5MaxAllowedSupportTrades > 0 && xEU5MinRewardPerSupportTradesInPips > 0 && xEU5SupportTradesPriceDistanceInPips > 0; if (!canDoTrade) { return; } // XSignal supports[]; bool hasSupportTrade = XEU5OpenSupportTrade(supports); if (hasSupportTrade) { } } // // Open Long Position ... bool XEU5OpenLongPosition( XTF_SIGNAL &info // Retrieve Signal Additional Info on this Object ) { // bool result = false; // // Calculate Required Data for Position ... double sl = info.sl > 0 ? info.sl : 0; double tp = info.tp > 0 ? info.tp : xEU5MinRewardPerTrade; double riskFree = info.riskFree > 0 ? info.riskFree : xEU5RiskFreeTrades; double riskFreeRate = xEU5RiskFreeRate; double volume = XEU5CalculateVolume(info.signalPusher); // XSignal signal = {}; signal = xEU5Trader.GenerateTradeSignal( X_SIGNAL_LONG, tp, sl, volume, riskFree, riskFreeRate); bool isValidSignal = IsValid( signal, xEU5MagicNumber); if (!isValidSignal) { return result; } // int error = -1; result = xEU5Trader.ExecuteSignal(signal, error); if (result) { XEU5IssueSignalExecutionAlert(signal); } else { XEU5IssueSignalExecutionError(error); } // return result; } // // Open Short Position ... bool XEU5OpenShortPosition( XTF_SIGNAL &info // Retrieve Signal Additional Info on this Object ) { // bool result = false; // // Calculate Required Data for Position ... double sl = info.sl > 0 ? info.sl : 0; double tp = info.tp > 0 ? info.tp : xEU5MinRewardPerTrade; double riskFree = info.riskFree > 0 ? info.riskFree : xEU5RiskFreeTrades; double riskFreeRate = xEU5RiskFreeRate; double volume = XEU5CalculateVolume(info.signalPusher); // XSignal signal = {}; signal = xEU5Trader.GenerateTradeSignal( X_SIGNAL_SHORT, tp, sl, volume, riskFree, riskFreeRate); bool isValidSignal = IsValid( signal, xEU5MagicNumber); if (!isValidSignal) { return result; } // int error = -1; result = xEU5Trader.ExecuteSignal(signal, error); if (result) { XEU5IssueSignalExecutionAlert(signal); } // return result; } // // Open a Support Signal ... bool XEU5OpenSupportTrade( XSignal &supports[] // Holds Result ... ) { // bool result = false; // // Check Can Trade ... result = xEU5AllowLongTrades || xEU5AllowShortTrades; if (!result) { return result; } // // Check Support Trades is Enable or not ... bool isSupportTradesEnabled = // xEU5MaxAllowedSupportTrades > 0 && xEU5MinRewardPerSupportTrades > 0 && xEU5SupportTradesPriceDistance > 0 // ; if (!isSupportTradesEnabled) { return result; } // // Recieve InDD Open Trades ... XSignal inDDTrades[]; xEU5Trader.GetInDrawDownTrades( xEU5SupportTradesPriceDistance, X_SIGNAL_UNKNOWN, X_KIND_TRADE, inDDTrades); int inDDTradesCount = ArraySize(inDDTrades); result = inDDTradesCount > 0; if (!result) { return result; } // // Check Signals Exists ... XTF_SIGNAL longSignalInfo = {}; XTF_SIGNAL shortSignalInfo = {}; bool hasLongSignal = XEU5CanOpenLongTrade(longSignalInfo); bool hasShortSignal = XEU5CanOpenShortTrade(shortSignalInfo); result = hasLongSignal || hasShortSignal; if (!result) { return result; } // // Loop Through In DrawDown Trades ... XSignal supportedSignals[]; for (int i = 0; i < inDDTradesCount; i++) { // // Retrieve Parent Signal ... XSignal parent = inDDTrades[i]; // // Check if Long Signal Happens ... // && parent.type == X_SIGNAL_LONG ... if (hasLongSignal) { // // Generate Support Signal ... XSignal sSignal = GenerateSupportSignal( longSignalInfo.signalPusher, X_SIGNAL_LONG, parent); // // Validate it ... bool isValidSupport = IsValid(sSignal, xEU5MagicNumber); if (!isValidSupport) { continue; ; } // // Try To Execute Support Signal ... int error = 0; bool isExecuted = xEU5Trader.ExecuteSupportSignal( sSignal, error); if (isExecuted) { // if (!result) { result = true; } // Add( sSignal, supports); // XEU5IssueSignalExecutionAlert(sSignal); } else { XEU5IssueSignalExecutionError(error); } // continue; } // // Check if Short Signal Happens ... // && parent.type == X_SIGNAL_SHORT if (hasShortSignal) { // // Generate Support Signal ... XSignal sSignal = GenerateSupportSignal( shortSignalInfo.signalPusher, X_SIGNAL_SHORT, parent); // // Validate it ... bool isValidSupport = IsValid(sSignal, xEU5MagicNumber); if (!isValidSupport) { continue; ; } // // Try To Execute Support Signal ... int error = 0; bool isExecuted = xEU5Trader.ExecuteSupportSignal( sSignal, error); if (isExecuted) { // if (!result) { result = true; } // Add( sSignal, supports); // XEU5IssueSignalExecutionAlert(sSignal); } else { XEU5IssueSignalExecutionError(error); } // continue; } } // return result; } // // Close In Profit Trades ... // the senario is to close in profit trades // if they are old age ... // age calculated based on xEU5MaxInDrawDownTradeAge / 2 ... void XEU5HandleCloseInProfitTrades() { // // Validate Args ... if (xEU5MaxInDrawDownTradeAge <= 0) { return; } // int age = xEU5MaxInDrawDownTradeAge / 2; // XSignal oldTrades[]; xEU5Trader.GetLongTimeTrades( age, _Period, X_SIGNAL_UNKNOWN, X_KIND_TRADE, oldTrades); int oldTradesCount = ArraySize(oldTrades); for (int i = 0; i < oldTradesCount; i++) { // XSignal iTrade = oldTrades[i]; if (iTrade.profit > 0) { // string comment = xEU5Trader.GetSignalForceClosedComment(iTrade); bool isClosed = xEU5Trader.Close( iTrade.ticket, comment); if (isClosed) { XEU5IssueAlert(comment); } } } // XSignal oldSupports[]; xEU5Trader.GetLongTimeTrades( age, _Period, X_SIGNAL_UNKNOWN, X_KIND_SUPPORT, oldSupports); int oldSupportsCount = ArraySize(oldSupports); for (int i = 0; i < oldSupportsCount; i++) { // XSignal iTrade = oldSupports[i]; if (iTrade.profit > 0) { // string comment = xEU5Trader.GetSignalForceClosedComment(iTrade); bool isClosed = xEU5Trader.Close( iTrade.ticket, comment); if (isClosed) { XEU5IssueAlert(comment); } } } } // // Close All InDrawDown Trades ... void XEU5HandleCloseMaxDrawDownTrades() { // // Validate Args ... if (xEU5MaxAllowedRiskPerTradesMultiplier <= 0) { return; } // double baseRiskableMoney = xEU5BaseRiskableMoneyPerTrade > 0 ? xEU5BaseRiskableMoneyPerTrade : 1; // XSignal inDDTrades[]; xEU5Trader.GetInDrawDownTrades( 0, X_SIGNAL_UNKNOWN, X_KIND_TRADE, inDDTrades); // int inDDTradesCount = ArraySize(inDDTrades); if (inDDTradesCount > 0) { // // Loop through Trades ... for (int i = 0; i < inDDTradesCount; i++) { // XSignal iTrade = inDDTrades[i]; // // Calculate Max Allowed Risk Per iTrade ... double iMaxAllowedRisk = (iTrade.volume / xEU5StaticVolume) * baseRiskableMoney; // // Check Negative Profit Matchs Riskable Money ... bool isProfitPassed = MathAbs(iTrade.profit) >= iMaxAllowedRisk; if (isProfitPassed) { // string comment = xEU5Trader.GetSignalForceClosedComment(iTrade); // bool isClosed = xEU5Trader.Close(iTrade.ticket, comment); if (isClosed) { LogMessage("Signal: " + (string)iTrade.ticket + ", closed by: " + (string)iMaxAllowedRisk); XEU5IssueAlert(comment); } } } } // XSignal inDDSupports[]; xEU5Trader.GetInDrawDownTrades( 0, X_SIGNAL_UNKNOWN, X_KIND_SUPPORT, inDDSupports); // int inDDSupportsCount = ArraySize(inDDSupports); if (inDDSupportsCount > 0) { // // Loop through Trades ... for (int i = 0; i < inDDSupportsCount; i++) { // XSignal iTrade = inDDSupports[i]; // // Calculate Max Allowed Risk Per iTrade ... double iMaxAllowedRisk = (iTrade.volume / xEU5StaticVolume) * baseRiskableMoney; // // Check Negative Profit Matchs Riskable Money ... bool isProfitPassed = MathAbs(iTrade.profit) >= iMaxAllowedRisk; if (isProfitPassed) { // string comment = xEU5Trader.GetSignalForceClosedComment(iTrade); // bool isClosed = xEU5Trader.Close(iTrade.ticket, comment); if (isClosed) { XEU5IssueAlert(comment); } } } } } // // Close All Too Old Trades ... // the senario is to close all tardes which has long age ... // age calculated based on xEU5MaxInDrawDownTradeAge ... void XEU5HandleCloseTooOldTrades() { // // Validate Args ... if (xEU5MaxInDrawDownTradeAge <= 0) { return; } // XSignal oldTrades[]; xEU5Trader.GetLongTimeTrades( xEU5MaxInDrawDownTradeAge, _Period, X_SIGNAL_UNKNOWN, X_KIND_TRADE, oldTrades); int oldTradesCount = ArraySize(oldTrades); for (int i = 0; i < oldTradesCount; i++) { // XSignal iTrade = oldTrades[i]; // string comment = xEU5Trader.GetSignalLongTimeClosedComment(iTrade); bool isClosed = xEU5Trader.Close( iTrade.ticket, comment); if (isClosed) { XEU5IssueAlert(comment); } } // XSignal oldSupports[]; xEU5Trader.GetLongTimeTrades( xEU5MaxInDrawDownTradeAge, _Period, X_SIGNAL_UNKNOWN, X_KIND_SUPPORT, oldSupports); int oldSupportsCount = ArraySize(oldSupports); for (int i = 0; i < oldSupportsCount; i++) { // XSignal iTrade = oldSupports[i]; // string comment = xEU5Trader.GetSignalLongTimeClosedComment(iTrade); bool isClosed = xEU5Trader.Close( iTrade.ticket, comment); if (isClosed) { XEU5IssueAlert(comment); } } } // // END Provided Functions ... // // // START Private Functions ... // // // Calculating Volume for Tradings ... double XEU5CalculateVolume( double forceMultiplier = 0 // some times we get more than one signal at the same time, here we increase volume using this ... ) { // // Assign default Value ... double result = xEU5StaticVolume; // // we can count open trades and in draw down trades // then do check volume based on it for gridding ... XSignal openInProfitTrades[]; xEU5Trader.GetInProfitTrades( 0, X_SIGNAL_UNKNOWN, X_KIND_TRADE, openInProfitTrades); int openTrades = ArraySize(openInProfitTrades); // // Calculate Normalized Multiplier ... double mVolumeMultiplier = xEU5VolumeMultiplier <= 0 ? 1 : xEU5VolumeMultiplier; double multiplier = mVolumeMultiplier; multiplier = multiplier * openTrades; if (multiplier < 1) { multiplier = 1; } // double growRate = xEU5Balance / xEU5Deposit; if (growRate >= 1 && multiplier == 1) { // double growDiff = growRate - 1; if (growDiff < 1) { growRate = 1 + (growDiff * mVolumeMultiplier); } // multiplier = multiplier * growRate; } // result = multiplier * xEU5StaticVolume; // // Apply Force Multiplier ... if (forceMultiplier > 1) { result *= forceMultiplier; } // // Check Max Allowed Lottage ... double maxAllowedVolume = xEU5MaxSupportedVolumePerTradeInLots; if (growRate >= 4 * mVolumeMultiplier) { maxAllowedVolume *= mVolumeMultiplier; } // if ( maxAllowedVolume > 0 && result > maxAllowedVolume) { result = maxAllowedVolume; } // // Normalize Volume ... result = NormalizeVolume(result); // return result; } // // Calculate Signal TP and SL ... XTPSL XEU5CalculateTPSL( ENUM_X_SIGNAL_TYPE type // Position Type ) { // XTPSL result = {}; // // Validate Args ... if ( type != X_SIGNAL_LONG && type != X_SIGNAL_SHORT) { return result; } // bool isLong = type == X_SIGNAL_LONG; // double ask = GetAsk(); double bid = GetBid(); double spread = GetSpread(); double entry = isLong ? ask : bid; // // TODO: Find Risk .. double risk = 0; // // Calculate Reward ... double reward = PipsToPrice(xEU5MinRewardPerTradeInPips) + spread; // // Calculate TP and SL ... double tp = isLong ? entry + reward : entry - reward; double sl = 0; // result.type = type; result.tp = tp; result.sl = sl; result.entry = entry; // // TODO: Calculate R2R ... result.r2r = 0; // return result; } // // Generate Support Signal for Specific Trade ... XSignal GenerateSupportSignal( double forceVolumeMultiplier, // how many time increase volume based on signal providers ENUM_X_SIGNAL_TYPE type, // which type of support signal issued XSignal &parent // generate support signal for which Trade Kind Position ) { // XSignal result = {}; // // Validate Type ... bool isTypeValid = type == X_SIGNAL_LONG || type == X_SIGNAL_SHORT; if (!isTypeValid) { return result; } // // Validate Parent Signal ... bool isValidSignal = IsValid(parent, xEU5MagicNumber); if (!isValidSignal) { return result; } // // Validate Parent is Kind ... bool isKindValid = parent.kind == X_KIND_TRADE; if (!isKindValid) { return result; } // // Check Parent Ticket ... bool isValidTicket = parent.ticket > 0; if (!isValidTicket) { return result; } // // Validate DrawDown ... bool isInDD = parent.profit < 0; if (!isInDD) { return result; } // // Calculate What we Want ... // bool isLong = type == X_SIGNAL_LONG; // // Entry Price ... // double entry = GetEntry(parent.symbol, type); // // Required for Calculating RiskFree Level of Support Signals ... double riskFreeRate = 0; double riskFreePrice = 0; bool canRiskFree = xEU5RiskFreeRate > 0; // // TP ... double tp = MathAbs(parent.tp - parent.entry) / 2; // PriceToPips(MathAbs(parent.tp - parent.entry) / 2); if (tp <= xEU5MinRewardPerSupportTrades) { tp = xEU5MinRewardPerSupportTrades; } else if ( canRiskFree && tp > xEU5MinRewardPerSupportTrades) { // // Fill Risk Free Info ... riskFreeRate = xEU5RiskFreeRate; riskFreePrice = isLong ? xEU5MinRewardPerSupportTrades : xEU5MinRewardPerSupportTrades; } // // SL ... double sl = isLong ? 0 : 0; // // VOLUME ... int pOpenSupportCount = xEU5Trader.CountSupportedPositions(parent); double volume = parent.volume * forceVolumeMultiplier; // // Check and Normalize Volume based on MaxAllowed Volume ... if (xEU5MaxSupportedVolumePerTradeInLots > 0 && volume > xEU5MaxSupportedVolumePerTradeInLots) { volume = xEU5MaxSupportedVolumePerTradeInLots; } // // Normalize Volume ... volume = NormalizeVolume(volume); // // Generating Support Signal for Parent ... result = xEU5Trader.GenerateSupportSignal( type, tp, sl, volume, riskFreePrice, riskFreeRate, parent.ticket); // return result; } void XEU5IssueInitializationSucceedAlert() { // string message = "Initializion of (" + XEU5ProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ..."; XEU5IssueAlert(message); } void XEU5IssueDeinitializationSucceedAlert() { // string message = "De Initializion of (" + XEU5ProviderName + " Provider" + ") Succeeded ..."; XEU5IssueAlert(message); } void XEU5IssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type) { // string typeStr = GetSignalType(type); if (StringLen(typeStr) == 0) { return; } // string message = "Force Close " + typeStr + " Trades ..."; XEU5IssueAlert(message); } void XEU5IssueMaxAllowedTradesReachedAlert() { // string message = "reached Max Allowed Same Time Trades ..."; XEU5IssueAlert(message); } void XEU5IssueMaxAllowedFreeMarginReachedAlert() { // string message = "reached FreeMarigin For Open Trades ..."; XEU5IssueAlert(message); } void XEU5IssueMinAllowedBalanceReachedAlert() { // string message = "doesn't have Minimum Balance For Open Trades ..."; XEU5IssueAlert(message); } void XEU5IssueSignalExecutionAlert( XSignal &signal // Executed Signal ) { // XEU5IssueAlert(signal); } void XEU5IssueSignalExecutionError(int error) { // string message = GetSignalExecutionError(error); if (StringLen(message) == 0) { return; } // XEU5IssueAlert(message); } void XEU5IssueRiskFreeTradesAlert() { // string message = "Make Some Trades Risk Free ..."; XEU5IssueAlert(message); } void XEU5IssueLongInProfitTradeClosed() { // string message = "Closed Long Time in Profit Trades ..."; XEU5IssueAlert(message); } void XEU5IssueLongInDrawdownTradeClosed() { // string message = "Closed Long Time in Profit Trades ..."; XEU5IssueAlert(message); } void XEU5IssueAlert(string message) { // if (xEU5EnableAlerts) { SendAlert(message); } else { LogMessage(message); } } void XEU5IssueAlert(XSignal &signal) { // string signalStr = xEU5Trader.ToString(signal); XEU5IssueAlert(signalStr); // // // if (xEU5EnableAlerts) // { // SendAlert(signal); // } // else // { // LogSignal(signal); // } } // // END Private Functions ... //