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

1804 lines
39 KiB
Plaintext

////////////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 XTM Signal Provider Library
// --------------------------------------------------------
// Name: XTMSignalProvider
// Description: XTM 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
//
// Include Models Library ...
#include "..\Libraries\x-saherelm.models.lib.mq5";
//
// START Inputs ...
#include "..\Libraries\x-saherelm.xtm.provider.inputs.mq5";
//
// 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 *xTMTrader;
XCAccountInfo xTMAccountInfo;
//
// Defined Indicator/Oscillator Handlers ...
//
// XTM Indicator ...
int xTMHandler = INVALID_HANDLE;
double xTMMaBuffer[];
double xTMStateBuffer[];
//
// XOBD Indicator ...
int xOBDHandler = INVALID_HANDLE;
double xOBDSwingsBuffer[];
//
// XTD Oscillator ...
int xTDHandler = INVALID_HANDLE;
double xTDBullishBuffer[];
double xTDBearishBuffer[];
double xTDStateBuffer[];
//
// XTPD Oscillator ...
int xTPDHandler = INVALID_HANDLE;
double xTPDBullishPowerBuffer[];
double xTPDBearishPowerBuffer[];
double xTPDStateBuffer[];
//
// XCHMA Oscillator ...
int xCHMAHandler = INVALID_HANDLE;
double xCHMALcFastBuffer[];
double xCHMALcSlowBuffer[];
double xCHMALcStateBuffer[];
double xCHMAMcFastBuffer[];
double xCHMAMcSlowBuffer[];
double xCHMAMcStateBuffer[];
double xCHMAScFastBuffer[];
double xCHMAScSlowBuffer[];
double xCHMAScStateBuffer[];
double xCHMAHotStateBuffer[];
//
// this is an important Variable which
// when it is true, all calculations paused ...
bool xTMPauseTrading = false;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool OnInInitXTMSignalProviderLibrary()
{
//
bool result = false;
//
// Check Risk Management ...
if (xTMUseDynamicVolume)
{
//
if (xTMBalanceIncreasedFactor <= 0 || xTMVolumeIncreasedFactor <= 0)
{
//
LogMessage("invalid volume increased factors ...");
//
return result;
}
}
else
{
//
double maxAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double minAvailableVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
//
if (xTMStaticVolume > maxAvailableVolume || xTMStaticVolume < minAvailableVolume)
{
//
LogMessage("invalid static volume ...");
//
return result;
}
}
//
// Define Handlers ...
ResetLastError();
//
// XTM Handler ...
xTMHandler = iCustom(
_Symbol,
_Period,
"x-saherelm.xtm.indicator",
//
// Inputs ...
xTMMaPeriod,
xTMMaShift,
xTMMaMethod,
xTMMaAppliedTo);
if (xTMHandler == INVALID_HANDLE)
{
//
LogMessage("XTM Provider => error initializing XTM Indicator: " + (string)GetLastError());
return result;
}
//
// XTD Handler ...
xTDHandler = iCustom(
_Symbol,
_Period,
"x-saherelm.xtd.oscillator",
//
// Inputs ...
xTDLength,
xTDDrawCrosses,
xTDBullishArrowCode,
xTDBullishArrowColor,
xTDBearishArrowCode,
xTDBearishArrowColor);
if (xTDHandler == INVALID_HANDLE)
{
//
LogMessage("XTM Provider => error initializing XTD Oscillator: " + (string)GetLastError());
return result;
}
//
// XOBD Handler ...
xOBDHandler = iCustom(
_Symbol,
_Period,
"x-saherelm.xobd.indicator",
//
// Inputs ...
xOBDLength,
xOBDArrowDistanceFromPrice,
xOBDSwingHighArrowCode,
xOBDSwingHighArrowColor,
xOBDSwingLowArrowCode,
xOBDSwingLowArrowColor);
if (xOBDHandler == INVALID_HANDLE)
{
//
LogMessage("XTM Provider => error initializing XOBD Indicator: " + (string)GetLastError());
return result;
}
//
// XTPD Handler ...
xTPDHandler = iCustom(
_Symbol,
_Period,
"x-saherelm.xtpd.oscillator",
//
// Inputs ...
xTPDLength);
if (xTPDHandler == INVALID_HANDLE)
{
//
LogMessage("XTM Provider => error initializing XTPD Oscillator: " + (string)GetLastError());
return result;
}
//
// XCHMA Handler ...
xCHMAHandler = iCustom(
_Symbol,
_Period,
"x-saherelm.xchma.oscillator",
//
// Inputs ...
"",
xCHMADrawHotAreas,
xCHMAHotBullishArrowCode,
xCHMAHotBullishArrowColor,
xCHMAHotBearishArrowCode,
xCHMAHotBearishArrowColor,
//
// Long Cycle ...
"",
"",
xCHMALcFastLength,
xCHMALcSlowLength,
xCHMALcMethod,
xCHMALcAppliedTo,
"",
xCHMALcDrawWidth,
xCHMALcDrawType,
xCHMALcDrawStyle,
xCHMALcFastColor,
xCHMALcSlowColor,
"",
xCHMALcDrawFast,
xCHMALcDrawSlow,
xCHMALcDrawCrosses,
//
// Medium Cycle ...
"",
"",
xCHMAMcFastLength,
xCHMAMcSlowLength,
xCHMAMcMethod,
xCHMAMcAppliedTo,
"",
xCHMAMcDrawWidth,
xCHMAMcDrawType,
xCHMAMcDrawStyle,
xCHMAMcFastColor,
xCHMAMcSlowColor,
"",
xCHMAMcDrawFast,
xCHMAMcDrawSlow,
xCHMAMcDrawCrosses,
//
// Short Cycle ...
"",
"",
xCHMAScFastLength,
xCHMAScSlowLength,
xCHMAScMethod,
xCHMAScAppliedTo,
"",
xCHMAScDrawWidth,
xCHMAScDrawType,
xCHMAScDrawStyle,
xCHMAScFastColor,
xCHMAScSlowColor,
"",
xCHMAScDrawFast,
xCHMAScDrawSlow,
xCHMAScDrawCrosses);
if (xCHMAHandler == INVALID_HANDLE)
{
//
LogMessage("XTM Provider => error initializing XCHMA Oscillator: " + (string)GetLastError());
return result;
}
//
// Define Buffer States ...
ArraySetAsSeries(xTMMaBuffer, true);
ArraySetAsSeries(xTMStateBuffer, true);
ArraySetAsSeries(xTDBullishBuffer, true);
ArraySetAsSeries(xTDBearishBuffer, true);
ArraySetAsSeries(xTDStateBuffer, true);
ArraySetAsSeries(xOBDSwingsBuffer, true);
ArraySetAsSeries(xTPDBullishPowerBuffer, true);
ArraySetAsSeries(xTPDBearishPowerBuffer, true);
ArraySetAsSeries(xTPDStateBuffer, true);
ArraySetAsSeries(xCHMALcFastBuffer, true);
ArraySetAsSeries(xCHMALcSlowBuffer, true);
ArraySetAsSeries(xCHMALcStateBuffer, true);
ArraySetAsSeries(xCHMAMcFastBuffer, true);
ArraySetAsSeries(xCHMAMcSlowBuffer, true);
ArraySetAsSeries(xCHMAMcStateBuffer, true);
ArraySetAsSeries(xCHMAScFastBuffer, true);
ArraySetAsSeries(xCHMAScSlowBuffer, true);
ArraySetAsSeries(xCHMAScStateBuffer, true);
ArraySetAsSeries(xCHMAHotStateBuffer, true);
//
// Make XCTrader instance ...
xTMTrader = new XCTrade(
_Symbol,
xTMSlippage,
xTMMagicNumber);
//
result = true;
//
// Logging State ...
string message = "Initializion of (" + "XTM Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
LogMessage(message);
//
return result;
}
//
// DeInitial Library if required ...
void OnDeinitXTMSignalProviderLibrary()
{
//
// Logging State ...
string message = "De Initializion of (" + "XTM Provider" + ") Succeeded ...";
LogMessage(message);
}
//
// this is a Globally Function which do all of
// checkings and positions handling ...
void HandleXTMSignalProviderTick()
{
//
if (xTMPauseTrading)
{
return;
}
//
// Copy required Buffers for handle processing and check Market Conditions ...
XTMReadingBuffers();
//
// Handle Open Trades ...
XTMHandleOpenTrades();
//
// Handle Close Trades ...
XTMHandleCloseTrades();
}
//
// Reading all required data from indicator/oscillator(s) Buffers ...
void XTMReadingBuffers()
{
//
// XTM Lines ...
CopyBuffer(
xTMHandler,
X_XTM_MA_LINE,
0,
xTMNumberOfItemsPerTick,
xTMMaBuffer);
CopyBuffer(
xTMHandler,
X_XTM_STATE_LINE,
0,
xTMNumberOfItemsPerTick,
xTMStateBuffer);
//
// XTD Lines ...
CopyBuffer(
xTDHandler,
X_XTD_BULLISH_POWER_LINE,
0,
xTMNumberOfItemsPerTick,
xTDBullishBuffer);
CopyBuffer(
xTDHandler,
X_XTD_BEARISH_POWER_LINE,
0,
xTMNumberOfItemsPerTick,
xTDBearishBuffer);
CopyBuffer(
xTDHandler,
X_XTD_TREND_STATE_LINE,
0,
xTMNumberOfItemsPerTick,
xTDStateBuffer);
//
// XOBD Lines ...
CopyBuffer(
xOBDHandler,
0,
0,
xTMNumberOfItemsPerTick,
xOBDSwingsBuffer);
//
// XTPD Lines ...
CopyBuffer(
xTPDHandler,
X_XTPD_BULLISH_POWER_LINE,
0,
xTMNumberOfItemsPerTick,
xTPDBullishPowerBuffer);
CopyBuffer(
xTPDHandler,
X_XTPD_BEARISH_POWER_LINE,
0,
xTMNumberOfItemsPerTick,
xTPDBearishPowerBuffer);
CopyBuffer(
xTPDHandler,
X_XTPD_STATE_LINE,
0,
xTMNumberOfItemsPerTick,
xTPDStateBuffer);
//
// XCHMA Buffer Readings ...
CopyBuffer(
xCHMAHandler,
X_XCHMA_LC_FAST_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMALcFastBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_LC_SLOW_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMALcSlowBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_LC_STATE_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMALcStateBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_MC_FAST_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMAMcFastBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_MC_SLOW_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMAMcSlowBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_MC_STATE_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMAMcStateBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_SC_FAST_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMAScFastBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_SC_SLOW_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMAScSlowBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_SC_STATE_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMAScStateBuffer);
CopyBuffer(
xCHMAHandler,
X_XCHMA_HOT_STATE_LINE,
0,
xTMNumberOfItemsPerTick,
xCHMAHotStateBuffer);
}
//
// Check Market Conditions to find Long Primary Signals ...
bool XTMHasPrimaryLongSignal()
{
//
bool result = false;
//
// Check MArket Conditions Based On XCHMA Oscillator for Long Signals ...
// METHOD: we have to read HotStateBuffer and LCStateBuffer ...
//
// Check Hot Bullish State ...
bool isXCHMAHotBullishState =
xCHMAHotStateBuffer[1] == X_XCHMA_HOT_BULLISH && xCHMAHotStateBuffer[2] != X_XCHMA_HOT_BULLISH;
//
// Check Hot Bearish State ...
bool isXCHMAHotBearishState =
xCHMAHotStateBuffer[1] == X_XCHMA_HOT_BEARISH && xCHMAHotStateBuffer[2] != X_XCHMA_HOT_BEARISH;
//
// Check LC Fast Cross Over Slow ...
bool isXCHMALCFastCrossedOverSlow =
xCHMALcStateBuffer[1] == X_XCHMA_FAST_CROSSED_OVER_SLOW && xCHMALcStateBuffer[2] != X_XCHMA_FAST_CROSSED_OVER_SLOW;
//
// Check LC Fast Cross Under Slow ...
bool isXCHMALCFastCrossedUnderSlow =
xCHMALcStateBuffer[1] == X_XCHMA_FAST_CROSSED_UNDER_SLOW && xCHMALcStateBuffer[2] != X_XCHMA_FAST_CROSSED_UNDER_SLOW;
//
// Check Buy/Long Conditions ...
result = xTMAllowLongTrades &&
isXCHMAHotBullishState &&
isXCHMALCFastCrossedOverSlow;
//
return result;
}
//
// Check Market Conditions to find Short Primary Signals ...
bool XTMHasPrimaryShortSignal()
{
//
bool result = false;
//
// Check Sell/Short Conditions ...
result = xTMAllowShortTrades &&
xTDStateBuffer[1] == X_XTD_BULLISH_CROSSED_UNDER_BEARISH && xTDStateBuffer[2] != X_XTD_BULLISH_CROSSED_UNDER_BEARISH;
//
return result;
}
//
// Check Market Conditions for Grid Long Signals ...
bool XTMHasGridLongSignal()
{
//
bool result = false;
//
// XCHMA ...
bool isXCHMAPassed = xCHMAScFastBuffer[1] < xCHMAScSlowBuffer[1] && xCHMAScFastBuffer[1] < xCHMAMcFastBuffer[1] && xCHMAScFastBuffer[1] < xCHMAMcSlowBuffer[1] && xCHMAScFastBuffer[1] < xCHMALcFastBuffer[1] && xCHMAScFastBuffer[1] < xCHMALcSlowBuffer[1] && xCHMAScFastBuffer[1] > xCHMAScFastBuffer[2];
//
// XCMA Medium Cycle ...
// bool isXCHMAMCPassed = xCHMAMcStateBuffer[1] == X_XCHMA_FAST_CROSSED_OVER_SLOW && xCHMAMcStateBuffer[2] != X_XCHMA_FAST_CROSSED_OVER_SLOW;
//
// XTD ...
// bool isXTDPassed = xTDStateBuffer[1] == X_XTD_BULLISH_CROSSED_OVER_BEARISH && xTDStateBuffer[2] != X_XTD_BULLISH_CROSSED_OVER_BEARISH;
//
// Check Market Conditions for Long Entry Grid Trades ...
result =
// isXTDPassed ||
isXCHMAPassed
// ||
// isXCHMAMCPassed
;
//
return result;
}
//
// Check Market Conditions for Grid Short Signals ...
bool XTMHasGridShortSignal()
{
//
bool result = false;
//
return result;
}
//
// Check Market Conditions for closing Long Trades ...
bool XTMCanCloseLongTrades()
{
//
bool result = false;
//
// result = (xTDStateBuffer[1] != X_XTD_BULLISH_OVER_BEARISH && xTDStateBuffer[1] != X_XTD_BULLISH_CROSSED_OVER_BEARISH) && xTDStateBuffer[2] == X_XTD_BULLISH_OVER_BEARISH;
//
// We Want to Close Long Trades When all XCHMA's is Down ...
// Hot Bearish Area ...
// result = xCHMAHotStateBuffer[1] == X_XCHMA_HOT_BEARISH;
//
return result;
}
//
// Check Market Conditions for closing Short Trades ...
bool XTMCanCloseShortTrades()
{
//
bool result = false;
//
return result;
}
//
// Handle Long/Buy for Primary Trades...
bool XTMHandlePrimaryLong(
XSignal &signal, // return structure if signal founded
bool doTrade = true // do trade on signal
)
{
//
bool result = false;
//
if (!xTMAllowLongTrades)
{
return result;
}
//
ResetLastError();
//
// && xTMTrader.CountLongs() == 0
if (XTMHasPrimaryLongSignal())
{
//
double entry = GetAsk();
double volume = XTMCalculateVolume();
//
bool canDoTrade =
!xTMPauseTrading &&
XTMIsReadyForPrimaryTrades();
//
XTPSL mTpSl = XTMCalculateTPSL(X_SIGNAL_LONG, entry);
if (IsValid(mTpSl))
{
//
signal.tp = mTpSl.tp;
signal.sl = 0; // mTpSl.sl;
}
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_LONG;
signal.magicNumber = xTMMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Primary_XTM_Long";
//
if (enableXTMProvider && xTMAllowLongTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = xTMTrader.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 (xTMEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Short/Sell for Primary Trades...
bool XTMHandlePrimaryShort(
XSignal &signal, // return structure if signal founded
bool doTrade = true // do trade on signal
)
{
//
bool result = false;
//
if (!xTMAllowShortTrades)
{
return result;
}
//
ResetLastError();
//
if (XTMHasPrimaryShortSignal() && xTMTrader.CountShorts() == 0)
{
//
double entry = GetBid();
double volume = XTMCalculateVolume();
//
bool canDoTrade =
!xTMPauseTrading &&
XTMIsReadyForPrimaryTrades();
//
XTPSL mTpSl = XTMCalculateTPSL(X_SIGNAL_SHORT, entry);
if (IsValid(mTpSl))
{
//
signal.tp = mTpSl.tp;
signal.sl = mTpSl.sl;
}
//
signal.entry = entry;
signal.volume = volume;
signal.symbol = _Symbol;
signal.type = X_SIGNAL_SHORT;
signal.magicNumber = xTMMagicNumber;
signal.time = iTime(_Symbol, _Period, 0);
signal.comment = "Primary_XTM_Short";
//
if (enableXTMProvider && xTMAllowShortTrades && doTrade && canDoTrade)
{
//
// Execute Signal ...
result = xTMTrader.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 (xTMEnableAlerts)
{
SendAlert(signal, true);
}
else
{
LogExecutedSignal(signal);
}
}
//
return result;
}
//
// Handle Grid Long Trades ...
void XTMHandleGridLong()
{
//
if (!enableXTMProvider || !xTMAllowLongTrades || !xTMEnableGridTrades)
{
return;
}
//
XSignal primaryLongs[];
XTMRetrievePrimaryTradesOfType(
X_SIGNAL_LONG,
primaryLongs);
int count = ArraySize(primaryLongs);
if (count == 0)
{
return;
}
//
double price = GetAsk();
double spread = GetSpread();
double lastPrice = 0;
double lastVolume = 0;
//
// Calculate Price Distance ...
double priceDiff = PipsToPrice(xTMGridDistanceInPips);
//
// Primary Long Loop ...
for (int i = 0; i < count; i++)
{
//
XSignal primary = primaryLongs[i];
if (!XTMIsPrimaryTrade(primary))
{
continue;
}
//
// Retrieve Last Price for Grid Entry ...
XSignal latestGridSignal = XTMRetrieveLastGridTradesOfPrimary(primary);
if (
!XTMIsGridTrade(latestGridSignal) ||
latestGridSignal.type != primary.type ||
!IsValid(latestGridSignal, xTMMagicNumber))
{
//
lastPrice = primary.entry;
lastVolume = primary.volume;
}
else
{
//
lastPrice = latestGridSignal.entry;
lastVolume = latestGridSignal.volume;
}
//
// Check Market Conditions for Grid Long Signals ...
bool canDoGridTrade = XTMHasGridLongSignal() && price <= lastPrice - priceDiff;
if (canDoGridTrade)
{
//
// Open a Long Grid Position ...
double volumeMultiplier = (primary.entry - price) / priceDiff;
double volume = NormalizeDouble(lastVolume * (volumeMultiplier * xTMGridVolumeMultiplier), 2); // NormalizeDouble(lastVolume * xTMGridVolumeMultiplier, 2);
string comment = "Grid_XTM_Long_" + XTMGenerateTicketTitle(primary.ticket);
//
XSignal gridLong = {};
//
gridLong.entry = price;
gridLong.volume = volume;
gridLong.symbol = _Symbol;
gridLong.type = X_SIGNAL_LONG;
gridLong.magicNumber = xTMMagicNumber;
gridLong.time = iTime(_Symbol, _Period, 0);
gridLong.comment = comment;
//
XTPSL mTpSl = XTMCalculateTPSL(X_SIGNAL_LONG, price);
if (IsValid(mTpSl))
{
//
gridLong.tp = price + (100 * _Point) + spread;
gridLong.sl = 0;
}
//
// Execute Signal ...
bool isExecuted = xTMTrader.ExecuteSignal(gridLong);
if (isExecuted)
{
//
// Handle Alert and Log ...
if (xTMEnableAlerts)
{
SendAlert(gridLong, true);
}
else
{
LogExecutedSignal(gridLong);
}
}
}
}
}
//
// Handle Open Trades ...
void XTMHandleOpenTrades()
{
//
// Check Provider is Enable ...
if (!enableXTMProvider)
{
return;
}
//
// Primary Long Trade ...
if (xTMAllowLongTrades)
{
//
XSignal primaryLongSignal = {};
bool isPrimaryLongSignalExecuted = XTMHandlePrimaryLong(primaryLongSignal);
//
// Handle Grid Trades ...
if (xTMEnableGridTrades)
{
XTMHandleGridLong();
}
}
//
// Primary Short Trade ...
if (xTMAllowShortTrades)
{
//
XSignal primaryShortSignal = {};
bool isPrimaryShortSignalExecuted = XTMHandlePrimaryShort(primaryShortSignal);
}
}
//
// Handle Close Trades ...
void XTMHandleCloseTrades()
{
//
// Close Conditional Long Trades ...
if (xTMAllowLongTrades)
{
//
// Handle Long/Buy Close ...
if (xTMTrader.CountLongs() > 0 && XTMCanCloseLongTrades())
{
//
xTMTrader.CloseLongPositions();
//
string message = "XTM Closing Long Trades ...";
//
if (xTMEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
}
//
// Close Conditional Short Trades ...
if (xTMAllowShortTrades)
{
//
// Handle Short/Sell Close ...
if (xTMTrader.CountShorts() > 0 && XTMCanCloseShortTrades())
{
//
xTMTrader.CloseShortPositions();
//
string message = "XTM Closing Short Trades ...";
//
if (xTMEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
}
//
// Close Long Time Trades ...
if (xTMMaximumTradeLife > 0)
{
//
bool hasLongTimeTradeClosed = xTMTrader.CloseLongTimeTrades(
xTMMaximumTradeLife,
_Period);
if (hasLongTimeTradeClosed)
{
//
string message = "Close Long Time Trades ...";
if (xTMEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
}
//
// Close MAximum DrawDown Trades ...
if (xTMMaximumAllowedDrawDownFactorPerTrade > 0)
{
//
// Calculate Max Available DrawDown per Trade ...
double deposit = xTMAccountInfo.GetInitialBalance();
double maxAllowedDrawDown = xTMMaximumAllowedDrawDownFactorPerTrade * deposit;
//
// Try To Find and Close In Max DrawDown Trades ...
bool hasInDrawDownTradeClosed = xTMTrader.CloseInDrawDownTrades(maxAllowedDrawDown);
if (hasInDrawDownTradeClosed)
{
//
string message = "Close Max DrawDown Trades ...";
if (xTMEnableAlerts)
{
SendAlert(message);
}
else
{
LogMessage(message);
}
}
}
}
//
// Calculating Volume for Tradings ...
double XTMCalculateVolume()
{
//
double result = xTMStaticVolume;
if (!xTMUseDynamicVolume)
{
return result;
}
//
double balance = xTMAccountInfo.GetBalance();
double deposit = xTMAccountInfo.GetInitialBalance();
double balanceIncreasedRate = xTMBalanceIncreasedFactor * deposit;
double volumeIncreasedRate = xTMVolumeIncreasedFactor;
//
// result = (volumeIncreased * accountBalance) / balanceIncreased;
result = (balance / balanceIncreasedRate) * volumeIncreasedRate;
//
// 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;
}
//
// Find MIN Swing Low ...
double XTMGetMinSwingLow()
{
//
double result = EMPTY_VALUE;
//
double xOBDSwings[];
ArraySetAsSeries(xOBDSwings, true);
//
XTMReadingSwings(50, xOBDSwings);
//
// Loopp through retrieved Swings ...
int count = 0;
int swingsCountForResult = 3;
for (int i = 0; i < ArraySize(xOBDSwings) && count < swingsCountForResult; i++)
{
//
if (xOBDSwings[i] == X_SWING_LOW)
{
//
count++;
//
XOHCL candle = GetCandle(i + 4);
//
result = result == EMPTY_VALUE ? candle.low : MathMin(result, candle.low);
}
}
//
// Free Array ...
ArrayFree(xOBDSwings);
//
return result;
}
//
// Reading Swing Buffers from XOBD Indicator ...
void XTMReadingSwings(
int count,
double &result[])
{
//
CopyBuffer(
xOBDHandler,
0,
0,
count,
result);
}
//
// Check Provider Ready for Primary Trades ...
bool XTMIsReadyForPrimaryTrades()
{
//
bool result = false;
//
bool isEquityPassed = XTMCheckAccountEquity();
bool isBalancePassed = XTMCheckAccountBalance();
bool isTradesCountPassed = XTMCheckMaxOpenTrades();
//
result =
isEquityPassed &&
isBalancePassed &&
isTradesCountPassed;
//
return result;
}
//
// Check Provider Ready for Grid Trades ...
bool XTMIsReadyForGridTrades()
{
//
bool result = false;
//
bool isBalancePassed = XTMCheckAccountBalance();
//
result =
isBalancePassed;
//
return result;
}
//
// Check Max Open Trades is Valid or not ...
bool XTMCheckMaxOpenTrades()
{
//
bool result = false;
//
if (xTMMaxOpenTrades <= 0)
{
//
result = true;
return result;
}
//
// Count Long Open Trades ...
int totalLongTrades = xTMTrader.CountLongs();
//
// Count Short Open Trades ...
int totalShortTrades = xTMTrader.CountShorts();
//
// Count all Open Positions ...
int totalTrades = xTMTrader.Count();
//
// Check Total Longs and Shorts Below or Equals to Max Open Trade Value ...
result = totalTrades < xTMMaxOpenTrades;
// totalLongTrades <= xTMMaxOpenTrades && totalShortTrades <= xTMMaxOpenTrades;
//
return result;
}
//
// Check Max Equity for Trades ...
bool XTMCheckAccountEquity()
{
//
bool result = false;
//
if (xTMMaximumEquityFactorForTrade <= 0)
{
//
result = true;
return result;
}
//
double equity = xTMAccountInfo.GetEquity();
double balance = xTMAccountInfo.GetBalance();
double initialBalance = xTMAccountInfo.GetInitialBalance();
//
double maxAvailableEquity = balance - (xTMMaximumEquityFactorForTrade * initialBalance);
//
result = equity > maxAvailableEquity;
//
return result;
}
//
// Check Account Balance For Trades ...
bool XTMCheckAccountBalance()
{
//
bool result = false;
//
if (xTMMinimumBalanceFactorForTrade <= 0)
{
//
result = true;
return result;
}
//
double balance = xTMAccountInfo.GetBalance();
double initialBalance = xTMAccountInfo.GetInitialBalance();
//
double minRequiredBalance = initialBalance * xTMMinimumBalanceFactorForTrade;
//
// Check Balance Bigger than Minimum Required ...
result = balance > minRequiredBalance;
//
return result;
}
//
// Calculate TP and SL ...
XTPSL XTMCalculateTPSL(
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 (!xTMUseTPSL)
// {
// return result;
// }
//
// Validate Args ...
if (entry <= 0 || type == X_SIGNAL_UNKNOWN)
{
return result;
}
//
result.type = type;
result.r2r = xTMR2r;
result.entry = entry;
//
bool isLong = type == X_SIGNAL_LONG;
//
// Retrieve Market Highest High and Lowest Low ...
double hh = GetHighestHigh(
xTMLoopback,
0);
double ll = GetLowestLow(
xTMLoopback,
0);
// //
// double maxRisk = xTMMaxRiskPerTrade * _Point;
// double minRisk = xTMMinRiskPerTrade * _Point;
//
// Calculate Long SL ...
double longSwingSL = XTMGetMinSwingLow();
longSwingSL = NormalizeDouble(longSwingSL, _Digits);
//
// 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 * xTMR2r; // 30 * _Point; // risk * xTMR2r;
//
double tp = isLong ? entry + reward : entry - reward;
double sl = isLong ? entry - risk : entry + risk; // swingSL; // isLong ? entry - risk : entry + risk;
//
tp = NormalizeDouble(tp, _Digits);
sl = NormalizeDouble(sl, _Digits);
//
result.tp = tp;
result.sl = isLong ? longSwingSL : 0; // swingSL; // sl;
//
return result;
}
//
// Generate Ticket Title for Signal ...
string XTMGenerateTicketTitle(ulong ticket)
{
//
string result = "Ticket(" + (string)ticket + ")";
//
return result;
}
//
// Determines a Signal is Primary or not ...
bool XTMIsPrimaryTrade(
XSignal &signal)
{
//
bool result = false;
//
int titlePosition = StringFind(
signal.comment,
"Primary");
result = titlePosition >= 0;
//
return result;
}
//
// Determines a Signal is Grid or not ...
bool XTMIsGridTrade(
XSignal &signal)
{
//
bool result = false;
//
int titlePosition = StringFind(
signal.comment,
"Grid");
result = titlePosition >= 0;
//
return result;
}
//
// Check a Signal Comment Contains Specific Ticket ...
bool XTMIsSignalContainsTicketComment(
ulong ticket, // specified ticket which going to check ...
XSignal &signal // the signal object which going to compare ...
)
{
//
bool result = false;
//
// Generate Ticket Title ...
string title = XTMGenerateTicketTitle(ticket);
int titlePosition = StringFind(signal.comment, title);
result = titlePosition >= 0;
//
return result;
}
//
// Retrieve All Primary Trades ...
void XTMRetrievePrimaryTrades(XSignal &result[])
{
//
ArrayFree(result);
ArrayResize(result, 0);
//
XSignal allSignals[];
xTMTrader.GetAllPositions(allSignals);
//
if (ArraySize(allSignals) <= 0)
{
return;
}
//
// Loop Through all Positions and Extract Primary Trades ...
for (int i = 0; i < ArraySize(allSignals); i++)
{
//
XSignal signal = allSignals[i];
//
bool isPrimary = XTMIsPrimaryTrade(signal);
if (!isPrimary)
{
continue;
}
//
ArrayResize(
result,
ArraySize(result) + 1);
result[ArraySize(result) - 1] = signal;
}
}
//
// Retrieve All Primary Spcified Type Trades ...
void XTMRetrievePrimaryTradesOfType(
ENUM_X_SIGNAL_TYPE type, // Specify Signal Type ...
XSignal &result[] // hold results ...
)
{
//
ArrayFree(result);
ArrayResize(result, 0);
//
XSignal allSignals[];
XTMRetrievePrimaryTrades(allSignals);
//
if (ArraySize(allSignals) <= 0)
{
return;
}
//
// Loop Through all Positions and Extract Primary Trades ...
for (int i = 0; i < ArraySize(allSignals); i++)
{
//
XSignal signal = allSignals[i];
//
if (signal.type != type)
{
continue;
}
//
ArrayResize(
result,
ArraySize(result) + 1);
result[ArraySize(result) - 1] = signal;
}
}
//
// Retrieve All Grid Trades ...
void XTMRetrieveGridTrades(XSignal &result[])
{
//
ArrayFree(result);
ArrayResize(result, 0);
//
XSignal allSignals[];
xTMTrader.GetAllPositions(allSignals);
//
if (ArraySize(allSignals) <= 0)
{
return;
}
//
// Loop Through all Positions and Extract Grid Trades ...
for (int i = 0; i < ArraySize(allSignals); i++)
{
//
XSignal signal = allSignals[i];
//
bool isGrid = XTMIsGridTrade(signal);
if (!isGrid)
{
continue;
}
//
ArrayResize(
result,
ArraySize(result) + 1);
result[ArraySize(result) - 1] = signal;
}
}
//
// Retrieve All Grid Specific Type Trades ...
void XTMRetrieveGridTradesOfType(
ENUM_X_SIGNAL_TYPE type, // Specify Signal Type ...
XSignal &result[] // hold results ...
)
{
//
ArrayFree(result);
ArrayResize(result, 0);
//
XSignal allSignals[];
XTMRetrieveGridTrades(allSignals);
//
if (ArraySize(allSignals) <= 0)
{
return;
}
//
// Loop Through all Positions and Extract Primary Trades ...
for (int i = 0; i < ArraySize(allSignals); i++)
{
//
XSignal signal = allSignals[i];
//
if (signal.type != type)
{
continue;
}
//
ArrayResize(
result,
ArraySize(result) + 1);
result[ArraySize(result) - 1] = signal;
}
}
//
// Retrieve an Specific Primary Trade's Related Grid Trades ...
void XTMRetrieveGridTradesOfPrimary(
XSignal &primary, // Primary Trade which looking for it's Grid Trades ...
XSignal &result[] // Hold Result ...
)
{
//
// Free Result ...
ArrayFree(result);
ArrayResize(result, 0);
//
// Validate Args ...
bool isPrimary = XTMIsPrimaryTrade(primary);
if (!isPrimary)
{
return;
}
//
XSignal gridSignals[];
XTMRetrieveGridTrades(gridSignals);
int gridCount = ArraySize(gridSignals);
if (gridCount == 0)
{
return;
}
//
// Loop Through Grid Signals for Finding Primary Grid Trades ...
for (int i = 0; i < gridCount; i++)
{
//
XSignal signal = gridSignals[i];
bool isSignalContainsTicket = XTMIsSignalContainsTicketComment(primary.ticket, signal);
if (!isSignalContainsTicket)
{
continue;
}
//
if (signal.type != primary.type)
{
continue;
}
//
ArrayResize(
result,
ArraySize(result) + 1);
result[ArraySize(result) - 1] = signal;
}
}
//
// Retrieve Most Down Grid Trades of Primary ...
XSignal XTMRetrieveLastGridTradesOfPrimary(
XSignal &primary // Primary Trade which looking for it's Grid Trades ...
)
{
//
XSignal result = {};
//
XSignal gridSignals[];
XTMRetrieveGridTradesOfPrimary(primary, gridSignals);
int gridCount = ArraySize(gridSignals);
if (gridCount == 0)
{
return result;
}
//
// Loop Throug a Primary Grids to Find Smallest Entry Price ...
for (int i = 0; i < gridCount; i++)
{
//
XSignal grid = gridSignals[i];
//
if (!IsValid(result, xTMMagicNumber))
{
result = grid;
}
else if (primary.type == X_SIGNAL_LONG)
{
if (grid.entry < result.entry)
{
result = grid;
}
}
else if (primary.type == X_SIGNAL_SHORT)
{
if (grid.entry > result.entry)
{
result = grid;
}
}
}
//
return result;
}
//
// Draw TPSL Object ...
void XTMDrawTPSL(
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 = xTDBullishArrowColor;
color slColor = xTDBearishArrowColor;
//
// 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 Provided Functions ...
//