1282 lines
30 KiB
Plaintext
1282 lines
30 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 ...
|
|
//
|
|
input group "XTM Provider";
|
|
|
|
//
|
|
input group "XTM Common";
|
|
input bool enableXTMProvider = true; // Enable Provider
|
|
input bool xTMEnableAlerts = true; // Enable Events Alert
|
|
input int xTMNumberOfItemsPerTick = 5; // Number of reading Items per Tick
|
|
|
|
//
|
|
input group "XTM Indicator";
|
|
input int xTMMaPeriod = 14; // Period
|
|
input int xTMMaShift = 0; // Shift
|
|
input ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method
|
|
input ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_CLOSE; // Applied To
|
|
|
|
//
|
|
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 "XTD Oscillator";
|
|
input int xTDLength = 14; // Market Length
|
|
input bool xTDDrawCrosses = false; // Draw Cross Arrows
|
|
input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code
|
|
input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color
|
|
input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code
|
|
input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color
|
|
|
|
//
|
|
input group "XTPD Oscillatro";
|
|
input int xTPDLength = 14;
|
|
|
|
//
|
|
input group "XCHMA Oscillator";
|
|
input group "XCHMA Hot Areas";
|
|
input bool xCHMADrawHotAreas = true; // Draw Hot Areas Symbol
|
|
input uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code
|
|
input color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color
|
|
input uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code
|
|
input color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color
|
|
|
|
//
|
|
// LC Inputs ...
|
|
input group "XCHMA Long Cycle";
|
|
input group "XCHMA LC Market";
|
|
input int xCHMALcFastLength = 20; // Fast Length
|
|
input int xCHMALcSlowLength = 50; // Slow Length
|
|
input ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method
|
|
input ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To
|
|
input group "XCHMA LC Style";
|
|
input int xCHMALcDrawWidth = 1; // Draw Width
|
|
input ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type
|
|
input ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style
|
|
input color xCHMALcFastColor = clrAqua; // Fast Color
|
|
input color xCHMALcSlowColor = clrFuchsia; // Slow Color
|
|
input group "XCHMA LC Drawings";
|
|
input bool xCHMALcDrawFast = true; // Draw Fast
|
|
input bool xCHMALcDrawSlow = true; // Draw Slow
|
|
input bool xCHMALcDrawCrosses = true; // Draw Cross Lines
|
|
|
|
//
|
|
// MC Inputs ...
|
|
input group "XCHMA Medium Cycle";
|
|
input group "XCHMA MC Market";
|
|
input int xCHMAMcFastLength = 10; // Fast Length
|
|
input int xCHMAMcSlowLength = 30; // Slow Length
|
|
input ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method
|
|
input ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To
|
|
input group "XCHMA MC Style";
|
|
input int xCHMAMcDrawWidth = 1; // Draw Width
|
|
input ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type
|
|
input ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style
|
|
input color xCHMAMcFastColor = clrLime; // Fast Color
|
|
input color xCHMAMcSlowColor = clrRed; // Slow Color
|
|
input group "XCHMA MC Drawings";
|
|
input bool xCHMAMcDrawFast = true; // Draw Fast
|
|
input bool xCHMAMcDrawSlow = true; // Draw Slow
|
|
input bool xCHMAMcDrawCrosses = false; // Draw Cross Lines
|
|
|
|
//
|
|
// SC Inputs ...
|
|
input group "XCHMA Short Cycle";
|
|
input group "XCHMA SC Market";
|
|
input int xCHMAScFastLength = 7; // Fast Length
|
|
input int xCHMAScSlowLength = 14; // Slow Length
|
|
input ENUM_MA_METHOD xCHMAScMethod = MODE_EMA; // Calculation Method
|
|
input ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To
|
|
input group "XCHMA SC Style";
|
|
input int xCHMAScDrawWidth = 1; // Draw Width
|
|
input ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type
|
|
input ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style
|
|
input color xCHMAScFastColor = clrLightBlue; // Fast Color
|
|
input color xCHMAScSlowColor = clrLightSalmon; // Slow Color
|
|
input group "XCHMA SC Drawings";
|
|
input bool xCHMAScDrawFast = true; // Draw Fast
|
|
input bool xCHMAScDrawSlow = true; // Draw Slow
|
|
input bool xCHMAScDrawCrosses = false; // Draw Cross Lines
|
|
|
|
//
|
|
input group "XTM Trader";
|
|
input int xTMMagicNumber = 16940563; // Trader MagicNumber
|
|
input int xTMSlippage = 10; // Trader Slippage
|
|
|
|
//
|
|
input group "XTM Trade Management";
|
|
input bool xTMAllowLongTrades = true; // Allow Long Trades
|
|
input bool xTMAllowShortTrades = false; // Allow Short Trades
|
|
input int xTMMaxOpenTrades = 1; // Max Open Trades at Same Time
|
|
|
|
//
|
|
input group "XTM Risk Management";
|
|
input bool xTMUseTPSL = true; // Allow use TP and SL
|
|
input bool xTMUseVirtualTPSL = false; // Allow Use Virtual TP and SL
|
|
input bool xTMDrawTPSL = true; // Draw TP and SL
|
|
input double xTMR2r = 1.5; // Risk To Reward Ratio
|
|
input int xTMLoopback = 7; // Loopback Length for TP/SL Calculation
|
|
input double xTMMinRiskPerTrade = 100; // Min Risk Per Trade in Points
|
|
input double xTMMaxRiskPerTrade = 1000; // Max Risk Per Trade in Points
|
|
input bool xTMUseDynamicVolume = false; // Enable Dynamic Volume
|
|
input double xTMStaticVolume = 0.01; // Static Volume
|
|
input double xTMBalanceIncreased = 500; // Balance Increase
|
|
input double xTMVolumeIncreased = 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 ...
|
|
//
|
|
//
|
|
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[];
|
|
|
|
//
|
|
// 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 (xTMBalanceIncreased <= 0 || xTMVolumeIncreased <= 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()
|
|
{
|
|
//
|
|
// 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 XTD Oscillator ...
|
|
bool isXTDPassed = xTDStateBuffer[1] == X_XTD_BULLISH_CROSSED_OVER_BEARISH && xTDStateBuffer[2] != X_XTD_BULLISH_CROSSED_OVER_BEARISH;
|
|
|
|
//
|
|
// Check Market Conditions base od XTPD Oscillator ...
|
|
bool isXTPDPassed = false;
|
|
if (
|
|
xTPDStateBuffer[1] == X_XTPD_NEUTURAL ||
|
|
xTPDStateBuffer[1] == X_XTPD_BULLISH_OVER_BEARISH ||
|
|
xTPDStateBuffer[1] == X_XTPD_BULLISH_CROSSED_OVER_BEARISH)
|
|
{
|
|
isXTPDPassed = true;
|
|
}
|
|
else if (xTPDStateBuffer[1] == X_XTPD_BULLISH_UNDER_BEARISH)
|
|
{
|
|
isXTPDPassed = xTPDBullishPowerBuffer[1] > xTPDBullishPowerBuffer[2] && xTPDBullishPowerBuffer[1] > xTPDBullishPowerBuffer[3];
|
|
}
|
|
|
|
//
|
|
// Check Buy/Long Conditions ...
|
|
result = xTMAllowLongTrades &&
|
|
isXTDPassed &&
|
|
isXTPDPassed;
|
|
|
|
//
|
|
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 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;
|
|
|
|
//
|
|
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();
|
|
|
|
//
|
|
double canDoTrade = XTMCanDoTrade();
|
|
|
|
//
|
|
// Handle TP SL if it's enabled ...
|
|
if (xTMUseTPSL)
|
|
{
|
|
XTPSL mTpSl = XTMCalculateTPSL(X_SIGNAL_LONG, entry);
|
|
if (IsValid(mTpSl))
|
|
{
|
|
//
|
|
// Check for Draw TP and SL ...
|
|
if (xTMDrawTPSL)
|
|
{
|
|
// Implement this if Required ...
|
|
XTMDrawTPSL(mTpSl);
|
|
}
|
|
|
|
//
|
|
// Set TP SL in Signal if it's required to add directly ...
|
|
if (!xTMUseVirtualTPSL)
|
|
{
|
|
//
|
|
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 = 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();
|
|
|
|
//
|
|
double canDoTrade = XTMCanDoTrade();
|
|
//
|
|
// Handle TP SL if it's enabled ...
|
|
if (xTMUseTPSL)
|
|
{
|
|
XTPSL mTpSl = XTMCalculateTPSL(X_SIGNAL_SHORT, entry);
|
|
if (IsValid(mTpSl))
|
|
{
|
|
//
|
|
// Check for Draw TP and SL ...
|
|
if (xTMDrawTPSL)
|
|
{
|
|
// Implement this if Required ...
|
|
XTMDrawTPSL(mTpSl);
|
|
}
|
|
|
|
//
|
|
// Set TP SL in Signal if it's required to add directly ...
|
|
if (!xTMUseVirtualTPSL)
|
|
{
|
|
//
|
|
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_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 Open Trades ...
|
|
void XTMHandleOpenTrades()
|
|
{
|
|
//
|
|
// Primary Long Trade ...
|
|
if (xTMAllowLongTrades)
|
|
{
|
|
//
|
|
XSignal primaryLongSignal = {};
|
|
bool isPrimaryLongSignalExecuted = XTMHandlePrimaryLong(primaryLongSignal);
|
|
}
|
|
|
|
//
|
|
// Primary Short Trade ...
|
|
if (xTMAllowShortTrades)
|
|
{
|
|
//
|
|
XSignal primaryShortSignal = {};
|
|
bool isPrimaryShortSignalExecuted = XTMHandlePrimaryShort(primaryShortSignal);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Handle Close Trades ...
|
|
void XTMHandleCloseTrades()
|
|
{
|
|
//
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Calculating Volume for Tradings ...
|
|
double XTMCalculateVolume()
|
|
{
|
|
//
|
|
double result = xTMStaticVolume;
|
|
if (!xTMUseDynamicVolume)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double accountBalance = xTMAccountInfo.GetBalance();
|
|
double balanceIncreased = xTMBalanceIncreased;
|
|
double volumeIncreased = xTMVolumeIncreased;
|
|
|
|
//
|
|
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;
|
|
}
|
|
|
|
//
|
|
// 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);
|
|
}
|
|
|
|
//
|
|
// Determine based on current account state
|
|
bool XTMCanDoTrade()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Check Max Open Trades ...
|
|
int totalOpenTrades = xTMTrader.Count();
|
|
result = totalOpenTrades <= xTMMaxOpenTrades;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
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 swingSL = XTMGetMinSwingLow();
|
|
|
|
//
|
|
// Calculate and Normalize risk ...
|
|
double risk = isLong ? entry - ll : hh - entry;
|
|
// if (risk > maxRisk)
|
|
// {
|
|
// risk = maxRisk;
|
|
// }
|
|
// else if (risk < minRisk)
|
|
// {
|
|
// risk = minRisk;
|
|
// }
|
|
|
|
//
|
|
double reward = 15 * _Point; // risk * xTMR2r;
|
|
|
|
//
|
|
double tp = isLong ? entry + reward : entry - reward;
|
|
double sl = 0; // swingSL; // isLong ? entry - risk : entry + risk;
|
|
|
|
//
|
|
tp = NormalizeDouble(tp, _Digits);
|
|
sl = NormalizeDouble(sl, _Digits);
|
|
|
|
//
|
|
result.tp = tp;
|
|
result.sl = sl;
|
|
|
|
//
|
|
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 ...
|
|
//
|