Files
xMQL5/BKPS/Projects/X_SAHER_XEU5/x-saherelm.xeu5.provider.lib.mq5
2024-01-25 04:09:42 +03:30

1280 lines
28 KiB
Plaintext

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