Initial Commit ...
This commit is contained in:
@@ -0,0 +1,670 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 XTEST Signal Provider Library
|
||||
// --------------------------------------------------------
|
||||
// Name: XTESTSignalProvider
|
||||
// Description: XTEST 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 XTESTProviderName "XTEST"
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
#include "x-saherelm.xtest.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 *xTESTTrader;
|
||||
XCAccountInfo xTESTAccountInfo;
|
||||
|
||||
//
|
||||
#include "x-saherelm.xtest.provider.indicators.lib.mq5"
|
||||
|
||||
//
|
||||
double xTESTDeposit = 0;
|
||||
double xTESTBalance = 0;
|
||||
double xTESTFreeMargin = 0;
|
||||
double xTESTMinRewardPerTrade = 0;
|
||||
double xTESTFreeMarginForOpenTrades = 0;
|
||||
double xTESTBalanceForOpenTrades = 0;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initial Library if required ...
|
||||
bool XTESTInitSignalProviderLibrary()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
result = XTESTValidateInputs();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Init Indicators ...
|
||||
result = XTESTInitIndicators();
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Account Deposit ...
|
||||
xTESTDeposit = xTESTAccountInfo.GetInitialBalance();
|
||||
|
||||
//
|
||||
// Calculate xTESTMinRewardPerTrade ...
|
||||
if (xTESTMinRewardPerTradeInPips > 0)
|
||||
{
|
||||
xTESTMinRewardPerTrade = PipsToPrice(xTESTMinRewardPerTradeInPips);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Min Balance for Trades ...
|
||||
if (xTESTBalanceFactorForOpenTrades > 0)
|
||||
{
|
||||
xTESTBalanceForOpenTrades = xTESTBalanceFactorForOpenTrades * xTESTDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Claculate Min Free Marging for Trades ...
|
||||
if (xTESTFreeMarginFactorForOpenTrades > 0)
|
||||
{
|
||||
xTESTFreeMarginForOpenTrades = xTESTFreeMarginFactorForOpenTrades * xTESTDeposit;
|
||||
}
|
||||
|
||||
//
|
||||
// Make XCTrader instance ...
|
||||
xTESTTrader = new XCTrade(
|
||||
XTESTProviderName,
|
||||
_Symbol,
|
||||
xTESTSlippage,
|
||||
xTESTMagicNumber,
|
||||
xTESTMaxAllowedTrades,
|
||||
xTESTMaxAllowedSupportTrades,
|
||||
xTESTMinRewardPerTradeInPips,
|
||||
xTESTSupportTradesPriceDistanceInPips,
|
||||
xTESTFreeMarginForOpenTrades,
|
||||
xTESTBalanceForOpenTrades);
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTESTIssueInitializationSucceedAlert();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// DeInitial Library if required ...
|
||||
void XTESTDeinitSignalProviderLibrary(
|
||||
const int reason)
|
||||
{
|
||||
//
|
||||
// Release Handlers ...
|
||||
XTESTReleaseIndicators();
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
XTESTIssueDeinitializationSucceedAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// this is a Globally Function which do all of
|
||||
// checkings and positions handling ...
|
||||
void XTESTSignalProviderHandleTick()
|
||||
{
|
||||
//
|
||||
// Update account Balance ...
|
||||
xTESTBalance = xTESTAccountInfo.GetBalance();
|
||||
xTESTFreeMargin = xTESTAccountInfo.GetFreeMargin();
|
||||
|
||||
//
|
||||
// Check Provider is Enable or Not ...
|
||||
if (!xTESTEnableProvider)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Indicator Buffers ...
|
||||
XTESTHandleReadingBuffers();
|
||||
if (xTESTCalculatedBars < xTESTMaxLengthOfInputs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
XTESTHandleOpenTrades();
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
XTESTHandleCloseTrades();
|
||||
|
||||
//
|
||||
// Handle Support Trades ...
|
||||
XTESTHandleSupportTrades();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Open Trades ...
|
||||
void XTESTHandleOpenTrades()
|
||||
{
|
||||
//
|
||||
// Check Can Trade ...
|
||||
bool canTrade = xTESTAllowLongTrades || xTESTAllowShortTrades;
|
||||
if (!canTrade)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Signals Exists ...
|
||||
bool hasLongSignal = XTESTCanOpenLongTrade();
|
||||
bool hasShortSignal = XTESTCanOpenShortTrade();
|
||||
if (!hasLongSignal && !hasShortSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Trades ...
|
||||
if (
|
||||
//
|
||||
hasLongSignal &&
|
||||
xTESTAllowLongTrades)
|
||||
{
|
||||
//
|
||||
bool isOpened = XTESTOpenLongPosition();
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Trades ...
|
||||
if (
|
||||
//
|
||||
hasShortSignal &&
|
||||
xTESTAllowShortTrades)
|
||||
{
|
||||
//
|
||||
bool isOpened = XTESTOpenShortPosition();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Close Trades ...
|
||||
void XTESTHandleCloseTrades()
|
||||
{
|
||||
//
|
||||
// All Close Mechanism Handles Here ...
|
||||
// - Force Close;
|
||||
// - Partial Close;
|
||||
// - Risk Free Close;
|
||||
// - Virtual TP/SL Close;
|
||||
|
||||
//
|
||||
// Force Close Long Trades ...
|
||||
bool canCloseLongTrades = XTESTCanCloseLongTrade();
|
||||
if (xTESTAllowLongTrades && canCloseLongTrades)
|
||||
{
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG;
|
||||
|
||||
//
|
||||
XSignal closed[];
|
||||
xTESTTrader.ClosePositionsByType(
|
||||
type,
|
||||
closed);
|
||||
|
||||
//
|
||||
bool isClosed = ArraySize(closed) > 0;
|
||||
if (isClosed)
|
||||
{
|
||||
XTESTIssueForceCloseTradesAlert(type);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Force Close Short Trades ...
|
||||
bool canCloseShortTrades = XTESTCanCloseShortTrade();
|
||||
if (xTESTAllowShortTrades && canCloseShortTrades)
|
||||
{
|
||||
//
|
||||
ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT;
|
||||
|
||||
//
|
||||
XSignal closed[];
|
||||
xTESTTrader.ClosePositionsByType(
|
||||
type,
|
||||
closed);
|
||||
|
||||
//
|
||||
bool isClosed = ArraySize(closed) > 0;
|
||||
if (isClosed)
|
||||
{
|
||||
XTESTIssueForceCloseTradesAlert(type);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close Risk Free Trades ...
|
||||
XSignal riskFrees[];
|
||||
xTESTTrader.RiskFreeSignals(riskFrees);
|
||||
bool isRiskFree = ArraySize(riskFrees) > 0;
|
||||
if (isRiskFree)
|
||||
{
|
||||
XTESTIssueRiskFreeTradesAlert();
|
||||
}
|
||||
|
||||
//
|
||||
// Close Virtual TP / SL Trades ...
|
||||
if (xTESTUseVirtualTPSL)
|
||||
{
|
||||
//
|
||||
XSignal takeProfits[];
|
||||
XSignal stopLosses[];
|
||||
|
||||
//
|
||||
xTESTTrader.HandleVirtualTPSL(
|
||||
takeProfits,
|
||||
stopLosses);
|
||||
|
||||
//
|
||||
// Take Profits ...
|
||||
int takeProfitsCount = ArraySize(takeProfits);
|
||||
if (takeProfitsCount > 0)
|
||||
{
|
||||
//
|
||||
// Do What we Want in Profits Trades ...
|
||||
}
|
||||
|
||||
//
|
||||
// Stop Losses ...
|
||||
int stopLossesCount = ArraySize(stopLosses);
|
||||
if (stopLossesCount > 0)
|
||||
{
|
||||
//
|
||||
// Do What we Want in Stop Losses Trades ...
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close Max DrawDown Trades ...
|
||||
|
||||
//
|
||||
// Close Long Time Trades ...
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Support Trades ...
|
||||
void XTESTHandleSupportTrades()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Open Long Position ...
|
||||
bool XTESTOpenLongPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double tp = PipsToPrice(xTESTMinRewardPerTradeInPips * 3);
|
||||
double riskFree = PipsToPrice(xTESTMinRewardPerTradeInPips);
|
||||
double riskFreeRate = 0.75;
|
||||
double volume = XTESTCalculateVolume();
|
||||
|
||||
//
|
||||
XSignal signal = {};
|
||||
signal = xTESTTrader.GenerateTradeSignal(
|
||||
X_SIGNAL_LONG,
|
||||
tp,
|
||||
0,
|
||||
volume,
|
||||
riskFree,
|
||||
riskFreeRate,
|
||||
true);
|
||||
bool isValidSignal = IsValid(
|
||||
signal,
|
||||
xTESTMagicNumber);
|
||||
if (!isValidSignal)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int error = -1;
|
||||
result = xTESTTrader.ExecuteSignal(signal, error);
|
||||
if (result)
|
||||
{
|
||||
XTESTIssueSignalExecutionAlert(signal);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open Short Position ...
|
||||
bool XTESTOpenShortPosition()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double tp = PipsToPrice(xTESTMinRewardPerTradeInPips * 3);
|
||||
double riskFree = PipsToPrice(xTESTMinRewardPerTradeInPips);
|
||||
double riskFreeRate = 0.75;
|
||||
double volume = XTESTCalculateVolume();
|
||||
|
||||
//
|
||||
XSignal signal = {};
|
||||
signal = xTESTTrader.GenerateTradeSignal(
|
||||
X_SIGNAL_LONG,
|
||||
tp,
|
||||
0,
|
||||
volume,
|
||||
riskFree,
|
||||
riskFreeRate,
|
||||
true);
|
||||
bool isValidSignal = IsValid(
|
||||
signal,
|
||||
xTESTMagicNumber);
|
||||
if (!isValidSignal)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
int error = -1;
|
||||
result = xTESTTrader.ExecuteSignal(signal, error);
|
||||
if (result)
|
||||
{
|
||||
XTESTIssueSignalExecutionAlert(signal);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Open a Support Signal ...
|
||||
bool XTESTOpenSupportTrade(
|
||||
XSignal &signal // Parent Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Private Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Calculating Volume for Tradings ...
|
||||
double XTESTCalculateVolume()
|
||||
{
|
||||
//
|
||||
// Assign default Value ...
|
||||
double result = xTESTStaticVolume;
|
||||
|
||||
//
|
||||
// we can count open trades and in draw down trades
|
||||
// then do check volume based on it for gridding ...
|
||||
int openTrades = xTESTTrader.Count();
|
||||
if (openTrades == 0)
|
||||
{
|
||||
openTrades = 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Normalized Multiplier ...
|
||||
double multiplier = xTESTVolumeMultiplier <= 0 ? 1 : xTESTVolumeMultiplier;
|
||||
|
||||
//
|
||||
result = multiplier * openTrades * xTESTStaticVolume;
|
||||
|
||||
//
|
||||
// Normalize Volume ...
|
||||
result = NormalizeVolume(result);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Signal TP and SL ...
|
||||
XTPSL XTESTCalculateTPSL(
|
||||
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(xTESTMinRewardPerTradeInPips) + 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 XTESTIssueInitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "Initializion of (" + XTESTProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueDeinitializationSucceedAlert()
|
||||
{
|
||||
//
|
||||
string message = "De Initializion of (" + XTESTProviderName + " Provider" + ") Succeeded ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueForceCloseTradesAlert(ENUM_X_SIGNAL_TYPE type)
|
||||
{
|
||||
//
|
||||
string typeStr = GetSignalType(type);
|
||||
if (StringLen(typeStr) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string message = "Force Close " + typeStr + " Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueMaxAllowedTradesReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached Max Allowed Same Time Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueMaxAllowedFreeMarginReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "reached FreeMarigin For Open Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueMinAllowedBalanceReachedAlert()
|
||||
{
|
||||
//
|
||||
string message = "doesn't have Minimum Balance For Open Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueSignalExecutionAlert(
|
||||
XSignal &signal // Executed Signal
|
||||
)
|
||||
{
|
||||
//
|
||||
XTESTIssueAlert(signal);
|
||||
}
|
||||
|
||||
void XTESTIssueSignalExecutionError(int error)
|
||||
{
|
||||
//
|
||||
string message = GetSignalExecutionError(error);
|
||||
if (StringLen(message) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueRiskFreeTradesAlert()
|
||||
{
|
||||
//
|
||||
string message = "Make Some Trades Risk Free ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueLongInProfitTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueLongInDrawdownTradeClosed()
|
||||
{
|
||||
//
|
||||
string message = "Closed Long Time in Profit Trades ...";
|
||||
XTESTIssueAlert(message);
|
||||
}
|
||||
|
||||
void XTESTIssueAlert(string message)
|
||||
{
|
||||
//
|
||||
if (xTESTEnableAlerts)
|
||||
{
|
||||
SendAlert(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
void XTESTIssueAlert(XSignal &signal)
|
||||
{
|
||||
//
|
||||
if (xTESTEnableAlerts)
|
||||
{
|
||||
SendAlert(signal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSignal(signal);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Private Functions ...
|
||||
//
|
||||
Reference in New Issue
Block a user