Files

1360 lines
32 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Expert Advisor
// ----------------------------------------
// Name: X121EA
// Description: this is an expert controller
// advisors which provides a mechanism for use them ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm X121EA"
#property strict
//
// START Definitions ...
//
//
// Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Alert Library ...
#include "../Libraries/x-saherelm.alert.lib.mq5"
//
// Draw Library ...
#include "../Libraries/x-saherelm.draw.lib.mq5"
//
// Account Class ...
#include "../Classes/x-saherelm.xaccount.class.mq5"
//
// Trade Class ...
#include "../Classes/x-saherelm.xtrade.class.mq5"
//
// Signal Provider Class Library ...
#include "../Providers/x.saherelm.x121.provider.mq5"
//
// Draw Library ...
#include "../Libraries/x-saherelm.x121.draw.lib.mq5"
//
#define ShortName "X121EA"
//
// Convert Position to Signal ...
XSignal ToSignalInfo(
XPosition &position)
{
//
XSignal result;
//
result.tp = position.tp;
result.sl = position.sl;
result.type = position.type;
result.entry = position.entry;
result.symbol = position.symbol;
result.period = position.period;
result.volume = position.volume;
//
return result;
}
//
// END Definitions ...
//
//
// START Inputs ...
//
//
// EA ...
input group "Common";
input bool xEAEnable = true; // Enable EA
input int xEASlippage = 10; // Slippgae
input ulong xEAMagicNumber = 1604056; // Magic Number
//
// Signals ...
input group "Signals";
input bool xEAEnableLongs = true; // Enable Long Trades
input bool xEAEnableShorts = true; // Enable Short Trades
//
// Risk Management ...
input group "Risk Management";
input int xEAMaxOpenPositions = 15; // Max Allowed Open Positions
input double xEAMaxAllowedDrawDownFactor = 0.15; // Max Allowed Drawdown Factor
// input double xEAMinProfitPerOpenPositionForHedging = 0.9; // Close All Positions Fctor
//
// Alerts ...
input group "Alerts";
input bool xEAEnableAlerts = true; // Enable Events Alert
input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour
input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day
input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week
input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month
//
// END Inputs ...
//
//
// START Including Providers ...
//
//
// Logger Library ...
#include "../Libraries/x-saherelm.log.lib.mq5"
//
// END Including Providers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
bool isXEANewHour;
bool isXEANewDay;
bool isXEANewWeek;
bool isXEANewMonth;
//
// Determines EA is Running On Test Mode or not ...
bool xEAIsTestMode = false;
//
// Check prevent Double Signalling on Same Candle ...
bool xEAWaitUntilNextCandle = false;
//
XSCTrade *xEATrade;
XSCAccount *xEAAccount;
XSCX121Provider *xEAProvider;
// X121SignalProvider xEAProviders[];
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
int OnInit()
{
//
logTag = ShortName;
drawPrefix = logTag;
alertPrefix = logTag;
//
// Reset Timings ...
ResetTiming();
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize X121EA Providers ...
if (!InitializeProviders())
{
return INIT_FAILED;
}
//
// 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
//
// Here we can handle De Initialization Reasons ...
delete xEATrade;
delete xEAAccount;
delete xEAProvider;
//
// De Initialize XEA Providers ...
}
//
// On Tick Handler ...
void OnTick()
{
//
// Handle Monthly Alert ...
bool isFirstMonth = xMonth == -1;
isXEANewMonth = IsNewMonth();
bool canMonthlyAlert =
isXEANewMonth &&
xEAEnableAlerts &&
xEAEnableMonthlyAlerts;
if (canMonthlyAlert)
{
//
string message = "New Month ...";
//
SendAlert(message);
}
//
// Handle Weekly Alert ...
bool isFirstWeek = xDayOfWeek == -1;
isXEANewWeek = IsNewWeek();
bool canWeeklyAlert =
isXEANewWeek &&
xEAEnableAlerts &&
xEAEnableWeeklyAlerts;
if (canWeeklyAlert)
{
//
string message = "New Week ...";
//
SendAlert(message);
}
//
// Handle Daily Alert ...
bool isFirstDay = xDay == -1;
isXEANewDay = IsNewDay();
bool canDailyAlert =
isXEANewDay &&
xEAEnableAlerts &&
xEAEnableDailyAlerts;
if (canDailyAlert)
{
//
string message = "New Day ...";
//
SendAlert(message);
}
//
// Handle Hourly Alert ...
bool isFirstHour = xHour == -1;
isXEANewHour = IsNewHour();
bool canHourlyAlert =
isXEANewHour &&
xEAEnableAlerts &&
xEAEnableHourlyAlerts;
if (canHourlyAlert)
{
//
string message = "New Hour ...";
//
SendAlert(message);
}
//
// Handle Guarding Strategies ...
HandleGuard();
//
// Prevent Going Forward if user Disable it ...
if (xEAEnable)
{
//
// TODO: Remove this due test ...
// if (IsRunningOnTestMode())
// {
// xEATrade.
// }
//
// Call All Providers OnTick Method ...
CallProvidersOnTick();
}
}
//
// Handle Trade Events ...
void OnTrade()
{
//
// Handle Trading State ...
xEATrade.HandleOnTrade();
}
//
// Chart Events Handling ...
void OnChartEvent(
const int id, // event ID
const long &lparam, // long type event parameter
const double &dparam, // double type event parameter
const string &sparam // string type event parameter
)
{
}
//
// Handle Signal Event ...
void OnSignalConditionsRecieved(X121MarketConditions &info)
{
//
if (!info.hasSignal)
{
return;
}
//
// Diable Trading if a Direction is Disabled ...
if ((info.signal.type == POSITION_TYPE_BUY && !xEAEnableLongs) ||
(info.signal.type != POSITION_TYPE_SELL && !xEAEnableShorts))
{
return;
}
//
// Count Open Positions ...
int openPositionsCount = xEATrade.PositionsCount();
if (xEAMaxOpenPositions > 0 &&
openPositionsCount >= xEAMaxOpenPositions)
{
//
string msg = "Max Allowed Positions Reached, Ignore Trading ...";
LogMessage(msg);
//
return;
}
//
// Retrieve Tradable Balance ...
double availableBalance = xEAAccount.GetEquity();
//
// Verify Available Balance ...
double balance = xEAAccount.GetBalance();
//
double forCalculationBalance = MathMax(balance, availableBalance);
double forTradeBalance = MathMin(balance, availableBalance);
double mustHaveBalanceForTrading = forCalculationBalance * xEAMaxAllowedDrawDownFactor;
if (availableBalance < mustHaveBalanceForTrading)
{
//
string msg = "Max Allowed Equity for Trading Reached, Ignore Trading ...";
LogMessage(msg);
//
return;
}
//
// Here i Must Calculate TP and SL based on R2R and riskable Factor ...
bool isLong = IsLong(info.signal.type);
//
// Check Order Mode ...
if (info.signal.mode == NULL)
{
//
// Set Market Execution as Default ...
info.signal.mode = X_ORDER_MODE_MARKET;
}
//
bool isMarketMode = info.signal.mode == X_ORDER_MODE_MARKET;
//
// Calculate Entry Price ...
if (info.signal.entry <= 0)
{
//
info.signal.entry = GetEntry(
info.signal.symbol,
info.signal.type);
}
//
// Calculate TP and SL ...
double mPoint = GetPoints(info.signal.symbol);
//
// Normalize SL Price ...
if (info.signal.sl > 0)
{
info.signal.sl = NormalizePrice(info.signal.sl, info.signal.symbol);
}
//
// Retrieve Symbol Point Value ...
double pointValue = xEAAccount.GetPointValue(info.signal.symbol);
//
// Calculate Risk ...
double riskPrice = MathAbs(info.signal.entry - info.signal.sl);
riskPrice = NormalizePrice(riskPrice, info.signal.symbol);
//
double riskPoints = PriceToPoint(riskPrice);
riskPoints = NormalizeDouble(riskPoints, 0);
//
// Calculating Reward based On Ratio ...
double rewardPoints = riskPoints * info.signal.r2r;
double rewardPrice = PointToPrice(rewardPoints);
rewardPrice = NormalizePrice(rewardPrice, info.signal.symbol);
//
// Calculate TP Price ...
double tpValue = isLong
? info.signal.entry + rewardPrice
: info.signal.entry - rewardPrice;
//
// Calculate SL Price ...
double slValue = isLong
? info.signal.entry - riskPrice
: info.signal.entry + riskPrice;
//
// Balance Amount which we risks on each Provider's Trade ...
double amount = availableBalance * info.signal.riskAmount;
//
// Calculating Trade Volume based on risk Points and Amount ...
double volume =
info.signal.useRiskAmountAsVolume
? info.signal.riskAmount
: xEAAccount.CalculateVolume(
info.signal.symbol,
amount,
riskPoints);
volume = NormalizeVolume(volume, info.signal.symbol);
//
// Set Caculated TP, SL and Volume ...
if (info.signal.calculateTP)
{
//
if (info.signal.useSupportAndResistance)
{
//
double mTmp[];
double mTmpPrice;
LogMessage("MomentumStep: " + (string)info.momentumStep);
//
// Find Good Entry Points ...
if (!isMarketMode)
{
//
if (isLong)
{
//
ArrayCopy(
mTmp,
info.supportResistances.res);
}
else
{
//
ArrayCopy(
mTmp,
info.supportResistances.sup);
}
//
mTmpPrice =
isLong
? info.signal.entry + info.momentumStep
: info.signal.entry - info.momentumStep;
double entry =
FindLesserThanValue(
mTmpPrice,
mTmp,
!isLong);
Clean(mTmp);
//
info.signal.entry = entry;
}
//
// Find Good SL Point ...
//
if (isLong)
{
//
ArrayCopy(
mTmp,
info.supportResistances.sup);
}
else
{
//
ArrayCopy(
mTmp,
info.supportResistances.res);
}
//
mTmpPrice =
isLong
? info.signal.entry - info.momentumStep
: info.signal.entry + info.momentumStep;
double sl =
FindBiggerThanValue(
mTmpPrice,
mTmp,
!isLong);
Clean(mTmp);
//
info.signal.sl = sl;
//
// Find Good TP Point ...
//
if (isLong)
{
//
ArrayCopy(
mTmp,
info.supportResistances.res);
}
else
{
//
ArrayCopy(
mTmp,
info.supportResistances.sup);
}
//
// Risk Price ...
mTmpPrice = MathAbs(info.signal.entry - info.signal.sl);
//
// Reward Price ...
mTmpPrice *= info.signal.r2r;
//
// Start Search TP ...
mTmpPrice = isLong
? info.signal.entry + mTmpPrice
: info.signal.entry - mTmpPrice;
double tp =
FindLesserThanValue(
mTmpPrice,
mTmp,
!isLong);
Clean(mTmp);
//
info.signal.tp = tp;
}
else
{
//
info.signal.tp = tpValue;
info.signal.sl = slValue;
}
}
//
info.signal.volume = volume;
//
string comment = GenerateProvidersString(info.signal);
//
// TODO: Remove this ...
ulong mTicket = MathRand() * 100000;
DrawSignal(
mTicket,
info.signal);
//
DrawSupportResistance(
0,
info.supportResistances,
info.signal.providers[0]);
//
return;
//
// Here We Execute the Signal by Trader Class Instance ...
bool isPositionExecuted = xEATrade.ExecuteSignal(
info.signal,
comment);
//
if (isPositionExecuted)
{
//
// Retrieve Position Ticket ...
ulong ticket = 0;
bool isMarketMode = info.signal.mode == X_ORDER_MODE_MARKET;
if (isMarketMode)
{
ticket = xEATrade.GetLastOpenPositionTicket();
}
else
{
ticket = xEATrade.GetLastPlacedOrderTicket();
}
if (ticket == 0)
{
return;
}
//
// Draw Signal ...
DrawSignal(ticket, info.signal);
//
// Alert Position ...
string msg =
(isMarketMode
? "Position"
: "Order") +
": " + (string)ticket + " was " + (isMarketMode ? "Opened" : "Placed") + " ...";
LogMessage(msg);
}
}
//
// Handle StopLoss Event ...
void OnStopLossTriggered(const XDeal &deal)
{
//
string msg = "SL: " + (string)deal.positionId;
LogMessage(msg);
}
//
// Handle TakeProfit Event ...
void OnTakeProfitTriggered(const XDeal &deal)
{
//
string msg = "TP: " + (string)deal.positionId;
LogMessage(msg);
}
//
// Handle Deals Changed Event ...
void OnDealsChangedHandler(int count)
{
//
// string msg = "Deals Changed: " + (string)count;
// LogMessage(msg);
}
//
// Handle Order Changed Event ...
void OnOrdersChangedHandler(int count)
{
//
// string msg = "Orders Changed: " + (string)count;
// LogMessage(msg);
}
//
// Handle Position Changed Event ...
void OnPositionsChangedHandler(int count)
{
// //
// int positionsCount = xEATrade.PositionsCount();
// if (count <= 0 || positionsCount <= 0)
// {
// return;
// }
// //
// XPosition positions[];
// xEATrade.GetPositions(positions);
// for (int i = 0; i < positionsCount; i++)
// {
// //
// XPosition iPosition = positions[i];
// //
// bool isIPositionHasSupport =
// xEATrade.HasSupport(iPosition.ticket);
// if (isIPositionHasSupport)
// {
// continue;
// }
// //
// double sl = iPosition.sl;
// //
// XSignal signal;
// bool isGenerated = xEATrade.GenerateSLSupportSignal(
// signal,
// iPosition.ticket);
// if (!isGenerated)
// {
// continue;
// }
// //
// string comment = GenerateSupportSignalComment(iPosition.ticket);
// //
// bool isExecuted = xEATrade.ExecuteSignal(
// signal,
// comment);
// if (!isExecuted)
// {
// continue;
// }
// //
// // Now we have to Disable Position SL ...
// bool isModified = xEATrade.Modify(
// iPosition.ticket,
// 0,
// iPosition.tp,
// iPosition.comment);
// if (!isModified)
// {
// return;
// }
// //
// string msg = "Execute SL Support Signal for Position (" + (string)iPosition.ticket + ") successfully ...";
// LogMessage(msg);
// }
//
// LogMessage("OnPositionsChangedHandler ...");
}
//
// Handle Trade State Changed ...
void OnTradeStateChangedHandler(
const XOnTradeHandlerState &state)
{
// //
// string msg = "Trade State Changed ...";
// LogMessage(msg);
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = true;
//
// Validate Args ...
result =
//
xEASlippage > 0 &&
xEAMagicNumber > 0
//
// TODO: add new validations here ...
//
;
//
// Logging State ...
string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ...";
LogMessage(message);
//
return result;
}
//
// Extract Signal Provider Struct from User Input ...
bool InitializeProviders()
{
//
bool result = false;
//
// Account Manager ...
xEAAccount = new XSCAccount();
//
// Trader ...
xEATrade = new XSCTrade(
xEASlippage,
xEAMagicNumber);
//
// Attach Event Handlers ...
xEATrade.AddOnStopLossEventHandler(OnStopLossTriggered);
xEATrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
xEATrade.AddOnDealsChangedEventHandler(OnDealsChangedHandler);
xEATrade.AddOnOrdersChangedEventHandler(OnOrdersChangedHandler);
xEATrade.AddOnPositionsChangedEventHandler(OnPositionsChangedHandler);
xEATrade.AddOnTradeStateChangedEventHandler(OnTradeStateChangedHandler);
//
// Prepare Config ...
//
// Prepare Default and Clean Config ...
// in this Config non of Indicators doesn't Draw anything on chart ...
// TODO: We Have to Get These from Inputs of Users ...
X121ProviderInputs configs;
//
// XCT ...
// Candle Timing ...
configs.xctConfig.clr = clrBlueViolet;
configs.xctConfig.corner = CORNER_RIGHT_UPPER;
configs.xctConfig.showCandleTime = true;
//
// XCC ...
// Candle Styling ...
configs.xccConfig.upColor = clrLime;
configs.xccConfig.downColor = clrRed;
configs.xccConfig.lineColor = clrLime;
configs.xccConfig.bearishColor = clrRed;
configs.xccConfig.bullishColor = clrLime;
configs.xccConfig.volumesColor = clrGreen;
configs.xccConfig.showCandles = true;
//
// XHK ...
// HikenAshi Candle Representing ...
configs.xhkConfig.drawCandleLines = false;
//
// XTM ...
// Trend Magic ...
configs.xtmConfig.length = 35;
configs.xtmConfig.shift = 0;
configs.xtmConfig.method = MODE_SMA;
configs.xtmConfig.appliedTo = PRICE_LOW;
configs.xtmConfig.showLine = false;
//
// XPV ...
// Peaks And Vales ...
configs.xpvConfig.shortLength = 9;
configs.xpvConfig.mediumLength = 17;
configs.xpvConfig.longLength = 26;
configs.xpvConfig.hindLength = 35;
configs.xpvConfig.fiboLevel1 = 0.382;
configs.xpvConfig.fiboLevel2 = 0.5;
configs.xpvConfig.fiboLevel3 = 0.618;
configs.xpvConfig.hhMode = MODE_HIGH;
configs.xpvConfig.llMode = MODE_LOW;
configs.xpvConfig.showPeaksAndVales = false;
configs.xpvConfig.showLevels = false;
configs.xpvConfig.showFibo1Levels = false;
configs.xpvConfig.showFibo2Levels = false;
configs.xpvConfig.showFibo3Levels = false;
//
// XAMA ...
// Adaptive Moving Average ...
configs.xamaConfig.length = 52;
configs.xamaConfig.fastEMA = 2;
configs.xamaConfig.slowEMA = 30;
configs.xamaConfig.maShift = 0;
configs.xamaConfig.appliedTo = PRICE_LOW;
configs.xamaConfig.showLine = false;
//
// XMRB ...
// Moving Average Ribbon ...
configs.xmrbConfig.fast1Length = 3;
configs.xmrbConfig.slow1Length = 5;
configs.xmrbConfig.fast2Length = 8;
configs.xmrbConfig.slow2Length = 13;
configs.xmrbConfig.fast3Length = 21;
configs.xmrbConfig.slow3Length = 34;
configs.xmrbConfig.fast4Length = 55;
configs.xmrbConfig.slow4Length = 89;
configs.xmrbConfig.fast5Length = 144;
configs.xmrbConfig.slow5Length = 233;
configs.xmrbConfig.ribbonMode = MODE_EMA;
configs.xmrbConfig.ribbonAppliedTo = PRICE_CLOSE;
configs.xmrbConfig.showFastMa = false;
configs.xmrbConfig.showSlowMa = false;
configs.xmrbConfig.showRibbon = false;
//
// XCHE ...
// Chandelier Exit Points ...
configs.xcheConfig.length = 35;
configs.xcheConfig.loopback = 26;
configs.xcheConfig.multiplier1 = 3;
configs.xcheConfig.multiplier2 = 3.5;
configs.xcheConfig.upAppliedTo = PRICE_HIGH;
configs.xcheConfig.downAppliedTo = PRICE_LOW;
configs.xcheConfig.showLongExit1Line = false;
configs.xcheConfig.showShortExit1Line = false;
configs.xcheConfig.showLongExit2Line = false;
configs.xcheConfig.showShortExit2Line = false;
//
// XICH ...
// Ichimopku Kinko Hyo ...
configs.xichConfig.tenkanSenLength = 9;
configs.xichConfig.tenkanSenMode = X_XICH_HH_LL_MODE;
configs.xichConfig.kijunSenLength = 26;
configs.xichConfig.kijunSenMode = X_XICH_HH_LL_MODE;
configs.xichConfig.senkouSpanBLength = 52;
configs.xichConfig.senkouSpanBMode = X_XICH_HH_LL_MODE;
configs.xichConfig.chikuoSpanAppliedTo = PRICE_CLOSE;
configs.xichConfig.showTenkanSen = false;
configs.xichConfig.showKijunSen = false;
configs.xichConfig.showKijunSenPlus = false;
configs.xichConfig.showKijunSenNegative = false;
configs.xichConfig.showChikouSpan = false;
configs.xichConfig.showSenkouSpanA = false;
configs.xichConfig.showSenkouSpanB = false;
configs.xichConfig.showKumo = false;
configs.xichConfig.shiftKumo = true;
//
// XTRND ...
// Trend Detector ...
configs.xtrndConfig.cycleLength = 2;
configs.xtrndConfig.numberOfVerifications = 2;
configs.xtrndConfig.hhMode = MODE_HIGH;
configs.xtrndConfig.llMode = MODE_LOW;
configs.xtrndConfig.l1Method = X_PERIOD_AUTO;
configs.xtrndConfig.l1Period = NULL;
configs.xtrndConfig.l2Method = X_PERIOD_AUTO;
configs.xtrndConfig.l2Period = NULL;
configs.xtrndConfig.l3Method = X_PERIOD_AUTO;
configs.xtrndConfig.l3Period = NULL;
configs.xtrndConfig.showConsolidations = false;
configs.xtrndConfig.showTrend = false;
configs.xtrndConfig.showL1Trend = false;
configs.xtrndConfig.showL2Trend = false;
configs.xtrndConfig.showL3Trend = false;
//
// XSSLC ...
// SSL Channel ...
configs.xsslcConfig.length = 36;
configs.xsslcConfig.method = MODE_SMA;
configs.xsslcConfig.upAppliedTo = PRICE_HIGH;
configs.xsslcConfig.downAppliedTo = PRICE_LOW;
configs.xsslcConfig.showUp = false;
configs.xsslcConfig.showDown = false;
//
// XHULL ...
// Hull Trend Detection Channel ...
configs.xhullConfig.length = 72;
configs.xhullConfig.divisor = 2;
configs.xhullConfig.upAppliedTo = PRICE_HIGH;
configs.xhullConfig.downAppliedTo = PRICE_LOW;
configs.xhullConfig.showUpZone = false;
configs.xhullConfig.showDownZone = false;
//
// Default Configs For Different States ...
bool showPV = true;
bool showHK = true;
bool showCHE = true;
bool showTRND = true;
bool simpleIchi = true;
//
//
if (showHK)
{
//
// Hiken Ashi ...
configs.xccConfig.showCandles = false;
configs.xhkConfig.drawCandles = true;
}
if (showPV)
{
//
// Peaks and Vales ...
configs.xpvConfig.showFibo1Levels = true;
configs.xpvConfig.showFibo2Levels = true;
configs.xpvConfig.showFibo3Levels = true;
configs.xpvConfig.showPeaksAndVales = true;
}
if (simpleIchi)
{
//
// Simple Ichimoku Kinko Hyo ...
configs.xichConfig.showKijunSen = true;
configs.xichConfig.showTenkanSen = true;
configs.xichConfig.showSenkouSpanA = true;
configs.xichConfig.showSenkouSpanB = true;
}
if (showCHE)
{
//
// Chandelier Exit ...
configs.xcheConfig.showLongExit1Line = true;
configs.xcheConfig.showLongExit2Line = true;
configs.xcheConfig.showShortExit1Line = true;
configs.xcheConfig.showShortExit2Line = true;
}
if (showTRND)
{
//
// Show Trend ...
configs.xtrndConfig.showL1Trend = true;
configs.xtrndConfig.showL2Trend = true;
configs.xtrndConfig.showL3Trend = true;
}
//
xEAProvider = new XSCX121Provider(
_Symbol,
_Period);
//
// Attach Event Handlers ...
xEAProvider.AddOnSignalConditionEventHandler(OnSignalConditionsRecieved);
//
// Initialize Provider ...
result = xEAProvider.SetConfig(configs);
if (!result)
{
return result;
}
//
return result;
}
//
void CallProvidersOnTick()
{
//
// int providersCount = ArraySize(xEAProviders);
// if (providersCount <= 0)
// {
// return;
// }
// //
// // Loop Through Providers ...
// for (int i = 0; i < providersCount; i++)
// {
// //
// X121SignalProvider providerDescriptor = xEAProviders[i];
// //
// providerDescriptor.provider.OnTick();
// }
//
xEAProvider.OnTick();
}
//
void GetPositions(
XPosition &result[], // Hold Result ...
string symbol = NULL, // Trading Symbol ...
ENUM_POSITION_TYPE type = NULL, // Trading Type ...
ENUM_TIMEFRAMES period = NULL, // Trading Period ...
ENUM_X121_SIGNAL_PROVIDERS provider = NULL // Trade Provider ...
)
{
//
Clean(result);
//
int positionsCount = xEATrade.PositionsCount();
if (positionsCount <= 0)
{
return;
}
//
XPosition positions[];
xEATrade.GetPositions(
positions,
symbol,
period);
positionsCount = ArraySize(positions);
if (positionsCount <= 0)
{
return;
}
//
if (provider == NULL && type == NULL)
{
//
ArrayResize(
result,
ArraySize(positions));
//
for (int i = 0; i < positionsCount; i++)
{
//
Add(
positions[i],
result);
}
//
return;
}
//
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
//
ENUM_X121_SIGNAL_PROVIDERS iProvider = ExtractProvider(iPosition);
if (provider != NULL && iProvider != provider)
{
continue;
}
//
if (type == NULL || iPosition.type == type)
{
//
Add(
iPosition,
result);
}
}
}
//
// START Guard Functions ...
//
//
// Do Guard Actions ...
void HandleGuard()
{
//
// Retrieve Provider Guard Actions ...
X121Guard guards[];
xEAProvider.ProvideGuard(guards);
int guardsCount = ArraySize(guards);
if (guardsCount <= 0)
{
return;
}
//
for (int i = 0; i < guardsCount; i++)
{
//
X121Guard iGuard = guards[i];
//
switch (iGuard.action)
{
//
// Hedge In Profit Specified Positions ...
case X_GUARD_ACTION_HEDGE:
HandleGuardHedgeAction(
iGuard.provider,
iGuard.symbol,
iGuard.type,
iGuard.period);
break;
//
// Trail Stop Loss in Specified Positions ...
case X_GUARD_ACTION_TRAIL_STOP:
HandleGuardTrailingStopAction(
iGuard.provider,
iGuard.symbol,
iGuard.type,
iGuard.period,
iGuard.dblPayLoad);
break;
//
// Force Close Specified Positions ...
case X_GUARD_ACTION_FORCE_CLOSE:
HandleGuardForceCloseAction(
iGuard.provider,
iGuard.symbol,
iGuard.type,
iGuard.period);
break;
//
// Generate and Place Support Signals ...
case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL:
HandleGuardAddSupportPositionAction(
iGuard.provider,
iGuard.symbol,
iGuard.type,
iGuard.period);
break;
//
// Delete All Placed Pending Orders ...
case X_GUARD_ACTION_CANCEL_PENDING_ORDERS:
HandleGuardCancelPendingOrdersAction(
iGuard.provider,
iGuard.symbol,
iGuard.type,
iGuard.period);
break;
}
}
}
//
// Close All Specified Provider's Positions in Profit Summary ...
void HandleGuardHedgeAction(
string provider, // Positions Provided by Specific Provider
string symbol, // Trading Symbol
ENUM_POSITION_TYPE type, // Trading Type
ENUM_TIMEFRAMES period // Specified Time Frame
)
{
//
// TODO: Implement this ...
}
//
// Force Close Specified Set Of Position ...
void HandleGuardForceCloseAction(
string provider, // Positions Provided by Specific Provider
string symbol, // Trading Symbol
ENUM_POSITION_TYPE type, // Trading Type
ENUM_TIMEFRAMES period // Specified Time Frame
)
{
//
ENUM_X121_SIGNAL_PROVIDERS mProvider = ExtractProvider(provider);
//
XPosition positions[];
GetPositions(
positions,
symbol,
type,
period,
mProvider);
if (ArraySize(positions) <= 0)
{
return;
}
//
string comment = provider + " Force Close Due Market Sense Change ...";
xEATrade.ClosePositions(
positions,
comment);
//
LogMessage(comment);
}
//
// Trailing Specified Set Of Positions Stop Losses ...
void HandleGuardTrailingStopAction(
string provider, // Positions Provided by Specific Provider
string symbol, // Trading Symbol
ENUM_POSITION_TYPE type, // Trading Type
ENUM_TIMEFRAMES period, // Specified Time Frame
double sl // Desired SL Value ...
)
{
//
// TODO: Implement this ...
}
//
// Add Support Signal for Specified Positions ...
void HandleGuardAddSupportPositionAction(
string provider, // Positions Provided by Specific Provider
string symbol, // Trading Symbol
ENUM_POSITION_TYPE type, // Trading Type
ENUM_TIMEFRAMES period // Specified Time Frame
)
{
//
// TODO: Implement this ...
}
//
// Cancel all Placed Orders ...
void HandleGuardCancelPendingOrdersAction(
string provider, // Positions Provided by Specific Provider
string symbol, // Trading Symbol
ENUM_POSITION_TYPE type, // Trading Type
ENUM_TIMEFRAMES period // Specified Time Frame
)
{
//
// TODO: Implement this ...
}
//
// END Guard Functions ...
//
//
// END Functions ...
//