Initial Commit ...

This commit is contained in:
2024-01-25 04:09:42 +03:30
commit b2037e07eb
1991 changed files with 668083 additions and 0 deletions
@@ -0,0 +1,197 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Alert Library
// --------------------------------------
// Name: XAlert
// Description: provides Alerts abilities ...
//
//
// 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 "Alerts";
input bool enableAlerts = true; // Enable Alerts
input bool logAlerts = true; // Log Alerts
input bool terminalAlerts = true; // Terminal Alerts
input bool mailAlerts = true; // Mail Alerts
input bool pushAlerts = true; // Push Alerts
//
// END Inputs ...
//
//
#include "x-saherelm.log.lib.mq5";
//
// START Global Definitions: Variables, Properties and etc ...
//
string alertPrefix = "X-Alert";
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool OnInInitAlertLibrary()
{
return false;
}
//
// DeInitial Library if required ...
void OnDeinitAlertLibrary()
{
}
//
// Attach Alert Prefix to Message ...
string PrepareAlertMessage(string message)
{
//
StringConcatenate(message, alertPrefix, " > ", message);
//
return message;
}
//
// Logging an Alert ...
void LogAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !logAlerts)
{
return;
}
//
LogMessage(alertPrefix, message);
}
//
// Terminal Alert ...
void TerminalAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !terminalAlerts)
{
return;
}
//
// Prepare Message ...
message = PrepareAlertMessage(message);
// Send Terminal Alert ...
Alert(message);
}
//
// Mail Alert ...
void MailAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !mailAlerts)
{
return;
}
//
// Send Mail Alert ...
SendMail(alertPrefix, message);
}
//
// Send Push Notification ...
void PushAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !pushAlerts)
{
return;
}
//
// Prepare Message ...
message = PrepareAlertMessage(message);
//
// Send Push Notification Alert ...
SendNotification(message);
}
//
// Alert Sending ...
void SendAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts)
{
return;
}
//
// Log ...
if (logAlerts)
{
LogAlert(message);
}
//
// Terminal ...
if (terminalAlerts)
{
TerminalAlert(message);
}
//
// Mail ...
if (mailAlerts)
{
MailAlert(message);
}
//
// Push ...
if (pushAlerts)
{
PushAlert(message);
}
}
void SendAlert(
XSignal &signal, // the Signal Object which requred to Alert
bool asExecuted = true // determines Alert Signal as Executed Signal or not
)
{
//
// Prepare Message ...
string message = asExecuted ? ExecutedSignalToString(signal) : SignalToString(signal);
//
// Do Alerting ...
SendAlert(message);
}
//
// END Provided Functions ...
//
@@ -0,0 +1,953 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XClass
// Description: provides all classes for use ...
//
//
// 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
//
#include <Trade\Trade.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include "x-saherelm.models.lib.mq5"
//
// END Model Definitions ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
// XSaherElm Trade Class ...
class XCTrade
{
//
// all public features ...
public:
//
// Constructor ...
void XCTrade(
string symbol,
int slippage,
ulong magicNumber)
{
//
mSymbol = symbol;
mSlippage = slippage;
mMagicNumber = magicNumber;
//
mTrader = new CTrade();
//
mTrader.SetAsyncMode(false);
mTrader.SetDeviationInPoints(mSlippage);
mTrader.SetExpertMagicNumber(mMagicNumber);
}
//
// Deconstructor ...
void ~XCTrade()
{
}
//
// Count Open Positions ...
int Count()
{
//
int result = 0;
//
int total = PositionsTotal();
for (int i = 0; i < total; i++)
{
//
if (!mPositionInfo.SelectByIndex(i))
{
continue;
}
//
if (mPositionInfo.Magic() != mMagicNumber)
{
continue;
}
//
if (mPositionInfo.Symbol() != mSymbol)
{
continue;
}
//
result++;
}
//
return result;
}
//
// Count Longs ...
int CountLongs()
{
int result = CountByType(X_SIGNAL_LONG);
return result;
}
//
// Count Shorts ...
int CountShorts()
{
int result = CountByType(X_SIGNAL_SHORT);
return result;
}
//
// Count By Type ...
int CountByType(ENUM_X_SIGNAL_TYPE type)
{
//
// Validate Args ...
ENUM_POSITION_TYPE mType = POSITION_TYPE_BUY;
if (type == X_SIGNAL_LONG)
{
mType = POSITION_TYPE_BUY;
}
else if (type == X_SIGNAL_SHORT)
{
mType = POSITION_TYPE_SELL;
}
//
int result = CountByType(mType);
return result;
}
//
// Retrieve all Positions ...
void GetAllPositions(XSignal &result[])
{
//
ArrayFree(result);
//
int total = Count();
ArrayResize(result, total);
//
int filledIndex = 0;
int totalPositions = PositionsTotal();
for (int i = 0; i < totalPositions; i++)
{
//
if (!mPositionInfo.SelectByIndex(i))
{
continue;
}
//
if (mPositionInfo.Magic() != mMagicNumber)
{
continue;
}
//
if (mPositionInfo.Symbol() != mSymbol)
{
continue;
}
//
result[filledIndex] = PositionToSignal(i);
filledIndex++;
}
}
//
// Retrieve all Long Positions ...
void GetLongPositions(XSignal &result[])
{
GetAllPositionsByType(POSITION_TYPE_BUY, result);
}
//
// Retrieve all Short Positions ...
void GetShortPositions(XSignal &result[])
{
GetAllPositionsByType(POSITION_TYPE_SELL, result);
}
//
// Open a Buy/Long Position ...
bool Buy(
double volume, // position volume
double price, // execution price
double sl = 0, // stop loss price
double tp = 0, // take profit price
const string comment = "" // comment
)
{
//
bool result = false;
//
result = mTrader.Buy(
volume,
mSymbol,
price,
sl,
tp,
comment);
//
return result;
}
//
// Open a Sell/Short Position ...
bool Sell(
double volume, // position volume
double price, // execution price
double sl = 0, // stop loss price
double tp = 0, // take profit price
const string comment = "" // comment
)
{
//
bool result = false;
//
result = mTrader.Sell(
volume,
mSymbol,
price,
sl,
tp,
comment);
//
return result;
}
//
// Validate Signal ...
bool ValidateSignal(XSignal &signal)
{
//
bool result = false;
//
// Validate Signal Type ...
result = signal.type != X_SIGNAL_UNKNOWN;
if (!result)
{
return result;
}
//
// Check Symbol ...
result = StringLen(signal.symbol) == 0 ? true : signal.symbol == mSymbol;
if (!result)
{
return result;
}
//
// Check magic number ...
result = signal.magicNumber <= 0 ? true : signal.magicNumber == mMagicNumber;
if (!result)
{
return result;
}
//
// Check Entry ...
result = signal.entry > 0;
if (!result)
{
return result;
}
//
// Check SL ...
result = signal.sl == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.sl < signal.entry
: signal.sl > signal.entry;
if (!result)
{
return result;
}
//
// Check TP ...
result = signal.tp == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.tp > signal.entry
: signal.tp < signal.entry;
if (!result)
{
return result;
}
//
// Check Volume ...
result = signal.volume > 0;
if (!result)
{
return result;
}
//
// Check Time ...
result = signal.time > 0;
if (!result)
{
return result;
}
//
return result;
}
//
// Execute an Specific XSignal instance ...
bool ExecuteSignal(XSignal &signal)
{
//
bool result = ValidateSignal(signal);
if (!result)
{
return result;
}
//
signal.symbol = mSymbol;
//
result = signal.type == X_SIGNAL_LONG ? Buy(
signal.volume,
signal.entry,
signal.sl,
signal.tp,
signal.comment)
: signal.type == X_SIGNAL_SHORT ? Sell(
signal.volume,
signal.entry,
signal.sl,
signal.tp,
signal.comment)
: false;
//
return result;
}
//
// Modify Position ...
bool Modify(
const ulong ticket, // position ticket
double sl = 0, // stop loss price
double tp = 0 // take profit
)
{
//
bool result = false;
//
// Validate Args ...
if (tp <= 0 && sl <= 0)
{
result = false;
return result;
}
//
result = mTrader.PositionModify(
ticket,
sl,
tp);
//
return result;
}
//
// Close Position By Ticket ...
bool Close(ulong ticket)
{
//
bool result = false;
//
// Try to Select Position ...
if (!mPositionInfo.SelectByTicket(ticket))
{
//
result = false;
return result;
}
//
result = mTrader.PositionClose(ticket);
//
return result;
}
//
// Close Partial By Ticket ...
bool ClosePartial(ulong ticket, double volume)
{
//
bool result = false;
//
if (!mPositionInfo.SelectByTicket(ticket))
{
//
result = false;
return result;
}
//
mTrader.PositionClosePartial(
ticket,
volume);
//
return result;
}
//
// Close All Positions ...
void CloseAllPositions()
{
//
// Count all Specified Positions ...
int total = Count();
if (total <= 0)
{
return;
}
//
XSignal allPositions[];
GetAllPositions(allPositions);
//
int allPositionsSize = ArraySize(allPositions);
if (allPositionsSize == 0 || allPositionsSize != total)
{
return;
}
//
for (int i = 0; i < total; i++)
{
//
XSignal signal = allPositions[i];
bool isClosed = Close(signal.ticket);
}
}
//
// Close All Longs Positions ...
void CloseLongPositions()
{
//
// Count all Specified Positions ...
int total = CountLongs();
if (total <= 0)
{
return;
}
//
XSignal longPositions[];
GetLongPositions(longPositions);
//
int longPositionsSize = ArraySize(longPositions);
if (longPositionsSize == 0 || longPositionsSize != total)
{
return;
}
//
for (int i = 0; i < total; i++)
{
//
XSignal signal = longPositions[i];
bool isClosed = Close(signal.ticket);
}
}
//
// Close All Shorts Positions ...
void CloseShortPositions()
{
//
// Count all Specified Positions ...
int total = CountShorts();
if (total <= 0)
{
return;
}
//
XSignal shortPositions[];
GetShortPositions(shortPositions);
//
int shortPositionsSize = ArraySize(shortPositions);
if (shortPositionsSize == 0 || shortPositionsSize != total)
{
return;
}
//
for (int i = 0; i < total; i++)
{
//
XSignal signal = shortPositions[i];
bool isClosed = Close(signal.ticket);
}
}
//
// all protected features ...
protected:
//
// all private features ...
private:
//
// which Symbol ...
string mSymbol;
//
// using deviation, it must be in Point ...
int mSlippage;
//
// using magic number ...
ulong mMagicNumber;
//
// using CTrade instance ...
CTrade mTrader;
//
// using PositionInfo instance ...
CPositionInfo mPositionInfo;
//
// Count Specific Type Of Positions ...
int CountByType(ENUM_POSITION_TYPE type)
{
//
int result = 0;
//
int total = PositionsTotal();
for (int i = 0; i < total; i++)
{
//
if (!mPositionInfo.SelectByIndex(i))
{
continue;
}
//
if (mPositionInfo.Symbol() != mSymbol)
{
continue;
}
//
if (mPositionInfo.PositionType() != type)
{
continue;
}
//
result++;
}
//
return result;
}
//
// Convert Position to Signal by Index ...
XSignal PositionToSignal(int index)
{
//
XSignal result = {};
//
if (!mPositionInfo.SelectByIndex(index))
{
return result;
}
//
// ID ...
result.id = mPositionInfo.Identifier();
//
// Symbol ...
result.symbol = mPositionInfo.Symbol();
//
// Type ...
ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType();
ENUM_X_SIGNAL_TYPE type = pType == POSITION_TYPE_BUY ? X_SIGNAL_LONG : X_SIGNAL_SHORT;
result.type = type;
//
// MagicNumber ...
result.magicNumber = mPositionInfo.Magic();
//
// Ticket ...
result.ticket = mPositionInfo.Ticket();
//
// Entry/Open Price ...
result.entry = mPositionInfo.PriceOpen();
//
// Take Profit ...
result.tp = mPositionInfo.TakeProfit();
//
// Stop Loss ...
result.sl = mPositionInfo.StopLoss();
//
// Time ...
result.time = mPositionInfo.Time();
//
// Volume ...
result.volume = mPositionInfo.Volume();
//
// Comment ...
result.comment = mPositionInfo.Comment();
//
return result;
}
//
// Get all Positions based on Position Type ...
void GetAllPositionsByType(ENUM_POSITION_TYPE type, XSignal &result[])
{
//
int existsTotal = CountByType(type);
//
ArrayFree(result);
ArrayResize(result, existsTotal);
//
int filledIndex = 0;
int total = PositionsTotal();
for (int i = 0; i < total; i++)
{
//
if (!mPositionInfo.SelectByIndex(i))
{
continue;
}
//
if (mPositionInfo.Magic() != mMagicNumber)
{
continue;
}
//
if (mPositionInfo.Symbol() != mSymbol)
{
continue;
}
//
if (mPositionInfo.PositionType() != type)
{
continue;
}
//
result[filledIndex] = PositionToSignal(i);
filledIndex++;
}
}
};
//
// XSaherElm Account Info Class ...
class XCAccountInfo
{
//
// Public properties ...
public:
//
// Constructro ...
void XCAccountInfo()
{
//
mAccountInfo = new CAccountInfo();
//
mInitialBalance = mAccountInfo.Balance();
}
//
// Deconstructor ...
void ~XCAccountInfo()
{
//
mInitialBalance = 0;
}
//
// User Account ...
long GetUserAccount()
{
return mAccountInfo.Login();
}
//
// Account Leverage ...
long GetLeverage()
{
return mAccountInfo.Leverage();
}
//
// Get Trade Expert State ...
bool CanExpertTrade()
{
return mAccountInfo.TradeExpert();
}
//
// User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ...
ENUM_ACCOUNT_TRADE_MODE GetTradeMode()
{
return mAccountInfo.TradeMode();
}
//
// Get Account Balance ...
double GetBalance()
{
return mAccountInfo.Balance();
}
//
// Get Initial Deposit Balance ...
double GetInitialBalance()
{
return mInitialBalance;
}
//
// Get the amount of give Credit ...
double GetCredit()
{
return mAccountInfo.Credit();
}
//
// Get the amount of current Profit on account ...
double GetProfit()
{
return mAccountInfo.Profit();
}
//
// Get the amount of current Equity on account ...
double GetEquity()
{
return mAccountInfo.Equity();
}
//
// Get the amount of reserved Margin ...
double GetMargin()
{
return mAccountInfo.Margin();
}
//
// Get the amount of free Margin ...
double GetFreeMargin()
{
return mAccountInfo.FreeMargin();
}
//
// Get the Level of Margin ...
double GetMarginLevel()
{
return mAccountInfo.MarginLevel();
}
//
// Get the Level Of Margin for a Deposit ...
double GetMarginCall()
{
return mAccountInfo.MarginCall();
}
//
// Get the Level of Margin for Stop out ...
double GetMarginStopOut()
{
return mAccountInfo.MarginStopOut();
}
//
// Get the Client Name ...
string GetName()
{
return mAccountInfo.Name();
}
//
// Get the Trade Server Name ...
string GetServerName()
{
return mAccountInfo.Server();
}
//
// Get deposit Currency Name ...
string GetCurrency()
{
return mAccountInfo.Currency();
}
//
// Get the Company Name that serves an Account ...
string GetCompany()
{
return mAccountInfo.Company();
}
//
// Calculate Profits for the current account based on passed parameters ...
double CalculateTradeProfit(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry, // open price
double exit // close price
)
{
//
double result = mAccountInfo.OrderProfitCheck(
symbol,
type,
volume,
entry,
exit);
//
return result;
}
//
// Calculate amount of margin which required for trade operation ...
double CalculateMarging(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry // open price
)
{
//
double result = mAccountInfo.MarginCheck(
symbol,
type,
volume,
entry);
//
return result;
}
//
// Calculate amount of free margin left after trade operation ...
double CalculateFreeMarging(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry // open price
)
{
//
double result = mAccountInfo.FreeMarginCheck(
symbol,
type,
volume,
entry);
//
return result;
}
//
// Calculate the Maximum possible volume of trade operation ...
double CalculateMaxVolume(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double entry, // open price
double percent = 100 // percent of available margin
)
{
//
double result = mAccountInfo.MaxLotCheck(
symbol,
type,
entry,
percent);
//
return result;
}
//
// Protected properties ...
protected:
//
// Private properties ...
private:
//
// Initial Account Balance ...
double mInitialBalance;
//
// Account Info ...
CAccountInfo mAccountInfo;
};
//
// END Global Definitions: Variables, Properties and etc ...
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,177 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Http Library
// ------------------------------------------
// Name: XHttp
// Description: provide http communication
// abilities ...
//
//
// 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 Model Definition ...
//
enum X_HTTP_METHOD
{
X_HTTP_GET,
X_HTTP_POST
};
//
// END Model Definition ...
//
//
// START Inputs ...
//
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool OnInInitHttpLibrary()
{
return false;
}
//
// DeInitial Library if required ...
void OnDeinitHttpLibrary()
{
}
//
// Convert enum to String ...
string ToString(X_HTTP_METHOD method)
{
//
string result = "";
//
switch (method)
{
//
case X_HTTP_GET:
result = "GET";
break;
//
case X_HTTP_POST:
result = "POST";
break;
}
//
return result;
}
//
// Send Global Request ...
int SendRequest(
X_HTTP_METHOD method, // Httm Request Method
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
)
{
//
int result = -1;
//
string strMethod = ToString(method);
if (StringLen(strMethod) == 0) {
return result;
}
//
result = WebRequest(
strMethod,
url,
headers,
timeout,
payload,
response,
responseHeaders
);
//
return result;
}
//
// Get Request ...
int GetRequest(
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
) {
//
int result = SendRequest(
X_HTTP_GET,
url,
headers,
payload,
response,
responseHeaders,
timeout
);
//
return result;
}
//
// Post Request ...
int PostRequest(
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
) {
//
int result = SendRequest(
X_HTTP_POST,
url,
headers,
payload,
response,
responseHeaders,
timeout
);
//
return result;
}
//
// END Provided Functions ...
//
@@ -0,0 +1,161 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Logger Library
// ---------------------------------------
// Name: XLogger
// Description: provides Logging abilities ...
//
//
// 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 "Logging";
input bool enableLogging = true; // Enable Logging
//
// END Inputs ...
//
//
// Including Models ...
#include "x-saherelm.models.lib.mq5"
//
// START Global Definitions: Variables, Properties and etc ...
//
string logTag = "X-Logger"; // LogTag
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Logging a Message ...
void LogMessage(string message)
{
//
if (!enableLogging)
{
return;
}
//
Print(logTag, " > ", message);
}
void LogMessage(string tag, string message)
{
//
if (!enableLogging)
{
return;
}
//
Print(tag, " > ", message);
}
//
// Logging an Array ...
void LogArray(int &array[])
{
//
if (!enableLogging)
{
return;
}
//
Print(logTag, ">");
ArrayPrint(array);
}
void LogArray(double &array[])
{
//
if (!enableLogging)
{
return;
}
//
Print(logTag, ">");
ArrayPrint(array);
}
void LogArray(string &array[])
{
//
if (!enableLogging)
{
return;
}
//
Print(logTag, ">");
ArrayPrint(array);
}
//
// Convert a Signal to String Message ...
string SignalToString(XSignal &signal)
{
//
string result = "";
//
result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment;
//
return result;
}
//
// Convert an Executed Signal to String Message ...
string ExecutedSignalToString(XSignal &signal)
{
//
string result = "";
//
result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal Executed provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment;
//
return result;
}
//
// Logging Signal ...
void LogSignal(XSignal &signal)
{
//
string message = SignalToString(signal);
//
LogMessage(message);
}
//
// Log Signal Execution ...
void LogExecutedSignal(XSignal &signal)
{
//
string message = ExecutedSignalToString(signal);
//
LogMessage(message);
}
//
// END Provided Functions ...
//
@@ -0,0 +1,225 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Models Library
// ---------------------------------------
// Name: XModels
// Description: provides all required models ...
//
//
// 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 ...
//
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// START Model Definitions ...
//
//
// OHCL Candel Model ...
enum ENUM_X_PRICE
{
X_PRICE_HIGH,
X_PRICE_OPEN,
X_PRICE_CLOSE,
X_PRICE_LOW
};
struct XOHCL
{
double high;
double open;
double close;
double low;
};
//
// Swing Types Enum ...
enum ENUM_X_SWING_TYPE
{
X_NO_SWING = 0,
X_SWING_HIGH = 1,
X_SWING_LOW = -1,
};
//
// Signal Types ...
enum ENUM_X_SIGNAL_TYPE
{
X_SIGNAL_LONG,
X_SIGNAL_SHORT,
X_SIGNAL_UNKNOWN,
};
//
// Signal Structure ...
struct XSignal
{
//
// Identifier ...
ulong id;
//
// Which Symbol used for Signal ...
string symbol;
//
// Which Type of operations ...
ENUM_X_SIGNAL_TYPE type;
//
// Magic Number ...
ulong magicNumber;
//
// Ticket ...
ulong ticket;
//
// Entry/Open Price ...
double entry;
//
// TP ...
double tp;
//
// SL ...
double sl;
//
// Time of Operation ...
datetime time;
//
// Volume ...
double volume;
//
// Comment ...
string comment;
};
//
// TP/SL Struct ...
struct XTPSL
{
ENUM_X_SIGNAL_TYPE type;
double tp;
double sl;
double entry;
double r2r;
};
//
// XTM Indicator States ...
enum ENUM_X_XTM_STATES
{
X_XTM_BULLISH = 1,
X_XTM_BEARISH = -1,
X_XTM_NEUTURAL = 0,
};
//
// XTM Indicator Buffer Lines ...
enum ENUM_X_XTM_BUFFER_LINES
{
X_XTM_MA_LINE = 0,
X_XTM_MC_COLOR_LINE = 1,
X_XTM_STATE_LINE = 2,
};
//
// XTD Oscillator States ...
enum ENUM_X_XTD_STATES
{
X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2,
X_XTD_BULLISH_OVER_BEARISH = 1,
X_XTD_NEUTURAL = 0,
X_XTD_BULLISH_UNDER_BEARISH = -1,
X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2
};
//
// XTD Oscillator Buffer Lines ...
enum ENUM_X_XTD_BUFFER_LINES
{
X_XTD_BULLISH_POWER_LINE = 0,
X_XTD_BEARISH_POWER_LINE = 1,
X_XTD_TREND_STATE_LINE = 2,
};
//
// XTPD States Enum ...
enum ENUM_X_XTPD_STATES
{
X_XTPD_BULLISH_CROSSED_OVER_BEARISH = 2,
X_XTPD_BULLISH_OVER_BEARISH = 1,
X_XTPD_NEUTURAL = 0,
X_XTPD_BULLISH_UNDER_BEARISH = -1,
X_XTPD_BULLISH_CROSSED_UNDER_BEARISH = -2
};
//
// XTPD Buffer Lines Enum ...
enum ENUM_X_XTPD_BUFFER_LINES
{
X_XTPD_BULLISH_POWER_LINE = 0,
X_XTPD_BEARISH_POWER_LINE = 1,
X_XTPD_STATE_LINE = 2,
};
//
// XCHMA Oscillator Cycles State Presentation ...
enum ENUM_XCHMA_CYCLE_STATE
{
X_XCHMA_FAST_CROSSED_OVER_SLOW = 2,
X_XCHMA_FAST_OVER_SLOW = 1,
X_XCHMA_NEUTURAL = 0,
X_XCHMA_FAST_UNDER_SLOW = -1,
X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2,
};
//
// XCHMA Oscillator Buffer Lines ...
enum ENUM_X_XCHMA_BUFFER_LINES
{
X_XCHMA_LC_FAST_LINE = 0,
X_XCHMA_LC_SLOW_LINE = 1,
X_XCHMA_LC_STATE_LINE = 6,
X_XCHMA_MC_FAST_LINE = 2,
X_XCHMA_MC_SLOW_LINE = 3,
X_XCHMA_MC_STATE_LINE = 7,
X_XCHMA_SC_FAST_LINE = 4,
X_XCHMA_SC_SLOW_LINE = 5,
X_XCHMA_SC_STATE_LINE = 8,
X_XCHMA_HOT_STATE_LINE = 9,
};
//
// END Provided Functions ...
//
@@ -0,0 +1,258 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 NN Class Library
// ----------------------------------------
// Name: XNNClass
// Description: provides all classes for implementing
// Neural Network ...
//
//
// 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 Global Definitions: Variables, Properties and etc ...
//
class XCNNBase
{
//
// Public Definitions ...
public:
//
// Constructor ...
void XCNNBase(
int nodes = 10, // Number of Input Nodes
double starterWeight = 0.5, // start weight for each input
double coEfficient = 0.1, // COEfficient Multiplier
double upperRange = 1, // Upper Normal Range Value
double lowerRange = -1, // Lower Normal Range Value
double learningRates = 0.1 // Back Propagation Learning Rate
) {
//
mNodes = nodes;
mUpperRange = upperRange;
mLowerRange = lowerRange;
mCoEfficient = coEfficient;
mLearningRates = learningRates;
mStarterWeight = starterWeight;
//
ReConstructWeights();
}
//
// Deconstructor ...
void ~XCNNBase() {}
//
// Protected Definitions ...
void NormalizeInputs(double &inputs[], double &result[])
{
//
ArrayFree(result);
ArrayResize(result, 1);
//
// Validate inputs ...
if (ArraySize(inputs) != mNodes)
{
return;
}
//
// Prepare Result ...
ArrayResize(result, mNodes);
//
// Calculating min and max range value ...
double minRangeValue = inputs[ArrayMinimum(inputs)];
double maxRangeValue = inputs[ArrayMaximum(inputs)];
//
// Loop through Inputs nd Normalize them ...
for (int i = 0; i < mNodes; i++)
{
//
double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange;
result[i] = normalValue;
}
}
//
// Hyperbolic Tangent Activation Function ...
double TanHActivationFunction(double weightedInputs)
{
//
double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs));
return result;
}
//
// Calculate Weighted Inputs ...
double CalculateWeightedInputs(
double &inputs[],
bool applyCOEfficient = true)
{
//
double result = 0;
//
// Validate Inputs ...
if (ArraySize(inputs) != mNodes)
{
//
result = -1;
return result;
}
//
for (int i = 0; i < mNodes; i++)
{
result += inputs[i] * mWeights[i];
}
//
// Multiply if required ...
if (applyCOEfficient)
{
result *= mCoEfficient;
}
//
return result;
}
//
// Calculate Hidden Layers ...
virtual double CalculateHiddenLayer(double &inputs[])
{
//
// this is Default Activation Function which used ...
// you can override this by writing your own ...
double totalWeightedInputs = CalculateWeightedInputs(inputs);
double result = TanHActivationFunction(totalWeightedInputs);
//
return result;
}
//
// Calculate Output Layers ...
double CalculateOutputLayer(double &inputs[])
{
//
double result = -1;
//
// Validate Inputs ...
if (ArraySize(inputs) != mNodes) {
return result;
}
//
double normalizedInputs[];
NormalizeInputs(inputs, normalizedInputs);
if (ArraySize(normalizedInputs) != mNodes) {
return result;
}
//
double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs);
//
result = 1 * hiddenLayerResult;
//
return result;
}
//
// Basck Propaggation Learning ...
void BackPropagation(
double &inputs[],
double &outputs,
double targetOutput
) {
//
// Validate Inputs ...
if (ArraySize(inputs) != mNodes) {
return;
}
//
double normalizedInputs[];
NormalizeInputs(inputs, normalizedInputs);
if (ArraySize(normalizedInputs) != mNodes) {
return;
}
//
double error = targetOutput - outputs;
double derivative = 1 - MathPow(outputs, 2);
//
for (int i = 0; i < mNodes; i++) {
//
double gradient = error * derivative * inputs[i];
mWeights[i] = mLearningRates * gradient;
}
}
protected:
//
// Private Definitions ...
private:
//
// Number of Input Nodes ...
int mNodes;
//
// Specify Upper range of Normal Values ...
double mUpperRange;
//
// Specify Lower range of Normal Values ...
double mLowerRange;
//
// Starter Weight for each input node ...
double mStarterWeight;
//
// double Input Node Weights ...
double mWeights[];
//
// CoEfficient is a multiplyer for weighted inputs ...
double mCoEfficient;
//
// Back Propagation Learning Rates ...
double mLearningRates;
//
// ReConstruct Weights ...
void ReConstructWeights() {
//
ArrayFree(mWeights);
ArrayResize(mWeights, mNodes);
//
for (int i = 0; i< mNodes; i++) {
mWeights[i] = mStarterWeight;
}
}
}
//
// END Global Definitions: Variables, Properties and etc ...
//
@@ -0,0 +1,947 @@
////////////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 RSI Signal Provider Library
// --------------------------------------------------------
// Name: XRSISignalProvider
// Description: RSI 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 "XRSI Provider";
//
input group "XRSI Common";
input bool enableRSIProvider = true; // Enable Provider
input bool rsiEnableAlerts = true; // Enable Events Alert
//
input group "XRSI Indicator";
input int rsiPeriod = 14; // RSI Period
input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // RSI Applied To
//
input group "XRSI Trader";
input int rsiMagicNumber = 16940561; // RSI Trader MagicNumber
input int rsiSlippage = 10; // RSI Trader Slippage
input double rsiLongEntryLevel = 30; // RSI Long Entry Level
input double rsiLongExitLevel = 60; // RSI Long Exit Level
input double rsiShortEntryLevel = 70; // RSI Short Entry Level
input double rsiShortExitLevel = 40; // RSI Short Exit Level
//
input group "XRSI Neural Networks";
input bool rsiUseNeuralNetworks = true; // Enable Neural Networks
input bool rsiNNUseContinuesLearning = true; // Enable Continues Learning on Neural Networks
input int rsiNNNumberOfNodes = 10; // Number Of Input Nodes
input double rsiNNLongTargetOutput = 0.3; // BackPropagation Target Output for Long Trades
input double rsiNNShortTargetOutput = -0.3; // BackPropagation Target Output for Short Trades
//
input group "XRSI Trade Management";
input bool rsiAllowLongTrades = true; // Allow Long Trades
input bool rsiAllowShortTrades = true; // Allow Short Trades
input bool rsiUseGridTrades = true; // Enable Grid Trades
input double rsiGridVolumeMultiplier = 2; // Grid Volume Multiplier
input double rsiGridDistancePips = 10; // Grid Position Distance in Pips
//
input group "XRSI Risk Management";
input bool rsiUseDynamicVolume = true; // Enable Dynamic Volume
input double rsiStaticVolume = 0.01; // Static Volume
// input double rsiBalanceIncreasedFactor = 0.1; // RSI Balance Increase Factor
// input double rsiVolumeIncreasedFactor = 0.000001; // RSI Volume Increase Factor
// //
// // END Inputs ...
// //
input double rsiBalanceIncreased = 500; // RSI Balance Increase
input double rsiVolumeIncreased = 0.01; // RSI 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"
//
// Include Neural Networks Library ...
#include "x-saherelm.nn.lib.mq5";
//
// START Global Definitions: Variables, Properties and etc ...
//
int rsiHandler = INVALID_HANDLE;
double rsiBuffer[];
//
XCTrade *rsiTrader;
XCAccountInfo rsiAccountInfo;
//
XCNNBase *rsiNN;
//
double rsiGridLongPrice = 0;
double rsiGridLongVolume = 0;
//
double rsiGridShortPrice = 0;
double rsiGridShortVolume = 0;
//
// holds Neural Networks Output Value ...
double rsiNNOutput;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool OnInInitXRSISignalProviderLibrary()
{
//
bool result = false;
//
// Error Message ...
string message = "";
//
// Check RSI Period ...
if (rsiPeriod < 5)
{
//
message = "invalid rsi period ...";
LogMessage(message);
//
return result;
}
//
// Check RSI Over Baught and Over Sold Levels ...
if (
rsiLongExitLevel <= 0 ||
rsiLongEntryLevel <= 0 ||
rsiShortExitLevel <= 0 ||
rsiShortEntryLevel <= 0 ||
rsiLongEntryLevel >= rsiLongExitLevel ||
rsiLongEntryLevel >= rsiShortEntryLevel ||
rsiShortEntryLevel <= rsiShortExitLevel ||
rsiShortEntryLevel <= rsiLongEntryLevel)
{
//
message = "invalid over baught / over seld level ...";
LogMessage(message);
//
return result;
}
//
// Check Risk Management ...
if (rsiUseDynamicVolume)
{
//
// if (rsiBalanceIncreasedFactor <= 0 || rsiVolumeIncreasedFactor <= 0)
if (rsiBalanceIncreased <= 0 || rsiVolumeIncreased <= 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 (rsiStaticVolume > maxAvailableVolume || rsiStaticVolume < minAvailableVolume)
{
//
message = "invalid static volume ...";
LogMessage(message);
//
return result;
}
}
//
// Check Neural Networks Inputs ...
if (rsiUseNeuralNetworks)
{
//
// Number Of Nodes ...
if (rsiNNNumberOfNodes < 3)
{
//
message = "invalid neurak networks inputs ...";
LogMessage(message);
//
return result;
}
//
// if there is no error in nn inputs, make an instance of
// Neural Networks Clsss ...
rsiNN = new XCNNBase(
rsiNNNumberOfNodes);
}
//
// Preparing RSI Handler ...
rsiHandler = iRSI(_Symbol, _Period, rsiPeriod, rsiAppliedTo);
if (rsiHandler == INVALID_HANDLE)
{
//
message = "failed to initialize rsi indicator handler ...";
LogMessage(message);
//
return result;
}
//
// Make XCTrader instance ...
rsiTrader = new XCTrade(
_Symbol,
rsiSlippage,
rsiMagicNumber);
//
result = true;
//
// Logging State ...
message = "Initializion of (" + "XRSI Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
LogMessage(message);
//
return result;
}
//
// DeInitial Library if required ...
void OnDeinitXRSISignalProviderLibrary()
{
//
// Logging State ...
string message = "De Initializion of (" + "XRSI Provider" + ") Succeeded ...";
LogMessage(message);
}
//
// this is a Globally Function which do all of
// checkings and positions handling ...
void HandleXSignalProviderTick()
{
//
// Reading RSI Values ...
ArraySetAsSeries(rsiBuffer, true);
//
// Copy RSI Buffers based on NN Conditions ...
if (rsiUseNeuralNetworks)
{
//
CopyBuffer(rsiHandler, 0, 0, rsiNNNumberOfNodes, rsiBuffer);
//
// Calculate Neural Network Output Layer based on Inputs ...
// since here there is no any external inputs except rsiBuffer
// we passed it directly to our Neural Networks as Inputs ...
rsiNNOutput = rsiNN.CalculateOutputLayer(rsiBuffer);
//
// Check Continues Learning is Enabled ...
if (rsiNNUseContinuesLearning)
{
//
// Handle Back Propagation (Continues Learning) ...
double targetOutput = 0;
if (rsiBuffer[1] >= 50)
{
targetOutput = rsiNNLongTargetOutput;
}
else if (rsiBuffer[1] < 50)
{
targetOutput = rsiNNShortTargetOutput;
}
//
// Handle Calculate Weights ...
if (targetOutput != 0)
{
rsiNN.BackPropagation(rsiBuffer, rsiNNOutput, targetOutput);
}
}
}
else
{
CopyBuffer(rsiHandler, 0, 0, 5, rsiBuffer);
}
//
// Handle Open Trades ...
HandleOpenTrades();
//
// Handle Close Trades ...
HandleCloseTrades();
//
// Draw Signals ...
// bool hasPrimaryLongSignal = HasPrimaryLongSignal();
// bool hasPrimaryShortSignal = HasPrimaryShortSignal();
// bool hasPrimarySignal = hasPrimaryLongSignal || hasPrimaryShortSignal;
// if (hasPrimarySignal)
// {
// //
// ENUM_X_SIGNAL_TYPE signalType = hasPrimaryLongSignal ? X_SIGNAL_LONG : X_SIGNAL_SHORT;
// double signalPrice = signalType == X_SIGNAL_LONG ? GetAsk() : GetBid();
// string signalName = logTag + "_" + EnumToString(signalType) + "_" + DoubleToString(signalPrice);
// color signalColor = signalType == X_SIGNAL_LONG ? clrAqua : clrYellow;
// datetime signalTime1 = iTime(_Symbol, _Period, 1);
// datetime signalTime2 = iTime(_Symbol, _Period, 0);
// //
// DrawTrendLine(
// 0, // Chart Id ...
// signalName, // Object Name ...
// 0, // SubWindow ...
// signalTime1, // Time 1 ...
// signalPrice, // Price 1 ...
// signalTime2, // Time 2 ...
// signalPrice, // Price 2 ...
// signalColor, // Color ...
// STYLE_SOLID,
// 5
// );
// }
}
//
// Check Market Conditions to find Long Primary Signals ...
bool HasPrimaryLongSignal()
{
//
bool result = false;
//
// Check Buy/Long Conditions ...
result = rsiBuffer[1] >= rsiLongEntryLevel && rsiBuffer[2] < rsiLongEntryLevel;
//
return result;
}
//
// Check Market Conditions to find Short Primary Signals ...
bool HasPrimaryShortSignal()
{
//
bool result = false;
//
// Check Sell/Short Conditions ...
result = rsiBuffer[1] <= rsiShortEntryLevel && rsiBuffer[2] > rsiShortEntryLevel;
//
return result;
}
//
// Check Market Conditions to find Long Grid Signals ...
bool HasGridLongSignal()
{
//
bool result = false;
//
// Check Buy/Long Conditions ...
result = rsiBuffer[1] >= rsiLongEntryLevel && rsiBuffer[2] < rsiLongEntryLevel;
//
return result;
}
//
// Check Market Conditions to find Short Grid Signals ...
bool HasGridShortSignal()
{
//
bool result = false;
//
// Check Sell/Short Conditions ...
result = rsiBuffer[1] <= rsiShortEntryLevel && rsiBuffer[2] > rsiShortEntryLevel;
//
return result;
}
//
// Check Market Conditions for closing Long Trades ...
bool CanCloseLongTrades()
{
//
bool result = rsiBuffer[1] > rsiLongExitLevel && rsiBuffer[2] < rsiLongExitLevel;
return result;
}
//
// Check Market Conditions for closing Short Trades ...
bool CanCloseShortTrades()
{
//
bool result = rsiBuffer[1] < rsiShortExitLevel && rsiBuffer[2] > rsiShortExitLevel;
return result;
}
//
// Handle Long/Buy for Primary Trades...
bool HandlePrimaryLong(
XSignal &signal, // return structure if signal founded
bool doTrade = true // do trade on signal
)
{
//
bool result = false;
//
ResetLastError();
//
// Check Conditions of Neural Networks if it's enabled ...
bool canForward = !rsiUseNeuralNetworks ? true : rsiNNOutput > 0;
//
if (HasPrimaryLongSignal() && rsiTrader.CountLongs() == 0 && canForward)
{
//
double entry = GetAsk();
double volume = CalculateVolume();
//
double canDoTrade = CanDoTrade();
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_LONG;
signal.magicNumber = rsiMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Primary XRSI Long";
//
if (enableRSIProvider && rsiAllowLongTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = rsiTrader.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 (rsiEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Short/Sell for Primary Trades...
bool HandlePrimaryShort(
XSignal &signal, // return structure if signal founded
bool doTrade = true // do trade on signal
)
{
//
bool result = false;
//
ResetLastError();
//
// Check Conditions of Neural Networks if it's enabled ...
bool canForward = !rsiUseNeuralNetworks ? true : rsiNNOutput < 0;
//
if (HasPrimaryShortSignal() && rsiTrader.CountShorts() == 0 && canForward)
{
//
double entry = GetBid();
double volume = CalculateVolume();
//
double canDoTrade = CanDoTrade();
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_SHORT;
signal.magicNumber = rsiMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Primary XRSI Short";
//
if (enableRSIProvider && rsiAllowShortTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = rsiTrader.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 (rsiEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Long/Buy for Grid Trades...
bool 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 <= rsiGridLongPrice;
if (HasGridLongSignal() && rsiTrader.CountLongs() > 0 && canDoGridTrade)
{
//
double entry = ask;
double volume = rsiGridLongVolume;
//
double canDoTrade = CanDoTrade();
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_LONG;
signal.magicNumber = rsiMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Grid XRSI Long";
//
if (enableRSIProvider && rsiAllowLongTrades && rsiUseGridTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = rsiTrader.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 (rsiEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Short/Sell for Grid Trades...
bool 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 >= rsiGridShortPrice;
if (HasGridShortSignal() && rsiTrader.CountShorts() > 0 && canDoGridTrade)
{
//
double entry = bid;
double volume = rsiGridShortVolume;
//
double canDoTrade = CanDoTrade();
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_SHORT;
signal.magicNumber = rsiMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Grid XRSI Short";
//
if (enableRSIProvider && rsiAllowShortTrades && rsiUseGridTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = rsiTrader.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 (rsiEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Open Trades ...
void HandleOpenTrades()
{
//
// Primary Long Trade ...
XSignal primaryLongSignal = {};
bool isPrimaryLongSignalExecuted = HandlePrimaryLong(primaryLongSignal);
if (isPrimaryLongSignalExecuted)
{
//
// Calculate Grid Long Conditions ...
CalculateGridLongConditions(primaryLongSignal);
}
//
// Primary Short Trade ...
XSignal primaryShortSignal = {};
bool isPrimaryShortSignalExecuted = HandlePrimaryShort(primaryShortSignal);
if (isPrimaryShortSignalExecuted)
{
//
// Calculate Grid Short Conditions ...
CalculateGridShortConditions(primaryShortSignal);
}
//
// Check Grid Trades ...
if (rsiUseGridTrades)
{
//
// Grid Long Trade ...
XSignal gridLongSignal = {};
bool isGridLongSignalExecuted = HandleGridLong(gridLongSignal);
if (isGridLongSignalExecuted)
{
//
// Calculate Grid Long Conditions ...
CalculateGridLongConditions(gridLongSignal);
}
//
// Grid Short Trade ...
XSignal gridShortSignal = {};
bool isGridShortSignalExecuted = HandleGridShort(gridShortSignal);
if (isGridShortSignalExecuted)
{
//
// Calculate Grid Short Conditions ...
CalculateGridShortConditions(gridShortSignal);
}
}
}
//
// Handle Close Trades ...
void HandleCloseTrades()
{
//
// Handle Long/Buy Close ...
if (rsiTrader.CountLongs() > 0 && CanCloseLongTrades())
{
//
rsiTrader.CloseLongPositions();
//
// Reset Grid Long Conditions ...
rsiGridLongPrice = 0;
rsiGridLongVolume = 0;
//
string message = "XRSI Closing Long Trades ...";
//
if (rsiEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
//
// Handle Short/Sell Close ...
if (rsiTrader.CountShorts() > 0 && CanCloseShortTrades())
{
//
rsiTrader.CloseShortPositions();
//
// Reset Grid Short Conditions ...
rsiGridShortPrice = 0;
rsiGridShortVolume = 0;
//
string message = "XRSI Closing Short Trades ...";
//
if (rsiEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
}
//
// Calculating Volume for Tradings ...
double CalculateVolume()
{
//
double result = rsiStaticVolume;
if (!rsiUseDynamicVolume)
{
return result;
}
//
double accountBalance = rsiAccountInfo.GetBalance();
// double accountInitialBalance = rsiAccountInfo.GetInitialBalance();
// double balanceIncreased = accountInitialBalance * rsiBalanceIncreasedFactor;
// double volumeIncreased = accountInitialBalance * rsiVolumeIncreasedFactor;
double balanceIncreased = rsiBalanceIncreased;
double volumeIncreased = rsiVolumeIncreased;
//
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 CalculateGridLongConditions(XSignal &signal)
{
//
// Check Grid Trades Enable ...
if (!rsiUseGridTrades)
{
return;
}
//
// Calculate GridLongPrice and GridLongVolume ...
rsiGridLongVolume = NormalizeDouble(signal.volume * rsiGridVolumeMultiplier, 2);
rsiGridLongPrice = NormalizeDouble(signal.entry - (rsiGridDistancePips * 10 * _Point), _Digits);
}
//
// Calculate Grid Short Trades Price and Volume ...
void CalculateGridShortConditions(XSignal &signal)
{
//
// Check Grid Trades Enable ...
if (!rsiUseGridTrades)
{
return;
}
//
// Calculate GridShortPrice and GridShortVolume ...
rsiGridShortVolume = NormalizeDouble(signal.volume * rsiGridVolumeMultiplier, 2);
rsiGridShortPrice = NormalizeDouble(signal.entry + (rsiGridDistancePips * 10 * _Point), _Digits);
}
//
// Determine based on current account state
bool CanDoTrade()
{
//
bool result = true;
//
// TODO: Complete this ...
//
return true;
}
//
// END Provided Functions ...
//
@@ -0,0 +1,758 @@
////////////////////////////////////////////////////////////
//
// 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 ...
//
@@ -0,0 +1,756 @@
////////////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 XOBD Signal Provider Library
// --------------------------------------------------------
// Name: XSignalProvider
// Description: 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 "XOBD Provider";
//
input group "XOBD Common";
input bool enableXOBDProvider = true; // Enable Provider
input bool xOBDEnableAlerts = true; // Enable Events Alert
//
input group "XOBD Indicator";
input int xOBDLength = 5; // Market Length
input double xOBDArrowDistanceFromPrice = 0; // Arrow Distrance from Price
input uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code
input color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color
input uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code
input color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color
//
input group "XOBD Trader";
input int xOBDMagicNumber = 16940562; // Trader MagicNumber
input int xOBDSlippage = 10; // Trader Slippage
//
input group "XOBD Trade Management";
input bool xOBDAllowLongTrades = true; // Allow Long Trades
input bool xOBDAllowShortTrades = false; // Allow Short Trades
input int xOBDMaxOpenTrades = 4; // Max Open Trades at Same Time
//
input group "XOBD Risk Management";
input bool xOBDUseTPSL = true; // Allow use TP and SL
input bool xOBDUseVirtualTPSL = false; // Allow Use Virtual TP and SL
input bool xOBDDrawTPSL = true; // Draw TP and SL
input double xOBDR2r = 1.5; // Risk To Reward Ratio
input int xOBDLoopback = 3; // Loopback Length for TP/SL Calculation
input double xOBDMinRiskPerTrade = 100; // Min Risk Per Trade in Points
input double xOBDMaxRiskPerTrade = 1000; // Max Risk Per Trade in Points
input bool xOBDUseDynamicVolume = false; // Enable Dynamic Volume
input double xOBDStaticVolume = 0.01; // Static Volume
input double xOBDBalanceIncreased = 500; // Balance Increase
input double xOBDVolumeIncreased = 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 ...
//
//
int xOBDHandler = INVALID_HANDLE;
double xOBDBuffer[];
//
XCTrade *xOBDTrader;
XCAccountInfo xOBDAccountInfo;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool OnInInitXOBDSignalProviderLibrary()
{
//
bool result = false;
//
// Error Message ...
string message = "";
//
ResetLastError();
xOBDHandler = iCustom(
_Symbol,
_Period,
"x-saherelm.xobd.indicator",
//
xOBDLength,
xOBDArrowDistanceFromPrice,
xOBDSwingHighArrowCode,
xOBDSwingHighArrowColor,
xOBDSwingLowArrowCode,
xOBDSwingLowArrowColor);
if (xOBDHandler == INVALID_HANDLE)
{
//
LogMessage("error initializing XOBD Indicator: " + (string)GetLastError());
return result;
}
//
// Check Risk Management ...
if (xOBDUseDynamicVolume)
{
//
if (xOBDBalanceIncreased <= 0 || xOBDVolumeIncreased <= 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 (xOBDStaticVolume > maxAvailableVolume || xOBDStaticVolume < minAvailableVolume)
{
//
message = "invalid static volume ...";
LogMessage(message);
//
return result;
}
}
//
// Validate use TPSL ...
if (xOBDUseTPSL)
{
//
if (xOBDR2r < 1.2)
{
//
LogMessage("Risk to Rewadrd Ratio is too small ...");
//
return result;
}
}
//
// Make XCTrader instance ...
xOBDTrader = new XCTrade(
_Symbol,
xOBDSlippage,
xOBDMagicNumber);
//
result = true;
//
// Logging State ...
message = "Initializion of (" + "XOBD Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
LogMessage(message);
//
return result;
}
//
// DeInitial Library if required ...
void OnDeinitXOBDSignalProviderLibrary()
{
//
// Logging State ...
string message = "De Initializion of (" + "XOBD Provider" + ") Succeeded ...";
LogMessage(message);
}
//
// this is a Globally Function which do all of
// checkings and positions handling ...
void HandleXOBDSignalProviderTick()
{
//
// Reding XOBD Buffer ...
CopyBuffer(xOBDHandler, 0, 0, 5, xOBDBuffer);
//
// Handle Open Trades ...
XOBDHandleOpenTrades();
//
// Handle Close Trades ...
XOBDHandleCloseTrades();
}
//
// Check Market Conditions to find Long Primary Signals ...
bool XOBDHasPrimaryLongSignal()
{
//
bool result = false;
//
// Check Buy/Long Conditions ...
// Swing Low is a sign of Bullish Trend ...
result = xOBDBuffer[4] == -1;
//
return result;
}
//
// Check Market Conditions to find Short Primary Signals ...
bool XOBDHasPrimaryShortSignal()
{
//
bool result = false;
//
// Check Sell/Short Conditions ...
// Swing High is a sign of Bearish Trend ...
result = xOBDBuffer[4] == 1;
//
return result;
}
//
// Check Market Conditions for closing Long Trades ...
bool XOBDCanCloseLongTrades()
{
//
bool result = false;
//
// Check Market Conditions for Closing
// Long Trades ...
// result = xOBDBuffer[4] == 1;
//
return result;
}
//
// Check Market Conditions for closing Short Trades ...
bool XOBDCanCloseShortTrades()
{
//
bool result = false;
//
// Check Market Conditions for Closing
// Short Trades ...
// result = xOBDBuffer[4] == -1;
//
return result;
}
//
// Handle Long/Buy for Primary Trades...
bool XOBDHandlePrimaryLong(
XSignal &signal, // return structure if signal founded
bool doTrade = true // do trade on signal
)
{
//
bool result = false;
//
ResetLastError();
//
// && xOBDTrader.CountLongs() == 0
if (XOBDHasPrimaryLongSignal())
{
//
double entry = GetAsk();
double volume = XOBDCalculateVolume();
//
double canDoTrade = XOBDCanDoTrade();
//
// Handle TP SL if it's enabled ...
if (xOBDUseTPSL)
{
XTPSL mTpSl = XOBDCalculateTPSL(X_SIGNAL_LONG, entry);
if (IsValid(mTpSl))
{
//
// Check for Draw TP and SL ...
if (xOBDDrawTPSL)
{
XOBDDrawTPSL(mTpSl);
}
//
// Set TP SL in Signal if it's required to add directly ...
if (!xOBDUseVirtualTPSL)
{
//
signal.tp = mTpSl.tp;
signal.sl = mTpSl.sl;
}
//
// Draw Virtual TP SL for Closing Trades ...
else
{
//
// TODO: implement this ...
}
}
}
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_LONG;
signal.magicNumber = xOBDMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Primary XOBD Long";
//
if (enableXOBDProvider && xOBDAllowLongTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = xOBDTrader.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 (xOBDEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Short/Sell for Primary Trades...
bool XOBDHandlePrimaryShort(
XSignal &signal, // return structure if signal founded
bool doTrade = true // do trade on signal
)
{
//
bool result = false;
//
ResetLastError();
//
// && xOBDTrader.CountShorts() == 0
if (XOBDHasPrimaryShortSignal())
{
//
double entry = GetBid();
double volume = XOBDCalculateVolume();
//
double canDoTrade = XOBDCanDoTrade();
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_SHORT;
signal.magicNumber = xOBDMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Primary XOBD Short";
//
if (enableXOBDProvider && xOBDAllowShortTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = xOBDTrader.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 (xOBDEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Open Trades ...
void XOBDHandleOpenTrades()
{
//
// Primary Long Trade ...
XSignal primaryLongSignal = {};
bool isPrimaryLongSignalExecuted = XOBDHandlePrimaryLong(primaryLongSignal);
if (isPrimaryLongSignalExecuted)
{
}
//
// Primary Short Trade ...
XSignal primaryShortSignal = {};
bool isPrimaryShortSignalExecuted = XOBDHandlePrimaryShort(primaryShortSignal);
if (isPrimaryShortSignalExecuted)
{
}
}
//
// Handle Close Trades ...
void XOBDHandleCloseTrades()
{
//
// Handle Long/Buy Close ...
if (xOBDTrader.CountLongs() > 0 && XOBDCanCloseLongTrades())
{
//
xOBDTrader.CloseLongPositions();
//
string message = "XOBD Closing Long Trades ...";
//
if (xOBDEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
//
// Handle Short/Sell Close ...
if (xOBDTrader.CountShorts() > 0 && XOBDCanCloseShortTrades())
{
//
xOBDTrader.CloseShortPositions();
//
string message = "XOBD Closing Short Trades ...";
//
if (xOBDEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
}
//
// Calculating Volume for Tradings ...
double XOBDCalculateVolume()
{
//
double result = xOBDStaticVolume;
if (!xOBDUseDynamicVolume)
{
return result;
}
//
double accountBalance = xOBDAccountInfo.GetBalance();
double balanceIncreased = xOBDBalanceIncreased;
double volumeIncreased = xOBDVolumeIncreased;
//
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 TP and SL ...
XTPSL XOBDCalculateTPSL(
ENUM_X_SIGNAL_TYPE type, // Which Type to Calculate TP and SL
double entry // Signal Entry Price
)
{
//
XTPSL result = {};
result.type = X_SIGNAL_UNKNOWN;
result.tp = 0;
result.sl = 0;
result.r2r = 0;
result.entry = 0;
//
if (!xOBDUseTPSL)
{
return result;
}
//
// Validate Args ...
if (entry <= 0 || type == X_SIGNAL_UNKNOWN)
{
return result;
}
//
result.type = type;
result.r2r = xOBDR2r;
result.entry = entry;
//
bool isLong = type == X_SIGNAL_LONG;
//
// Retrieve Market Highest High and Lowest Low ...
double hh = GetHighestHigh(
xOBDLoopback,
0);
double ll = GetLowestLow(
xOBDLoopback,
0);
//
double maxRisk = xOBDMaxRiskPerTrade * _Point;
double minRisk = xOBDMinRiskPerTrade * _Point;
//
// Calculate and Normalize risk ...
double risk = isLong ? entry - ll : hh - entry;
// if (risk > maxRisk)
// {
// risk = maxRisk;
// }
// else if (risk < minRisk)
// {
// risk = minRisk;
// }
//
double reward = risk * xOBDR2r;
//
double tp = isLong ? entry + reward : entry - reward;
double sl = isLong ? entry - risk : entry + risk;
//
tp = NormalizeDouble(tp, _Digits);
sl = NormalizeDouble(sl, _Digits);
//
result.tp = tp;
result.sl = sl;
//
return result;
}
//
// Determine based on current account state
bool XOBDCanDoTrade()
{
//
bool result = false;
//
// Check Max Open Trades ...
int totalOpenTrades = xOBDTrader.Count();
result = totalOpenTrades <= xOBDMaxOpenTrades;
if (!result)
{
return result;
}
//
return result;
}
//
// START Draw Functions ...
//
void XOBDDrawTPSL(
XTPSL &model // an instance of XTPS structure
)
{
//
// Validate Args ...
if (!IsValid(model))
{
return;
}
//
string entryName = "T_" + EnumToString(model.type) + "_Entry_" + (string)model.entry;
string slName = entryName + "_SL_" + (string)model.sl;
string tpName = entryName + "_TP_" + (string)model.tp;
datetime time1 = iTime(_Symbol, _Period, 2);
datetime time2 = iTime(_Symbol, _Period, 0);
color tpColor = xOBDSwingLowArrowColor;
color slColor = xOBDSwingHighArrowColor;
//
// Draw Entry ...
DrawTrendLine(
0,
entryName,
0,
time1,
model.entry,
time2,
model.entry,
clrYellow);
//
// Draw TP ...
if (model.tp > 0)
{
//
DrawTrendLine(
0,
tpName,
0,
time1,
model.tp,
time2,
model.tp,
tpColor);
}
//
// Draw SL ...
if (model.sl > 0)
{
//
DrawTrendLine(
0,
slName,
0,
time1,
model.sl,
time2,
model.sl,
slColor);
}
}
//
// END Draw Functions ...
//
//
// END Provided Functions ...
//
File diff suppressed because it is too large Load Diff