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

1006 lines
20 KiB
Plaintext

////////////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 XCHLH Signal Provider Library
// --------------------------------------------------------
// Name: XCHLHSignalProvider
// Description: XCHLH based signal provider ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
#define XCHLHProviderName "XCHLH"
//
// START Inputs ...
//
#include "x-saherelm.xchlh.provider.inputs.lib.mq5";
//
// END Inputs ...
//
//
// Include Common Library ...
#include "x-saherelm.common.lib.mq5"
//
// Include Logger Library ...
#include "x-saherelm.log.lib.mq5"
//
// Include Alert Library ...
#include "x-saherelm.alert.lib.mq5"
//
// Include Draw Library ...
#include "x-saherelm.draw.lib.mq5"
//
// Include Class Libraries ...
#include "x-saherelm.class.lib.mq5"
//
// START Global Definitions: Variables, Properties and etc ...
//
//
XCTrade *xCHLHTrader;
XCAccountInfo xCHLHAccountInfo;
//
#include "x-saherelm.xchlh.provider.indicators.lib.mq5"
//
double xCHLHDeposit = 0;
double xCHLHBalance = 0;
double xCHLHFreeMargin = 0;
double xCHLHMinRewardPerTrade = 0;
double xCHLHFreeMarginForOpenTrades = 0;
double xCHLHBalanceForOpenTrades = 0;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool XCHLHInitSignalProviderLibrary()
{
//
bool result = false;
//
// Validate Inputs ...
result = XCHLHValidateInputs();
if (!result)
{
return result;
}
//
// Init Indicators ...
result = XCHLHInitIndicators();
if (!result)
{
return result;
}
//
// Calculate Account Deposit ...
xCHLHDeposit = xCHLHAccountInfo.GetInitialBalance();
//
// Calculate xCHLHMinRewardPerTrade ...
if (xCHLHMinRewardPerTradeInPips > 0)
{
xCHLHMinRewardPerTrade = PipsToPrice(xCHLHMinRewardPerTradeInPips);
}
//
// Calculate Min Balance for Trades ...
if (xCHLHBalanceFactorForOpenTrades > 0)
{
xCHLHBalanceForOpenTrades = xCHLHBalanceFactorForOpenTrades * xCHLHDeposit;
}
//
// Claculate Min Free Marging for Trades ...
if (xCHLHFreeMarginFactorForOpenTrades > 0)
{
xCHLHFreeMarginForOpenTrades = xCHLHFreeMarginFactorForOpenTrades * xCHLHDeposit;
}
//
// Make XCTrader instance ...
xCHLHTrader = new XCTrade(
_Symbol,
xCHLHSlippage,
xCHLHMagicNumber);
//
result = true;
//
// Logging State ...
XCHLHIssueInitializationSucceedAlert();
//
return result;
}
//
// DeInitial Library if required ...
void XCHLHDeinitSignalProviderLibrary(
const int reason)
{
//
// Release Handlers ...
XCHLHReleaseIndicators();
//
// Logging State ...
XCHLHIssueDeinitializationSucceedAlert();
}
//
// this is a Globally Function which do all of
// checkings and positions handling ...
void XCHLHSignalProviderHandleTick()
{
//
// Update account Balance ...
xCHLHBalance = xCHLHAccountInfo.GetBalance();
xCHLHFreeMargin = xCHLHAccountInfo.GetFreeMargin();
//
// Check Provider is Enable or Not ...
if (!xCHLHEnableProvider)
{
return;
}
//
// Reading Indicator Buffers ...
XCHLHHandleReadingBuffers();
if (xCHLHCalculatedBars < xCHLHMaxLengthOfInputs)
{
return;
}
//
// Handle Open Trades ...
XCHLHHandleOpenTrades();
//
// Handle Close Trades ...
XCHLHHandleCloseTrades();
//
// Handle Support Trades ...
XCHLHHandleSupportTrades();
}
//
// Handle Open Trades ...
void XCHLHHandleOpenTrades()
{
//
// Check Can Trade ...
bool canTrade = xCHLHAllowLongTrades || xCHLHAllowShortTrades;
if (!canTrade)
{
return;
}
//
// First Check Signal Exists or NOt ...
bool xCHLHHasLongSignal = XCHLHCanOpenLongTrade();
bool xCHLHHasShortSignal = XCHLHCanOpenShortTrade();
if (!xCHLHHasLongSignal && !xCHLHHasShortSignal)
{
return;
}
//
// Count Max Open Trades ...
if (xCHLHMaxAllowedTrades > 0)
{
//
int count = xCHLHTrader.Count();
bool canOpenTrade = count < xCHLHMaxAllowedTrades;
if (!canOpenTrade)
{
//
XCHLHIssueMaxAllowedTradesReachedAlert();
//
return;
}
}
//
// Check Free Margin ...
if (xCHLHFreeMargin <= xCHLHFreeMarginForOpenTrades)
{
//
XCHLHIssueMaxAllowedFreeMarginReachedAlert();
//
return;
}
//
// Check Account Balance ...
if (xCHLHBalance <= xCHLHBalanceForOpenTrades)
{
//
XCHLHIssueMinAllowedBalanceReachedAlert();
//
return;
}
//
// Primary Long Trade ...
if (
xCHLHHasLongSignal &&
xCHLHAllowLongTrades)
{
//
bool isLongSignalExecuted = XCHLHOpenLongPosition();
if (isLongSignalExecuted)
{
}
}
//
// Primary Short Trade ...
if (
xCHLHHasShortSignal &&
xCHLHAllowShortTrades)
{
//
bool isShortSignalExecuted = XCHLHOpenShortPosition();
if (isShortSignalExecuted)
{
}
}
}
//
// Handle Close Trades ...
void XCHLHHandleCloseTrades()
{
//
// Handle Long/Buy Close ...
if (xCHLHTrader.CountLongs() > 0 && XCHLHCanCloseLongTrade())
{
//
XSignal closed[];
xCHLHTrader.CloseLongPositions(closed);
bool hasClosed = ArraySize(closed) > 0;
if (hasClosed)
{
XCHLHIssueForceCloseTradesAlert(X_SIGNAL_LONG);
}
}
//
// Handle Short/Sell Close ...
if (xCHLHTrader.CountShorts() > 0 && XCHLHCanCloseShortTrade())
{
//
XSignal closed[];
xCHLHTrader.CloseShortPositions(closed);
bool hasClosed = ArraySize(closed) > 0;
if (hasClosed)
{
XCHLHIssueForceCloseTradesAlert(X_SIGNAL_SHORT);
}
}
//
// Handle Close In Profit Teades ...
if (xCHLHMaxInProfitTradeAge > 0)
{
//
XSignal closed[];
XSignal longTimeTrades[];
xCHLHTrader.GetLongTimeTrades(
xCHLHMaxInProfitTradeAge,
_Period,
longTimeTrades);
int count = ArraySize(longTimeTrades);
if (count > 0)
{
//
// Loop ...
for (int i = 0; i < count; i++)
{
//
XSignal trade = longTimeTrades[i];
if (trade.profit < 0)
{
continue;
}
//
bool isClosed = xCHLHTrader.Close(trade.ticket);
if (isClosed)
{
Add(
trade,
closed);
}
}
}
//
if (ArraySize(closed) > 0)
{
XCHLHIssueLongInProfitTradeClosed();
}
}
//
// Handle Close In DrawDown Trades ...
if (xCHLHMaxInDrawDownTradeAge > 0)
{
//
// XSignal closed[];
// XSignal longTimeTrades[];
// xCHLHTrader.GetLongTimeTrades(
// xCHLHMaxInDrawDownTradeAge,
// _Period,
// longTimeTrades);
// int count = ArraySize(longTimeTrades);
// if (count > 0)
// {
// //
// // Loop ...
// for (int i = 0; i < count; i++)
// {
// //
// XSignal trade = longTimeTrades[i];
// if (trade.profit > 0)
// {
// continue;
// }
// //
// // Open Grid Trades ...
// // XCHLHOpenSuppurtTrade(trade);
// // //
// // bool isClosed = xCHLHTrader.Close(trade.ticket);
// // if (isClosed)
// // {
// // //
// // Add(
// // trade,
// // closed);
// // }
// }
// }
// //
// if (ArraySize(closed) > 0)
// {
// XCHLHIssueLongInDrawdownTradeClosed();
// }
}
}
//
// Open Long Position ...
bool XCHLHOpenLongPosition()
{
//
bool result = false;
//
// Generate Position Signal and Validate it ...
XSignal position = XCHLHGeneratePositionSignal(X_SIGNAL_LONG);
if (!IsValid(
position,
xCHLHMagicNumber))
{
return result;
}
//
// Try to Open Position ...
result = xCHLHTrader.ExecuteSignal(position);
if (result)
{
XCHLHIssueSignalExecutionAlert(position);
}
//
return result;
}
//
// Open Short Position ...
bool XCHLHOpenShortPosition()
{
//
bool result = false;
//
// Generate Position Signal and Validate it ...
XSignal position = XCHLHGeneratePositionSignal(X_SIGNAL_SHORT);
if (!IsValid(
position,
xCHLHMagicNumber))
{
return result;
}
//
// Try to Open Position ...
result = xCHLHTrader.ExecuteSignal(position);
if (result)
{
XCHLHIssueSignalExecutionAlert(position);
}
//
return result;
}
//
// Handle Support Trades ...
void XCHLHHandleSupportTrades()
{
//
// Check Provider Enable ...
if (
//
!xCHLHEnableProvider
//
||
//
(
//
!xCHLHAllowLongTrades && !xCHLHAllowShortTrades
//
)
//
)
{
return;
}
//
double supportTradeDistance = NormalizePrice(xCHLHMinRewardPerTrade * 3);
//
// Check Long Support Trades ...
XSignal inDDLongs[];
if (xCHLHAllowLongTrades)
{
xCHLHTrader.GetInDrawDownTrades(
supportTradeDistance,
X_SIGNAL_LONG,
inDDLongs);
}
int inDDLongsCount = ArraySize(inDDLongs);
//
// Check Short Support Trades ...
XSignal inDDShorts[];
if (xCHLHAllowShortTrades)
{
xCHLHTrader.GetInDrawDownTrades(
supportTradeDistance,
X_SIGNAL_SHORT,
inDDShorts);
}
int inDDShortsCount = ArraySize(inDDShorts);
//
// Check Can Going Forward or not ...
if (inDDLongsCount == 0 && inDDShortsCount == 0)
{
return;
}
//
// Check Free Margin ...
if (xCHLHFreeMargin <= xCHLHFreeMarginForOpenTrades)
{
//
XCHLHIssueMaxAllowedFreeMarginReachedAlert();
//
return;
}
//
// Check Account Balance ...
if (xCHLHBalance <= xCHLHBalanceForOpenTrades)
{
//
XCHLHIssueMinAllowedBalanceReachedAlert();
//
return;
}
//
// Handle Long Trades Supports ...
if (xCHLHAllowLongTrades && inDDLongsCount > 0)
{
//
// Loop Through In DrawDown Trades ...
for (int i = 0; i < inDDLongsCount; i++)
{
//
XSignal inDDTrade = inDDLongs[i];
bool isExecuted = XCHLHOpenSupportTrade(inDDTrade);
if (isExecuted)
{
}
}
}
//
// Handle Short Trades Supports ...
if (xCHLHAllowShortTrades && inDDShortsCount > 0)
{
//
// Loop Through In DrawDown Trades ...
for (int i = 0; i < inDDShortsCount; i++)
{
//
XSignal inDDTrade = inDDShorts[i];
bool isExecuted = XCHLHOpenSupportTrade(inDDTrade);
if (isExecuted)
{
}
}
}
}
//
// Open a Support Signal ...
bool XCHLHOpenSupportTrade(
XSignal &signal // Parent Signal
)
{
//
bool result = false;
//
if (xCHLHMaxAllowedSupportTrades <= 0)
{
return result;
}
//
// Validate Signal ...
if (!IsValid(signal, xCHLHMagicNumber))
{
return result;
}
//
// Market Conditions ...
bool hasLongSignal = XCHLHCanOpenLongTrade();
bool hasShortSignal = XCHLHCanOpenShortTrade();
//
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN;
//
// Detect Support Signal Direction ...
XSignal support = {};
switch (signal.type)
{
//
case X_SIGNAL_LONG:
//
// First Check Long Support ...
// Then Look for Short Support ...
if (hasLongSignal)
{
type = X_SIGNAL_LONG;
}
else if (hasShortSignal)
{
type = X_SIGNAL_SHORT;
}
else
{
type = signal.type;
}
break;
//
case X_SIGNAL_SHORT:
// First Check Short Support ...
// Then Look for Long Support ...
if (hasShortSignal)
{
type = X_SIGNAL_SHORT;
}
else if (hasLongSignal)
{
type = X_SIGNAL_LONG;
}
else
{
type = signal.type;
}
break;
}
//
if (type == X_SIGNAL_UNKNOWN)
{
return result;
}
bool isLong = type == X_SIGNAL_LONG;
//
// Find Common Used ...
double entry = GetEntry(type);
double volumeMultiplier = 2;
if (xCHLHVolumeMultiplier > 2)
{
volumeMultiplier = xCHLHVolumeMultiplier;
}
//
// Check Signal is Support ot nor ...
int titlePosition = StringFind(
signal.comment,
"Support");
bool isSupport = titlePosition >= 0;
//
// double priceDistance = MathAbs(signal.entry - entry);
// || priceDistance < PipsToPrice(5) ...
if (isSupport)
{
return result;
}
//
// Check Signal Support Trades ...
XSignal allTrades[];
if (signal.type == X_SIGNAL_LONG)
{
xCHLHTrader.GetLongPositions(allTrades);
}
else if (signal.type == X_SIGNAL_SHORT)
{
xCHLHTrader.GetShortPositions(allTrades);
}
//
datetime time = iTime(
_Symbol,
_Period,
0);
double volume = NormalizeVolume(isSupport ? signal.volume : signal.volume * volumeMultiplier);
string comment = "Support_" + GetSignalType(type) + "_For_" + (string)signal.ticket + "_" + (string)volume + "_" + (string)time;
//
XTPSL tpSL = XCHLHCalculateTPSL(type);
if (!IsValid(tpSL))
{
return result;
}
//
// Calculate reward of signal ...
double reward = MathAbs(signal.entry - signal.tp) / 2;
double tp = tpSL.tp; // isLong ? entry + reward : entry - reward;
double sl = tpSL.sl;
//
// Filling Support Signal ...
support.tp = tp;
support.sl = sl;
support.type = type;
support.time = time;
support.entry = entry;
support.volume = volume;
support.symbol = _Symbol;
support.comment = comment;
support.magicNumber = xCHLHMagicNumber;
//
// Validate Generated Support ...
if (!IsValid(support, xCHLHMagicNumber))
{
return result;
}
//
result = xCHLHTrader.ExecuteSignal(support);
if (result)
{
XCHLHIssueSignalExecutionAlert(support);
}
//
return result;
}
//
// Generate Specific type of Signals for Trading ...
XSignal XCHLHGeneratePositionSignal(
ENUM_X_SIGNAL_TYPE type // direction of position
)
{
//
XSignal result = {};
//
if (type != X_SIGNAL_LONG &&
type != X_SIGNAL_SHORT)
{
return result;
}
//
double ask = GetAsk();
double bid = GetBid();
double entry = GetEntry(type);
//
double volume = XCHLHCalculateVolume();
//
datetime time = iTime(
_Symbol,
_Period,
0);
//
string typeString = GetSignalType(type);
string comment = XCHLHProviderName + "_" + typeString + "_" + (string)volume + "_" + (string)time;
//
XTPSL tpSL = XCHLHCalculateTPSL(type);
if (IsValid(tpSL))
{
//
// Apply TP ...
if (tpSL.tp > 0)
{
result.tp = tpSL.tp;
}
//
// Apply SL ...
if (tpSL.sl > 0)
{
result.sl = tpSL.sl;
}
}
//
result.type = type;
result.time = time;
result.entry = entry;
result.volume = volume;
result.symbol = _Symbol;
result.comment = comment;
result.magicNumber = xCHLHMagicNumber;
//
return result;
}
//
// END Provided Functions ...
//
//
// START Private Functions ...
//
//
// Calculating Volume for Tradings ...
double XCHLHCalculateVolume()
{
//
// Assign default Value ...
double result = xCHLHStaticVolume;
//
// we can count open trades and in draw down trades
// then do check volume based on it for gridding ...
int openTrades = xCHLHTrader.Count();
if (openTrades == 0)
{
openTrades = 1;
}
//
// Calculate Normalized Multiplier ...
double multiplier = xCHLHVolumeMultiplier <= 0 ? 1 : xCHLHVolumeMultiplier;
//
result = multiplier * openTrades * xCHLHStaticVolume;
//
// Normalize Volume ...
result = NormalizeVolume(result);
//
return result;
}
//
// Calculate Signal TP and SL ...
XTPSL XCHLHCalculateTPSL(
ENUM_X_SIGNAL_TYPE type // Position Type
)
{
//
XTPSL result = {};
//
// Validate Args ...
if (
type != X_SIGNAL_LONG &&
type != X_SIGNAL_SHORT)
{
return result;
}
//
bool isLong = type == X_SIGNAL_LONG;
//
double ask = GetAsk();
double bid = GetBid();
double spread = GetSpread();
double entry = isLong ? ask : bid;
//
// TODO: Find Risk ..
double risk = 0;
//
// Calculate Reward ...
double reward = PipsToPrice(xCHLHMinRewardPerTradeInPips) + spread;
//
// Calculate TP and SL ...
double tp = isLong ? entry + reward : entry - reward;
double sl = 0;
//
result.type = type;
result.tp = tp;
result.sl = sl;
result.entry = entry;
//
// TODO: Calculate R2R ...
result.r2r = 0;
//
return result;
}
void XCHLHIssueInitializationSucceedAlert()
{
//
string message = "Initializion of (" + XCHLHProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueDeinitializationSucceedAlert()
{
//
string message = "De Initializion of (" + XCHLHProviderName + " Provider" + ") Succeeded ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type)
{
//
string typeStr = GetSignalType(type);
if (StringLen(typeStr) == 0)
{
return;
}
//
string message = "Force Close " + typeStr + " Trades ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueMaxAllowedTradesReachedAlert()
{
//
string message = "reached Max Allowed Same Time Trades ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueMaxAllowedFreeMarginReachedAlert()
{
//
string message = "reached FreeMarigin For Open Trades ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueMinAllowedBalanceReachedAlert()
{
//
string message = "doesn't have Minimum Balance For Open Trades ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueSignalExecutionAlert(
XSignal &signal // Executed Signal
)
{
//
XCHLHIssueAlert(signal);
}
void XCHLHIssueLongInProfitTradeClosed()
{
//
string message = "Closed Long Time in Profit Trades ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueLongInDrawdownTradeClosed()
{
//
string message = "Closed Long Time in Profit Trades ...";
XCHLHIssueAlert(message);
}
void XCHLHIssueAlert(string message)
{
//
if (xCHLHEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
void XCHLHIssueAlert(XSignal &signal)
{
//
if (xCHLHEnableAlerts)
{
SendAlert(signal);
}
else
{
LogSignal(signal);
}
}
//
// END Private Functions ...
//