//////////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 _XPROVIDER_ Signal Provider Library // -------------------------------------------------------- // Name: _XPROVIDER_SignalProvider // Description: _XPROVIDER_ 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 // // START Inputs ... // input group "_XPROVIDER_ Provider"; // input group "_XPROVIDER_ Common"; input bool enable_XPROVIDER_Provider = true; // Enable Provider input bool _xPROVIDER_EnableAlerts = true; // Enable Events Alert // input group "_XPROVIDER_ Indicator"; // input group "_XPROVIDER_ Trader"; input int _xPROVIDER_MagicNumber = 16940562; // Trader MagicNumber input int _xPROVIDER_Slippage = 10; // Trader Slippage // input group "_XPROVIDER_ Trade Management"; input bool _xPROVIDER_AllowLongTrades = true; // Allow Long Trades input bool _xPROVIDER_AllowShortTrades = true; // Allow Short Trades input bool _xPROVIDER_UseGridTrades = true; // Enable Grid Trades input double _xPROVIDER_GridVolumeMultiplier = 2; // Grid Volume Multiplier input double _xPROVIDER_GridDistancePips = 10; // Grid Position Distance in Pips // input group "_XPROVIDER_ Risk Management"; input bool _xPROVIDER_UseDynamicVolume = true; // Enable Dynamic Volume input double _xPROVIDER_StaticVolume = 0.01; // Static Volume input double _xPROVIDER_BalanceIncreased = 500; // Balance Increase input double _xPROVIDER_VolumeIncreased = 0.01; // Volume Increase // // 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 *_xPROVIDER_Trader; XCAccountInfo _xPROVIDER_AccountInfo; // double _xPROVIDER_GridLongPrice = 0; double _xPROVIDER_GridLongVolume = 0; // double _xPROVIDER_GridShortPrice = 0; double _xPROVIDER_GridShortVolume = 0; // // END Global Definitions: Variables, Properties and etc ... // // // START Provided Functions ... // // // Initial Library if required ... bool OnInInit_XPROVIDER_SignalProviderLibrary() { // bool result = false; // // Error Message ... string message = ""; // // Check Risk Management ... if (_xPROVIDER_UseDynamicVolume) { // if (_xPROVIDER_BalanceIncreased <= 0 || _xPROVIDER_VolumeIncreased <= 0) { // message = "invalid volume increased factors ..."; LogMessage(message); // return result; } } else { // double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); // if (_xPROVIDER_StaticVolume > maxAvailableVolume || _xPROVIDER_StaticVolume < minAvailableVolume) { // message = "invalid static volume ..."; LogMessage(message); // return result; } } // // Make XCTrader instance ... _xPROVIDER_Trader = new XCTrade( _Symbol, _xPROVIDER_Slippage, _xPROVIDER_MagicNumber); // result = true; // // Logging State ... message = "Initializion of (" + "_XPROVIDER_ Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ..."; LogMessage(message); // return result; } // // DeInitial Library if required ... void OnDeinit_XPROVIDER_SignalProviderLibrary() { // // Logging State ... string message = "De Initializion of (" + "_XPROVIDER_ Provider" + ") Succeeded ..."; LogMessage(message); } // // this is a Globally Function which do all of // checkings and positions handling ... void Handle_XPROVIDER_SignalProviderTick() { // // Handle Open Trades ... _XPROVIDER_HandleOpenTrades(); // // Handle Close Trades ... _XPROVIDER_HandleCloseTrades(); } // // Check Market Conditions to find Long Primary Signals ... bool _XPROVIDER_HasPrimaryLongSignal() { // bool result = false; // // Check Buy/Long Conditions ... // return result; } // // Check Market Conditions to find Short Primary Signals ... bool _XPROVIDER_HasPrimaryShortSignal() { // bool result = false; // // Check Sell/Short Conditions ... // return result; } // // Check Market Conditions to find Long Grid Signals ... bool _XPROVIDER_HasGridLongSignal() { // bool result = false; // // Check Buy/Long Conditions ... // return result; } // // Check Market Conditions to find Short Grid Signals ... bool _XPROVIDER_HasGridShortSignal() { // bool result = false; // // Check Sell/Short Conditions ... // return result; } // // Check Market Conditions for closing Long Trades ... bool _XPROVIDER_CanCloseLongTrades() { // bool result = false; // return result; } // // Check Market Conditions for closing Short Trades ... bool _XPROVIDER_CanCloseShortTrades() { // bool result = false; // return result; } // // Handle Long/Buy for Primary Trades... bool _XPROVIDER_HandlePrimaryLong( XSignal &signal, // return structure if signal founded bool doTrade = true // do trade on signal ) { // bool result = false; // ResetLastError(); // if (_XPROVIDER_HasPrimaryLongSignal() && _xPROVIDER_Trader.CountLongs() == 0) { // double entry = GetAsk(); double volume = _XPROVIDER_CalculateVolume(); // double canDoTrade = _XPROVIDER_CanDoTrade(); // signal.entry = entry; signal.volume = volume; signal.symbol = _Symbol; signal.type = X_SIGNAL_LONG; signal.magicNumber = _xPROVIDER_MagicNumber; signal.time = iTime(_Symbol, _Period, 0); signal.comment = "Primary _XPROVIDER_ Long"; // if (enable_XPROVIDER_Provider && _xPROVIDER_AllowLongTrades && doTrade && canDoTrade) { // // Execute Signal ... result = _xPROVIDER_Trader.ExecuteSignal(signal); // // Since this means an error happens, we have to log this error ... if (!result) { string errMessage = "failed to execute Long signal: " + (string)GetLastError(); LogMessage(errMessage); } } else { result = false; } } // // Handle Alerts ... if (result) { // if (_xPROVIDER_EnableAlerts) { SendAlert(signal, true); } else { LogExecutedSignal(signal); } } // return result; } // // Handle Short/Sell for Primary Trades... bool _XPROVIDER_HandlePrimaryShort( XSignal &signal, // return structure if signal founded bool doTrade = true // do trade on signal ) { // bool result = false; // ResetLastError(); // if (_XPROVIDER_HasPrimaryShortSignal() && _xPROVIDER_Trader.CountShorts() == 0) { // double entry = GetBid(); double volume = _XPROVIDER_CalculateVolume(); // double canDoTrade = _XPROVIDER_CanDoTrade(); // signal.entry = entry; signal.volume = volume; signal.symbol = _Symbol; signal.type = X_SIGNAL_SHORT; signal.magicNumber = _xPROVIDER_MagicNumber; signal.time = iTime(_Symbol, _Period, 0); signal.comment = "Primary _XPROVIDER_ Short"; // if (enable_XPROVIDER_Provider && _xPROVIDER_AllowShortTrades && doTrade && canDoTrade) { // // Execute Signal ... result = _xPROVIDER_Trader.ExecuteSignal(signal); // // Since this means an error happens, we have to log this error ... if (!result) { string errMessage = "failed to execute Short signal: " + (string)GetLastError(); LogMessage(errMessage); } } else { result = false; } } // // Handle Alerts ... if (result) { // if (_xPROVIDER_EnableAlerts) { SendAlert(signal, true); } else { LogExecutedSignal(signal); } } // return result; } // // Handle Long/Buy for Grid Trades... bool _XPROVIDER_HandleGridLong( XSignal &signal, // return structure if signal founded bool doTrade = true // do trade on signal ) { // bool result = false; // ResetLastError(); // double ask = GetAsk(); bool canDoGridTrade = ask <= _xPROVIDER_GridLongPrice; if (_XPROVIDER_HasGridLongSignal() && _xPROVIDER_Trader.CountLongs() > 0 && canDoGridTrade) { // double entry = ask; double volume = _xPROVIDER_GridLongVolume; // double canDoTrade = _XPROVIDER_CanDoTrade(); // signal.entry = entry; signal.volume = volume; signal.symbol = _Symbol; signal.type = X_SIGNAL_LONG; signal.magicNumber = _xPROVIDER_MagicNumber; signal.time = iTime(_Symbol, _Period, 0); signal.comment = "Grid _XPROVIDER_ Long"; // if (enable_XPROVIDER_Provider && _xPROVIDER_AllowLongTrades && _xPROVIDER_UseGridTrades && doTrade && canDoTrade) { // // Execute Signal ... result = _xPROVIDER_Trader.ExecuteSignal(signal); // // Since this means an error happens, we have to log this error ... if (!result) { string errMessage = "failed to execute Long signal: " + (string)GetLastError(); LogMessage(errMessage); } } else { result = false; } } // // Handle Alerts ... if (result) { // if (_xPROVIDER_EnableAlerts) { SendAlert(signal, true); } else { LogExecutedSignal(signal); } } // return result; } // // Handle Short/Sell for Grid Trades... bool _XPROVIDER_HandleGridShort( XSignal &signal, // return structure if signal founded bool doTrade = true // do trade on signal ) { // bool result = false; // ResetLastError(); // double bid = GetBid(); bool canDoGridTrade = bid >= _xPROVIDER_GridShortPrice; if (_XPROVIDER_HasGridShortSignal() && _xPROVIDER_Trader.CountShorts() > 0 && canDoGridTrade) { // double entry = bid; double volume = _xPROVIDER_GridShortVolume; // double canDoTrade = _XPROVIDER_CanDoTrade(); // signal.entry = entry; signal.volume = volume; signal.symbol = _Symbol; signal.type = X_SIGNAL_SHORT; signal.magicNumber = _xPROVIDER_MagicNumber; signal.time = iTime(_Symbol, _Period, 0); signal.comment = "Grid _XPROVIDER_ Short"; // if (enable_XPROVIDER_Provider && _xPROVIDER_AllowShortTrades && _xPROVIDER_UseGridTrades && doTrade && canDoTrade) { // // Execute Signal ... result = _xPROVIDER_Trader.ExecuteSignal(signal); // // Since this means an error happens, we have to log this error ... if (!result) { string errMessage = "failed to execute Short signal: " + (string)GetLastError(); LogMessage(errMessage); } } else { result = false; } } // // Handle Alerts ... if (result) { // if (_xPROVIDER_EnableAlerts) { SendAlert(signal, true); } else { LogExecutedSignal(signal); } } // return result; } // // Handle Open Trades ... void _XPROVIDER_HandleOpenTrades() { // // Primary Long Trade ... XSignal primaryLongSignal = {}; bool isPrimaryLongSignalExecuted = _XPROVIDER_HandlePrimaryLong(primaryLongSignal); if (isPrimaryLongSignalExecuted) { // // Calculate Grid Long Conditions ... _XPROVIDER_CalculateGridLongConditions(primaryLongSignal); } // // Primary Short Trade ... XSignal primaryShortSignal = {}; bool isPrimaryShortSignalExecuted = _XPROVIDER_HandlePrimaryShort(primaryShortSignal); if (isPrimaryShortSignalExecuted) { // // Calculate Grid Short Conditions ... _XPROVIDER_CalculateGridShortConditions(primaryShortSignal); } // // Check Grid Trades ... if (_xPROVIDER_UseGridTrades) { // // Grid Long Trade ... XSignal gridLongSignal = {}; bool isGridLongSignalExecuted = _XPROVIDER_HandleGridLong(gridLongSignal); if (isGridLongSignalExecuted) { // // Calculate Grid Long Conditions ... _XPROVIDER_CalculateGridLongConditions(gridLongSignal); } // // Grid Short Trade ... XSignal gridShortSignal = {}; bool isGridShortSignalExecuted = _XPROVIDER_HandleGridShort(gridShortSignal); if (isGridShortSignalExecuted) { // // Calculate Grid Short Conditions ... _XPROVIDER_CalculateGridShortConditions(gridShortSignal); } } } // // Handle Close Trades ... void _XPROVIDER_HandleCloseTrades() { // // Handle Long/Buy Close ... if (_xPROVIDER_Trader.CountLongs() > 0 && _XPROVIDER_CanCloseLongTrades()) { // _xPROVIDER_Trader.CloseLongPositions(); // // Reset Grid Long Conditions ... _xPROVIDER_GridLongPrice = 0; _xPROVIDER_GridLongVolume = 0; // string message = "_XPROVIDER_ Closing Long Trades ..."; // if (_xPROVIDER_EnableAlerts) { SendAlert(message); } else { LogMessage(message); } } // // Handle Short/Sell Close ... if (_xPROVIDER_Trader.CountShorts() > 0 && _XPROVIDER_CanCloseShortTrades()) { // _xPROVIDER_Trader.CloseShortPositions(); // // Reset Grid Short Conditions ... _xPROVIDER_GridShortPrice = 0; _xPROVIDER_GridShortVolume = 0; // string message = "_XPROVIDER_ Closing Short Trades ..."; // if (_xPROVIDER_EnableAlerts) { SendAlert(message); } else { LogMessage(message); } } } // // Calculating Volume for Tradings ... double _XPROVIDER_CalculateVolume() { // double result = _xPROVIDER_StaticVolume; if (!_xPROVIDER_UseDynamicVolume) { return result; } // double accountBalance = _xPROVIDER_AccountInfo.GetBalance(); double balanceIncreased = _xPROVIDER_BalanceIncreased; double volumeIncreased = _xPROVIDER_VolumeIncreased; // result = (volumeIncreased * accountBalance) / balanceIncreased; // // Normalize Volume ... result = NormalizeDouble(result, 2); // double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); // // Validate Result ... if (result > maxAvailableVolume) { result = maxAvailableVolume; } else if (result < minAvailableVolume) { result = minAvailableVolume; } // return result; } // // Calculate Grid Long Trades Price and Volume ... void _XPROVIDER_CalculateGridLongConditions(XSignal &signal) { // // Check Grid Trades Enable ... if (!_xPROVIDER_UseGridTrades) { return; } // // Calculate GridLongPrice and GridLongVolume ... _xPROVIDER_GridLongVolume = NormalizeDouble(signal.volume * _xPROVIDER_GridVolumeMultiplier, 2); _xPROVIDER_GridLongPrice = NormalizeDouble(signal.entry - (_xPROVIDER_GridDistancePips * 10 * _Point), _Digits); } // // Calculate Grid Short Trades Price and Volume ... void _XPROVIDER_CalculateGridShortConditions(XSignal &signal) { // // Check Grid Trades Enable ... if (!_xPROVIDER_UseGridTrades) { return; } // // Calculate GridShortPrice and GridShortVolume ... _xPROVIDER_GridShortVolume = NormalizeDouble(signal.volume * _xPROVIDER_GridVolumeMultiplier, 2); _xPROVIDER_GridShortPrice = NormalizeDouble(signal.entry + (_xPROVIDER_GridDistancePips * 10 * _Point), _Digits); } // // Determine based on current account state bool _XPROVIDER_CanDoTrade() { // bool result = true; // // TODO: Complete this ... // return true; } // // END Provided Functions ... //