1006 lines
20 KiB
Plaintext
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 ...
|
|
//
|