561 lines
12 KiB
Plaintext
561 lines
12 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center XTest MQL5 Expert Advisor
|
|
// -------------------------------------------------
|
|
// Name: XSTestEA
|
|
// Description: an Exper Advisor which used XTestSetup
|
|
// to Analyse Market ...
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////x
|
|
//
|
|
// Global Properties ...
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://saherelm.ir"
|
|
#property version "1.00"
|
|
#property description "SaherElm XSTestEA"
|
|
#property strict
|
|
|
|
//
|
|
#define ShortName "XSTestEA"
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Helpers/x-saherelm.xct.helper.mq5"
|
|
#include "../Helpers/x-saherelm.xcc.helper.mq5"
|
|
|
|
//
|
|
#include "../Strategies/x-saherelm.xch.strategy.mq5"
|
|
|
|
//
|
|
// Inputs ...
|
|
long eaMagicNumber = 78692110; // Magic Number
|
|
int eaSlippage = 10; // Slippgae
|
|
|
|
//
|
|
double eaVolume = 0.01; // Static Volume
|
|
bool eaIgnoreTP = false; // Ignore TP
|
|
bool eaIgnoreSL = false; // Ignore SL
|
|
double eaTPPoint = 150; // Static TP Point
|
|
double eaSLPoint = 500; // Static SL Point
|
|
|
|
//
|
|
double eaR2R = 1.5; // Risk to Reward Ratio
|
|
double eaAllowLong = true; // Allow Long Positions
|
|
double eaAllowShort = true; // Allow Short Positions
|
|
int eaMaxAllowedLongs = 1; // Max Allowed Long Positions
|
|
int eaMaxAllowedShorts = 1; // Max Allowed Short Positions
|
|
double eaMaxDrawdownPercentForOpenTrades = 3; // Max Drawdown Percent for Open Trades
|
|
|
|
//
|
|
bool eaMultiSymbol = false; // Use Multi Symbol
|
|
bool eaUseMaxAllowedTradesPerSymbol = true; // Use Max Allowed Trades Per Symbol
|
|
string eaSymbols = "EURUSDb,USDJPYb"; // Trading Symbols
|
|
// string eaSymbols = "EURUSDb,USDJPYb,USDCHFb,GBPUSDb,XAUUSDb,XAGUSDb"; // Trading Symbols
|
|
|
|
//
|
|
// Variables ...
|
|
|
|
//
|
|
// int mNumberOfSLs = 0;
|
|
|
|
//
|
|
// Bar Style nad Time Instances ...
|
|
XSCXCTHelper *mCTHelper;
|
|
XSCXCCHelper *mCCHelper;
|
|
|
|
//
|
|
// Registred Strategies ...
|
|
XSCBaseStrategy *strategies[];
|
|
|
|
//
|
|
// Trader Instance Class ...
|
|
XSCTrade *eaTrader;
|
|
|
|
//
|
|
// Alert Class ...
|
|
XSCAlert *eaAlert;
|
|
|
|
//
|
|
// Time Tracker ...
|
|
XTimeTracker eaTimeTracker;
|
|
|
|
//
|
|
// Trade Handler Instance Class ...
|
|
XSCXTradeHandler *eaTradeHandler;
|
|
|
|
//
|
|
// Event Handlers ...
|
|
|
|
//
|
|
// Initialization ...
|
|
int OnInit()
|
|
{
|
|
//
|
|
if (!ValidateInputs())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
if (!InitialEA())
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
drawPrefix = ShortName;
|
|
|
|
//
|
|
// EventSetTimer(1);
|
|
// EventSetMillisecondTimer(100);
|
|
|
|
//
|
|
// Init Succeed ...
|
|
return INIT_SUCCEEDED;
|
|
}
|
|
|
|
//
|
|
// DeInitialization ...
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//
|
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
|
// REASON_REMOVE 1 Program removed from a chart
|
|
// REASON_RECOMPILE 2 Program recompiled
|
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
|
// REASON_CHARTCLOSE 4 Chart closed
|
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
|
// REASON_TEMPLATE 7 Another chart template applied
|
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
|
// REASON_CLOSE 9 Terminal closed
|
|
|
|
//
|
|
string msg = "MaxSameTimeTrades: " + ToString(eaTradeHandler.MaxSameTimeTrades());
|
|
eaAlert.Alert(msg);
|
|
|
|
//
|
|
// De Initialize XSampleEA Providers ...
|
|
delete mCTHelper;
|
|
delete mCCHelper;
|
|
|
|
//
|
|
delete eaAlert;
|
|
delete eaTrader;
|
|
delete eaTradeHandler;
|
|
|
|
//
|
|
// EventKillTimer();
|
|
|
|
//
|
|
Clean(strategies);
|
|
}
|
|
|
|
//
|
|
// On Tick Handler ...
|
|
void OnTick()
|
|
{
|
|
//
|
|
HandleTradeState();
|
|
HandleTimeReport();
|
|
HandleStrategiesOnTick();
|
|
}
|
|
|
|
//
|
|
// Handle On Trade Event ...
|
|
void OnTrade()
|
|
{
|
|
eaTrader.HandleOnTrade();
|
|
}
|
|
|
|
//
|
|
// On Timer ...
|
|
void OnTimer()
|
|
{
|
|
//
|
|
// HandleTradeState();
|
|
// HandleTimeReport();
|
|
// HandleStrategiesOnTick();
|
|
|
|
// //
|
|
// if (eaTimeTracker.IsNewDay())
|
|
// {
|
|
// mNumberOfSLs = 0;
|
|
// }
|
|
}
|
|
|
|
//
|
|
// Custom Functions ...
|
|
|
|
//
|
|
// Validate Inputs ...
|
|
bool ValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = true;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Initialize all Requirements ...
|
|
bool InitialEA()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Bar Timer ...
|
|
XCTInputs ctInputs;
|
|
ctInputs.Default();
|
|
mCTHelper = new XSCXCTHelper();
|
|
result = mCTHelper.Init(
|
|
_Symbol,
|
|
_Period,
|
|
ctInputs //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bar Styles ...
|
|
XCCInputs ccInputs;
|
|
ccInputs.Default();
|
|
mCCHelper = new XSCXCCHelper();
|
|
result = mCCHelper.Init(
|
|
_Symbol,
|
|
_Period,
|
|
ccInputs //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Create Instance of Alert Class ...
|
|
eaAlert = new XSCAlert();
|
|
eaAlert.SetPrefix(ShortName);
|
|
|
|
//
|
|
// Create Trader Instance ...
|
|
eaTrader = new XSCTrade(
|
|
eaSlippage,
|
|
eaMagicNumber //
|
|
);
|
|
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
|
|
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
|
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
|
|
|
//
|
|
// Initialize Trade Handler ...
|
|
eaTradeHandler = new XSCXTradeHandler(eaTrader);
|
|
eaTradeHandler.SetAlertPrefix(ShortName + "> TradeHandler");
|
|
eaTradeHandler.SaveTrades(true);
|
|
eaTradeHandler.SaveSignals(true);
|
|
|
|
//
|
|
eaTradeHandler.AllowLong(eaAllowLong);
|
|
eaTradeHandler.AllowShort(eaAllowShort);
|
|
eaTradeHandler.MaxAllowedLongs(eaMaxAllowedLongs);
|
|
eaTradeHandler.MaxAllowedShorts(eaMaxAllowedShorts);
|
|
eaTradeHandler.UseMaxAllowedTradesPerSymbol(eaUseMaxAllowedTradesPerSymbol);
|
|
eaTradeHandler.MaxDrawdownPercentForOpenTrades(eaMaxDrawdownPercentForOpenTrades);
|
|
|
|
//
|
|
// Configure Hedging ...
|
|
eaTradeHandler.AllowHedging(true);
|
|
eaTradeHandler.MinTradesForHedge(2);
|
|
eaTradeHandler.HedgeVolumeFactor(eaVolume);
|
|
eaTradeHandler.HedgeMinProfitPerVolumeFactor(0.3);
|
|
|
|
//
|
|
// Configure Trailing ...
|
|
eaTradeHandler.AllowTrailStops(false);
|
|
eaTradeHandler.TrailStepInPoint(30);
|
|
eaTradeHandler.TrailStartInPoint(100);
|
|
eaTradeHandler.IgnoreTPOnTrail(true);
|
|
eaTradeHandler.TrailBasedOnProfit(true);
|
|
|
|
//
|
|
// Configure Recovery ...
|
|
eaTradeHandler.AllowRecover(false);
|
|
eaTradeHandler.RecoveryTPPoint(150);
|
|
eaTradeHandler.MaxAllowedRecover(0);
|
|
eaTradeHandler.MaxAllowedRecoveryVolume(0.1);
|
|
eaTradeHandler.RecoverySLPoint(200);
|
|
eaTradeHandler.RecoveryVolumeMultiplier(2);
|
|
eaTradeHandler.ForcePressuresInRecovery(false);
|
|
|
|
//
|
|
// Single Symbol ...
|
|
if (!eaMultiSymbol)
|
|
{
|
|
//
|
|
XSCXCHStrategy *xchStrategy;
|
|
xchStrategy = new XSCXCHStrategy(
|
|
_Symbol,
|
|
_Period,
|
|
PERIOD_H1, // Analyzing Period
|
|
eaVolume,
|
|
eaR2R, // R2R ...
|
|
eaSlippage,
|
|
eaMagicNumber,
|
|
true, // Ignore Signal Execution
|
|
true, // Use TP SL Point
|
|
false, // Use Max
|
|
eaTPPoint, // TP
|
|
eaSLPoint, // SL
|
|
eaIgnoreTP,
|
|
eaIgnoreSL,
|
|
eaAllowLong,
|
|
eaAllowShort,
|
|
eaMaxAllowedLongs, // Max Longs
|
|
eaMaxAllowedShorts // Max Shorts
|
|
);
|
|
xchStrategy.EnableXCHM(true);
|
|
xchStrategy.EnableXCHHK(true);
|
|
xchStrategy.EnableXCHSTR(true);
|
|
xchStrategy.EnableXCHCHE(true);
|
|
xchStrategy.SetAlertLogAlerts(true);
|
|
xchStrategy.DrawImportantAreas(false);
|
|
xchStrategy.SetAlertEnableAlerts(true);
|
|
xchStrategy.AddXCHSignalEventHandler(OnSignalRecieved);
|
|
RegisterStrategy(xchStrategy);
|
|
}
|
|
//
|
|
// Multi Symbol ...
|
|
else
|
|
{
|
|
//
|
|
// Parse Symbols ...
|
|
string symbols[];
|
|
int symbolsCount = SplitContent(
|
|
symbols,
|
|
eaSymbols //
|
|
);
|
|
result = IsValidSize(symbolsCount);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < symbolsCount; i++)
|
|
{
|
|
//
|
|
string iSymbol = symbols[i];
|
|
|
|
//
|
|
XSCXCHStrategy *iStrategy;
|
|
iStrategy = new XSCXCHStrategy(
|
|
iSymbol,
|
|
_Period,
|
|
PERIOD_H1, // Analyzing Period
|
|
eaVolume,
|
|
eaR2R, // R2R ...
|
|
eaSlippage,
|
|
eaMagicNumber,
|
|
true, // Ignore Signal Execution
|
|
true, // Use TP SL Point
|
|
false, // Use Max
|
|
eaTPPoint, // TP
|
|
eaSLPoint, // SL
|
|
eaIgnoreTP,
|
|
eaIgnoreSL,
|
|
eaAllowLong,
|
|
eaAllowShort,
|
|
eaMaxAllowedLongs, // Max Longs
|
|
eaMaxAllowedShorts // Max Shorts
|
|
);
|
|
iStrategy.EnableXCHM(true);
|
|
iStrategy.EnableXCHHK(true);
|
|
iStrategy.EnableXCHSTR(true);
|
|
iStrategy.EnableXCHCHE(true);
|
|
iStrategy.SetAlertLogAlerts(true);
|
|
iStrategy.DrawImportantAreas(false);
|
|
iStrategy.SetAlertEnableAlerts(true);
|
|
iStrategy.AddXCHSignalEventHandler(OnSignalRecieved);
|
|
|
|
//
|
|
RegisterStrategy(iStrategy);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Register Strategy ...
|
|
void RegisterStrategy(XSCBaseStrategy *strategy)
|
|
{
|
|
//
|
|
if (strategy == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
ArrayResize(
|
|
strategies,
|
|
ArraySize(strategies) + 1 //
|
|
);
|
|
|
|
//
|
|
strategies[ArraySize(strategies) - 1] = strategy;
|
|
}
|
|
|
|
//
|
|
// Call All Registered Strategis Tick Handler Functions ...
|
|
void HandleStrategiesOnTick()
|
|
{
|
|
//
|
|
int count = ArraySize(strategies);
|
|
if (!IsValidSize(count))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Call Tick Handler Function ...
|
|
strategies[i].HandleTick();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Manage Trading States ...
|
|
void HandleTradeState()
|
|
{
|
|
//
|
|
// Implement All Trade States here ...
|
|
eaTradeHandler.UpdateData();
|
|
|
|
//
|
|
// Do Protection Senarios ...
|
|
eaTradeHandler.HandleProtection();
|
|
}
|
|
|
|
//
|
|
// Time Reporting ...
|
|
void HandleTimeReport()
|
|
{
|
|
//
|
|
if (eaTimeTracker.IsNewDay())
|
|
{
|
|
//
|
|
string msg = "New Day ...";
|
|
|
|
//
|
|
eaAlert.Alert(msg);
|
|
}
|
|
}
|
|
|
|
//
|
|
// All Signals from Strategies Comming Here for Execution or
|
|
// Analyzing ...
|
|
void OnSignalRecieved(
|
|
XSignal &signal,
|
|
XCHStrategyConditions &conditions //
|
|
)
|
|
{
|
|
//
|
|
// Check Signal and Conditions Validations ...
|
|
|
|
//
|
|
if (!signal.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
if (!conditions.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
XCHStartegyConditionsParser parser;
|
|
bool isFiltered = parser.IsFiltered(
|
|
signal,
|
|
conditions //
|
|
);
|
|
if (isFiltered)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Attach Conditions Summary to Signal ...
|
|
string conditionsSummary = conditions.GenerateSummary(
|
|
false,
|
|
false,
|
|
true,
|
|
false //
|
|
);
|
|
signal.conditions = conditionsSummary;
|
|
|
|
//
|
|
// Execute Signal Using Trade Handler ...
|
|
ENUM_X_SIGNAL_EXECUTION_RESULT state;
|
|
bool isExecuted = eaTradeHandler.ExecuteSignal(
|
|
signal,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Trader Event Handlers for Trade Handling ...
|
|
|
|
//
|
|
void OnStopLossTriggered(const XDeal &deal)
|
|
{
|
|
//
|
|
// Finish ...
|
|
eaTradeHandler.Finish(deal);
|
|
|
|
// //
|
|
// if (deal.profit < 0)
|
|
// {
|
|
// mNumberOfSLs++;
|
|
// }
|
|
}
|
|
|
|
//
|
|
void OnTakeProfitTriggered(const XDeal &deal)
|
|
{
|
|
//
|
|
// Finish ...
|
|
eaTradeHandler.Finish(deal);
|
|
}
|
|
|
|
//
|
|
void OnPositionForceClosed(
|
|
const ulong ticket,
|
|
const XPosition &position,
|
|
const string comment //
|
|
)
|
|
{
|
|
//
|
|
// Finish ...
|
|
eaTradeHandler.Finish(
|
|
ticket,
|
|
position,
|
|
comment //
|
|
);
|
|
}
|
|
|
|
// |