720 lines
17 KiB
Plaintext
720 lines
17 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center XTest MQL5 Expert Advisor
|
|
// -------------------------------------------------
|
|
// Name: XCHEA
|
|
// 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 XCHEA"
|
|
#property strict
|
|
|
|
//
|
|
#define ShortName "XCHEA"
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Helpers/x-saherelm.xct.helper.mq5"
|
|
#include "../Helpers/x-saherelm.xcc.helper.mq5"
|
|
|
|
//
|
|
#include "../Parsers/x-saherelm.xch.parser.mq5"
|
|
#include "../Strategies/x-saherelm.xch.strategy.mq5"
|
|
|
|
//
|
|
// Inputs ...
|
|
|
|
//
|
|
// Common ...
|
|
input group "Common";
|
|
input long eaMagicNumber = 78692110; // Magic Number
|
|
input int eaSlippage = 10; // Slippgae
|
|
input string eaLogSuffix = ""; // Log Suffix
|
|
|
|
//
|
|
// Symbols ...
|
|
input group "Symbols";
|
|
input bool eaMultiSymbol = true; // Use Multi Symbol
|
|
input bool eaUseMaxAllowedTradesPerSymbol = true; // Use Max Allowed Trades Per Symbol
|
|
input string eaSymbols = "EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb,DowJones30"; // Trading Symbols
|
|
|
|
//
|
|
// Trades ...
|
|
input group "Trades";
|
|
input double eaVolume = 0.3; // Static Volume
|
|
input double eaR2R = 1.5; // Risk to Reward Ratio for Dynamic TP SL
|
|
input bool eaUseFixedTPSLPoints = true; // Use Fixed TP SL in Points
|
|
input bool eaIgnoreTP = false; // Ignore TP
|
|
input bool eaIgnoreSL = false; // Ignore SL
|
|
input double eaTPPoint = 200; // Static TP Point
|
|
input double eaSLPoint = 500; // Static SL Point
|
|
|
|
//
|
|
// Risk Management ...
|
|
input group "Risk Management";
|
|
|
|
//
|
|
// Risk Management > Trade Management ...
|
|
input group "Trade Management";
|
|
input bool eaAllowLong = true; // Allow Long Positions
|
|
input bool eaAllowShort = true; // Allow Short Positions
|
|
input int eaMaxAllowedLongs = 1; // Max Allowed Long Positions
|
|
input int eaMaxAllowedShorts = 1; // Max Allowed Short Positions
|
|
input double eaMaxDrawdownPercentForOpenTrades = 3; // Max Drawdown Percent for Open Trades
|
|
|
|
//
|
|
// Risk Management > Hedging ...
|
|
input group "Hedging";
|
|
input bool eaAllowHedging = true; // Allow Hedging Trades
|
|
input int eaMinTradesForHedge = 2; // Minimum Open Trades for Hedging
|
|
input double eaHedgeVolumeFactor = 0.01; // Volume Factor for Hedging
|
|
input double eaMinimumProfitPerVolumeForHedging = 1; // Minimum Required Profit per Volume for Hedging
|
|
|
|
//
|
|
// Risk Management > Trailling Stop ...
|
|
input group "Trailling Stop";
|
|
input bool eaAllowTrailStop = false; // Allow Trail Stop
|
|
input double eaStartTrailInPoint = 100; // Trail Start After Profit (Point)
|
|
input double eaTrailStepInPoint = 30; // Trail Size in each Step (Point)
|
|
input bool eaIgnoreTPAfterTrail = true; // Ignore TP after Trail
|
|
|
|
//
|
|
// Risk Management > Trades Recovery ...
|
|
input group "Trades Recovery";
|
|
input bool eaAllowRecovery = false; // Allow Recover Trades
|
|
input double eaRecoveryTPPoint = 150; // Recovery TP (Point)
|
|
input double eaRecoverySLPoint = 200; // Recovery SL (Point)
|
|
input int eaMaxAllowedRecoveryTrades = 0; // Max Allowed Recovery Trades
|
|
input double eaRecoveryVolumeMultiplier = 2; // Recovery Volume Multiplier
|
|
input double eaMaxAllowedRecoveryTradesVolume = 0.1; // Max Allowed Recovery Volume
|
|
|
|
//
|
|
// Alert ...
|
|
input group "Alert";
|
|
input bool eAEnableAlerts = true; // Enable Alerts
|
|
input bool eALogAlerts = true; // Log Alerts
|
|
input bool eAMailAlerts = false; // Mail Alerts
|
|
input bool eAPushAlerts = false; // Push Alerts
|
|
input bool eATerminalAlerts = false; // Terminal Alerts
|
|
|
|
//
|
|
// Time Report ...
|
|
input group "Reports";
|
|
input bool eaAlertNewMonths = false; // Alert New Month
|
|
input bool eaAlertNewWeeks = false; // Alert New Weeks
|
|
input bool eaAlertNewDays = false; // Alert New Days
|
|
input bool eaAlertNewHours = false; // Alert New Hours
|
|
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
string mTag =
|
|
!IsValid(eaLogSuffix)
|
|
? ShortName
|
|
: ShortName + "_" + eaLogSuffix;
|
|
|
|
//
|
|
// Event Handlers ...
|
|
|
|
//
|
|
// Initialization ...
|
|
int OnInit()
|
|
{
|
|
//
|
|
if (!ValidateInputs())
|
|
{
|
|
return INIT_PARAMETERS_INCORRECT;
|
|
}
|
|
|
|
//
|
|
if (!InitialEA())
|
|
{
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
//
|
|
drawPrefix = mTag;
|
|
|
|
//
|
|
// EventSetTimer(1);
|
|
// EventSetMillisecondTimer(100);
|
|
|
|
//
|
|
// Alert Initialization ...
|
|
string msg = "Initialized Successfully ...";
|
|
eaAlert.Alert(msg);
|
|
|
|
//
|
|
// 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);
|
|
|
|
//
|
|
// Alert De Initialization Succeeded ...
|
|
msg = "De Initialized Successfully ...";
|
|
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(mTag);
|
|
eaAlert.SetLogAlerts(eALogAlerts);
|
|
eaAlert.SetMailAlerts(eAMailAlerts);
|
|
eaAlert.SetPushAlerts(eAPushAlerts);
|
|
eaAlert.SetEnableAlerts(eAEnableAlerts);
|
|
eaAlert.SetTerminalAlerts(eATerminalAlerts);
|
|
|
|
//
|
|
// 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.SaveTrades(true);
|
|
eaTradeHandler.SaveSignals(true);
|
|
eaTradeHandler.SaveConditions(true);
|
|
|
|
//
|
|
// Configure Alerts ...
|
|
eaTradeHandler.SetAlertPrefix(mTag);
|
|
eaTradeHandler.SetAlertEnableAlerts(eAEnableAlerts);
|
|
eaTradeHandler.SetAlertLogAlerts(eALogAlerts);
|
|
eaTradeHandler.SetAlertMailAlerts(eAMailAlerts);
|
|
eaTradeHandler.SetAlertPushAlerts(eAPushAlerts);
|
|
eaTradeHandler.SetAlertTerminalAlerts(eATerminalAlerts);
|
|
|
|
//
|
|
// Configure Trade Management ...
|
|
eaTradeHandler.AllowLong(eaAllowLong);
|
|
eaTradeHandler.AllowShort(eaAllowShort);
|
|
eaTradeHandler.MaxAllowedLongs(eaMaxAllowedLongs);
|
|
eaTradeHandler.MaxAllowedShorts(eaMaxAllowedShorts);
|
|
eaTradeHandler.UseMaxAllowedTradesPerSymbol(eaUseMaxAllowedTradesPerSymbol);
|
|
eaTradeHandler.MaxDrawdownPercentForOpenTrades(eaMaxDrawdownPercentForOpenTrades);
|
|
|
|
//
|
|
// Configure Hedging ...
|
|
eaTradeHandler.AllowHedging(eaAllowHedging);
|
|
eaTradeHandler.HedgeVolumeFactor(eaHedgeVolumeFactor);
|
|
eaTradeHandler.MinTradesForHedge(eaMinTradesForHedge);
|
|
eaTradeHandler.HedgeMinProfitPerVolumeFactor(eaMinimumProfitPerVolumeForHedging);
|
|
|
|
//
|
|
// Configure Trailing ...
|
|
eaTradeHandler.AllowTrailStops(eaAllowTrailStop);
|
|
eaTradeHandler.TrailBasedOnProfit(true);
|
|
eaTradeHandler.TrailStartInPoint(eaStartTrailInPoint);
|
|
eaTradeHandler.TrailStepInPoint(eaTrailStepInPoint);
|
|
eaTradeHandler.IgnoreTPOnTrail(eaIgnoreTPAfterTrail);
|
|
|
|
//
|
|
// Configure Recovery ...
|
|
eaTradeHandler.AllowRecover(eaAllowRecovery);
|
|
eaTradeHandler.ForcePressuresInRecovery(false);
|
|
eaTradeHandler.RecoveryTPPoint(eaRecoveryTPPoint);
|
|
eaTradeHandler.RecoverySLPoint(eaRecoverySLPoint);
|
|
eaTradeHandler.MaxAllowedRecover(eaMaxAllowedRecoveryTrades);
|
|
eaTradeHandler.RecoveryVolumeMultiplier(eaRecoveryVolumeMultiplier);
|
|
eaTradeHandler.MaxAllowedRecoveryVolume(eaMaxAllowedRecoveryTradesVolume);
|
|
|
|
//
|
|
// Single Symbol ...
|
|
if (!eaMultiSymbol)
|
|
{
|
|
//
|
|
// Create Class Instance ...
|
|
XSCXCHStrategy *xchStrategy;
|
|
xchStrategy = new XSCXCHStrategy(
|
|
_Symbol,
|
|
_Period,
|
|
PERIOD_H1, // Analyzing Period
|
|
eaVolume,
|
|
eaR2R, // R2R ...
|
|
eaSlippage,
|
|
eaMagicNumber,
|
|
true, // Ignore Signal Execution
|
|
eaUseFixedTPSLPoints, // Use TP SL Point
|
|
false, // Use Max
|
|
eaTPPoint, // TP
|
|
eaSLPoint, // SL
|
|
eaIgnoreTP,
|
|
eaIgnoreSL,
|
|
eaAllowLong,
|
|
eaAllowShort,
|
|
eaMaxAllowedLongs, // Max Longs
|
|
eaMaxAllowedShorts // Max Shorts
|
|
);
|
|
|
|
//
|
|
// Configuere Strategy ...
|
|
xchStrategy.EnableXCHM(true);
|
|
xchStrategy.EnableXCHHK(true);
|
|
xchStrategy.EnableXCHSTR(true);
|
|
xchStrategy.EnableXCHCHE(true);
|
|
xchStrategy.DrawImportantAreas(false);
|
|
xchStrategy.AddXCHSignalEventHandler(OnSignalRecieved);
|
|
|
|
//
|
|
// Configure Alerts ...
|
|
xchStrategy.SetAlertPrefix(mTag);
|
|
xchStrategy.SetAlertEnableAlerts(eAEnableAlerts);
|
|
xchStrategy.SetAlertLogAlerts(eALogAlerts);
|
|
xchStrategy.SetAlertMailAlerts(eAMailAlerts);
|
|
xchStrategy.SetAlertPushAlerts(eAPushAlerts);
|
|
xchStrategy.SetAlertTerminalAlerts(eATerminalAlerts);
|
|
|
|
//
|
|
// Register Strategy ...
|
|
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++)
|
|
{
|
|
//
|
|
// Select Symbol ...
|
|
string iSymbol = symbols[i];
|
|
|
|
//
|
|
// Create Class Instance ...
|
|
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
|
|
);
|
|
|
|
//
|
|
// Configuere Strategy ...
|
|
iStrategy.EnableXCHM(true);
|
|
iStrategy.EnableXCHHK(true);
|
|
iStrategy.EnableXCHSTR(true);
|
|
iStrategy.EnableXCHCHE(true);
|
|
iStrategy.DrawImportantAreas(false);
|
|
iStrategy.AddXCHSignalEventHandler(OnSignalRecieved);
|
|
|
|
//
|
|
// Configure Alerts ...
|
|
iStrategy.SetAlertPrefix(mTag);
|
|
iStrategy.SetAlertEnableAlerts(eAEnableAlerts);
|
|
iStrategy.SetAlertLogAlerts(eALogAlerts);
|
|
iStrategy.SetAlertMailAlerts(eAMailAlerts);
|
|
iStrategy.SetAlertPushAlerts(eAPushAlerts);
|
|
iStrategy.SetAlertTerminalAlerts(eATerminalAlerts);
|
|
|
|
//
|
|
// Register Strategy ...
|
|
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()
|
|
{
|
|
//
|
|
// Monthly Report ....
|
|
if (eaAlertNewMonths &&
|
|
eaTimeTracker.IsNewMonth())
|
|
{
|
|
//
|
|
string msg = "New Month ...";
|
|
|
|
//
|
|
eaAlert.Alert(msg);
|
|
}
|
|
|
|
//
|
|
// Weekly Report ....
|
|
if (eaAlertNewWeeks &&
|
|
eaTimeTracker.IsNewWeek())
|
|
{
|
|
//
|
|
string msg = "New Week ...";
|
|
|
|
//
|
|
eaAlert.Alert(msg);
|
|
}
|
|
|
|
//
|
|
// Daily Report ....
|
|
if (eaAlertNewDays &&
|
|
eaTimeTracker.IsNewDay())
|
|
{
|
|
//
|
|
string msg = "New Day ...";
|
|
|
|
//
|
|
eaAlert.Alert(msg);
|
|
}
|
|
|
|
//
|
|
// Hourly Report ....
|
|
if (eaAlertNewHours &&
|
|
eaTimeTracker.IsNewHour())
|
|
{
|
|
//
|
|
string msg = "New Hour ...";
|
|
|
|
//
|
|
eaAlert.Alert(msg);
|
|
}
|
|
}
|
|
|
|
//
|
|
// SIGNAL EVENT Handlers ...
|
|
//
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
// Since Signal Filtering done based on
|
|
// Strategy and it's not related to Public
|
|
// TradeHandler for Seperation of Concern issue,
|
|
// we do this here ...
|
|
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 = parser.GenerateSignalConditions(
|
|
signal,
|
|
conditions //
|
|
); // conditionsSummary;
|
|
|
|
//
|
|
// Execute Signal Using Trade Handler ...
|
|
ENUM_X_SIGNAL_EXECUTION_RESULT state;
|
|
bool isExecuted = eaTradeHandler.ExecuteSignal(
|
|
signal,
|
|
state //
|
|
);
|
|
}
|
|
|
|
//
|
|
void OnStopLossTriggered(const XDeal &deal)
|
|
{
|
|
//
|
|
// Finish ...
|
|
eaTradeHandler.Finish(deal);
|
|
}
|
|
|
|
//
|
|
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 //
|
|
);
|
|
}
|
|
|
|
// |