Files
xMQL5/BKPS/Series2/Temp/Libraries/x-saherelm.xobd.provider.lib.mq5
T
2024-01-25 04:09:42 +03:30

757 lines
16 KiB
Plaintext

////////////////////////////////////////////////////////////
//
// 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 ...
//