Files
xMQL5/MQLTestWorkspace/BKPS/BKP/x121 old style indicators/Experts/x-saherelm.xea.mq5
T

1554 lines
32 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Expert Advisor
// ----------------------------------------
// Name: XEA
// 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 XEA EA"
#property strict
//
// START Definitions ...
//
//
string mProviderPrefix = "PRV";
string mSupportPrefix = "SP";
//
enum ENUM_X_SIGNAL_PROVIDERS
{
NONE = 0,
XICHI = 1,
};
//
// 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
//
// Determine Symbols and TimeFrames ...
input group "Symbols and Time Frames";
//
// (EURUSDb|M5|0.0005)
// (EURUSDb|M5|0.0005)_(USDCHFb|M5|0.0005)_(USDJPYb|M5|0.0005)_(GBPUSDb|M5|0.0005)
// (EURUSDb|M5,M15,M30|0.0005)_(USDCHFb|M5,M15|0.0005)_(USDJPYb|M5,M15|0.0005)_(GBPUSDb|M5,M15,M30|0.0005)_(AUDUSDb|M5,M15|0.0005)_(USDCADb|M5,M15|0.0005)_(NZDUSDb|M5,M15|0.0005)_(XAUUSDb|M5|0.0005)
input string xEAProvidersDescription = "(EURUSDb|M5|0.0005)"; // Specify Symbols and Time Frames
//
// 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 bool xEABalancePositions = true; // Balance Positions
input double xEAMaxAllowedDrawDownFactor = 0.15; // Max Allowed Drawdown Factor
input int xEATrailStopsInPoint = 0; // Trail Stops Moving Rate in Points
input int xEAMinProfitForHedging = 5; // Hedge Positions on Minimum Profit
input double xEAMaxDrawdownForClosePosition = 0; // Max Drawdown For Close Positions
input double xEAMaxDrawdownForSupportPosition = 0; // Max Drawdown For Open Support Positions
//
// 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"
//
// 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"
//
// 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;
XLastSignal xEALastSignals[];
X121SignalProvider xEAProviders[];
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
int OnInit()
{
//
logTag = "XEA";
drawPrefix = logTag;
alertPrefix = logTag;
//
// Reset Timings ...
ResetTiming();
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize XEA Providers ...
if (!InitializeProviders())
{
return INIT_FAILED;
}
//
// Initialize Trade Class ...
xEATrade = new XSCTrade(
xEASlippage,
xEAMagicNumber);
//
// Initialize Account Class ...
xEAAccount = new XSCAccount();
//
// 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;
//
// 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);
}
//
Guard();
//
// Prevent Going Forward if user Disable it ...
if (xEAEnable)
{
//
// Call All Providers OnTick Method ...
CallProvidersOnTick();
}
}
//
// Handle Trade Events ...
void OnTrade()
{
//
// TODO: Complete this ...
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
// TODO: Fix this ...
bool result = true;
//
// Validate Args ...
result =
//
xEASlippage > 0 &&
xEAMagicNumber > 0 &&
xEAMaxOpenPositions > 0 &&
xEAMaxAllowedDrawDownFactor > 0 &&
xEAMaxAllowedDrawDownFactor <= 0.4 &&
StringLen(xEAProvidersDescription) > 0
//
;
//
// 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;
//
string workingString = xEAProvidersDescription;
StringTrimLeft(workingString);
StringTrimRight(workingString);
if (StringLen(workingString) == 0)
{
return result;
}
//
string descriptors[];
int numOfDescriptors = StringSplit(
workingString,
StringGetCharacter("_", 0),
descriptors);
if (numOfDescriptors <= 0)
{
return result;
}
//
// Loop Through Descriptors ...
for (int iDX = 0; iDX < numOfDescriptors; iDX++)
{
//
string descriptor = descriptors[iDX];
//
// Clear Start and End Pranteses ...
StringReplace(
descriptor,
"(",
"");
StringReplace(
descriptor,
")",
"");
//
string descriptorData[];
int numOfData = StringSplit(
descriptor,
StringGetCharacter("|", 0),
descriptorData);
if (numOfData < 3)
{
continue;
}
//
string symbols[];
int numOfSymbols = StringSplit(
descriptorData[0],
StringGetCharacter(",", 0),
symbols);
if (numOfSymbols <= 0)
{
continue;
}
//
string timeFrames[];
int numOfTimeFrames = StringSplit(
descriptorData[1],
StringGetCharacter(",", 0),
timeFrames);
if (numOfTimeFrames <= 0)
{
continue;
}
//
string riskAmounts[];
int numOfRiskAmounts = StringSplit(
descriptorData[2],
StringGetCharacter(",", 0),
riskAmounts);
if (numOfRiskAmounts <= 0)
{
continue;
}
//
for (int cpIdx = 0; cpIdx < numOfSymbols; cpIdx++)
{
//
string symbol = symbols[cpIdx];
//
for (int tfIdx = 0; tfIdx < numOfTimeFrames; tfIdx++)
{
//
string timeFrame = timeFrames[tfIdx];
ENUM_TIMEFRAMES period = ToPeriod(timeFrame);
//
double riskAmount = (double)(numOfRiskAmounts == numOfTimeFrames
? riskAmounts[tfIdx]
: riskAmounts[0]);
//
string magicNumberString = "169" + (string)iDX + (string)cpIdx + (string)tfIdx + (string)PeriodSeconds(period) + "4056";
ulong magicNumber = (ulong)magicNumberString;
//
X121SignalProvider providerDescriptor;
//
providerDescriptor.symbol = symbol;
providerDescriptor.period = period;
providerDescriptor.riskAmount = riskAmount;
providerDescriptor.magicNumber = magicNumber;
//
// Initial Provider Class Instance ...
XSCX121Provider *x121Provider = new XSCX121Provider(
symbol,
period);
//
// Attach On Signal Event Listener ...
x121Provider.AddOnSignalEventHandler(OnSignalRecieved);
//
providerDescriptor.provider = x121Provider;
//
Add(
providerDescriptor,
xEAProviders);
}
}
}
//
result = true;
//
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();
}
}
//
void OnSignalRecieved(
XSignalInfo &info)
{
//
// Ignore Disabled Signals ...
if ((info.type == POSITION_TYPE_BUY && !xEAEnableLongs) ||
(info.type == POSITION_TYPE_SELL && !xEAEnableShorts))
{
return;
}
//
// Find Provider based On Signal Info ...
int providersCount = ArraySize(xEAProviders);
if (providersCount <= 0)
{
return;
}
//
if (StringLen(info.symbol) == 0 || info.period == NULL)
{
return;
}
//
bool isFoundDescriptor = false;
X121SignalProvider providerDescriptor;
//
for (int i = 0; i < providersCount; i++)
{
//
X121SignalProvider provDesc = xEAProviders[i];
//
if (provDesc.symbol == info.symbol &&
provDesc.period == info.period)
{
//
isFoundDescriptor = true;
providerDescriptor = provDesc;
//
break;
}
}
//
// Prevent Moving Forward if there is no Descriptor Found ...
if (!isFoundDescriptor)
{
return;
}
//
// Count Open Positions ...
int openPositionsCount = xEATrade.OpenPositionsCount();
//
if (xEABalancePositions)
{
//
// Count Same Signals for Balancing ...
int smaeTypeOpenPositionsCount = xEATrade.OpenPositionsCount("", info.type);
//
if (openPositionsCount > (int)xEAMaxOpenPositions / 3)
{
//
if (smaeTypeOpenPositionsCount > (int)openPositionsCount / 2)
{
return;
}
}
}
//
string mTagId = GenerateTag(info);
//
// Check Last Signal ...
datetime barTime = iTime(
info.symbol,
info.period,
0);
//
XLastSignal lastSignal = {};
int foundedLastSignalId = -1;
bool isFoundLastSignal = false;
int lastSignalsCount = ArraySize(xEALastSignals);
//
for (int i = 0; i < lastSignalsCount; i++)
{
//
XLastSignal mLS = xEALastSignals[i];
if (mLS.provider == mTagId)
{
//
lastSignal = mLS;
foundedLastSignalId = i;
isFoundLastSignal = true;
//
break;
}
}
//
if (isFoundLastSignal)
{
//
bool isSameDate = xEALastSignals[foundedLastSignalId].at == barTime;
if (isSameDate)
{
return;
}
else
{
xEALastSignals[foundedLastSignalId].at = barTime;
}
}
else
{
//
lastSignal.at = barTime;
lastSignal.provider = mTagId;
//
ArrayResize(
xEALastSignals,
ArraySize(xEALastSignals) + 1);
//
xEALastSignals[ArraySize(xEALastSignals) - 1] = lastSignal;
}
//
// Retrieve Tradable Balance ...
double availableBalance = xEAAccount.GetEquity();
//
// Here we Have to Check Some Conditions for Open
// Positions, before Do Calculations, for improve Performance ...
//
// Verify Open Positions ...
if (openPositionsCount >= xEAMaxOpenPositions)
{
//
LogMessage("Max Allowed Positions Reached ...");
return;
}
//
// Verify Available Balance ...
double balance = xEAAccount.GetBalance();
double minBalanceForTrades = balance * xEAMaxAllowedDrawDownFactor;
if (availableBalance <= minBalanceForTrades)
{
//
LogMessage("Max Drawdown Reached ...");
return;
}
//
// Here i Must Calculate TP and SL based on R2R and riskable Factor ...
bool isLong = IsLong(info.type);
//
// Correct Period ...
if (info.period == NULL)
{
info.period = providerDescriptor.period;
}
//
// Check Order Mode ...
if (info.mode == NULL)
{
//
// Set Market Execution as Default ...
info.mode = X_ORDER_MODE_MARKET;
}
//
// Calculate Entry Price ...
if (info.entry <= 0)
{
//
info.entry = GetEntry(
info.symbol,
info.type);
}
//
// R2R ...
if (info.r2r <= 0)
{
//
// Set Default Risk to Reward Ratio to 1 ...
info.r2r = 1;
}
//
// Set Risk Amount Factor ...
if (info.riskAmount <= 0)
{
//
info.riskAmount = providerDescriptor.riskAmount;
}
//
// Calculate TP and SL ...
double mPoint = GetPoints(info.symbol);
//
// Normalize SL Price ...
if (info.sl > 0)
{
info.sl = NormalizePrice(info.sl, info.symbol);
}
//
// Retrieve Symbol Point Value ...
double pointValue = xEAAccount.GetPointValue(info.symbol);
//
// Calculate Risk ...
double riskPrice = MathAbs(info.entry - info.sl);
riskPrice = NormalizePrice(riskPrice, info.symbol);
//
double riskPoints = PriceToPoint(riskPrice);
riskPoints = NormalizeDouble(riskPoints, 0);
//
// Calculating Reward based On Ratio ...
double rewardPoints = riskPoints * info.r2r;
double rewardPrice = PointToPrice(rewardPoints);
rewardPrice = NormalizePrice(rewardPrice, info.symbol);
//
// TODO: Remove This ...
// rewardPrice = PipsToPrice(
// info.symbol,
// 15
// );
//
// Calculate TP Price ...
double tpValue = isLong
? info.entry + rewardPrice
: info.entry - rewardPrice;
//
// Calculate SL Price ...
double slValue = isLong
? info.entry - riskPrice
: info.entry + riskPrice;
//
// Balance Amount which we risks on each Provider's Trade ...
double amount = availableBalance * info.riskAmount;
//
// Calculating Trade Volume based on risk Points and Amount ...
double volume = xEAAccount.CalculateVolume(
info.symbol,
amount,
riskPoints);
volume = NormalizeVolume(volume, info.symbol);
//
// Set Caculated TP, SL and Volume ...
info.tp = tpValue;
info.sl = slValue;
info.volume = 0.01; // volume;
//
string comment = "";
int signalProvidersCount = ArraySize(info.providers);
if (signalProvidersCount > 0)
{
//
string prvs = "";
for (int i = 0; i < signalProvidersCount; i++)
{
//
string p = info.providers[i];
//
if (StringLen(prvs) > 0)
{
prvs += ",";
}
//
prvs += p;
}
//
comment = "PRV(" + prvs + ")";
}
//
bool isPositionOpen = false;
//
// Open Signal Position ...
if (isLong)
{
//
isPositionOpen = xEATrade.Buy(
info.symbol,
info.period,
info.volume,
info.entry,
info.sl,
info.tp,
comment);
}
else
{
//
isPositionOpen = xEATrade.Sell(
info.symbol,
info.period,
info.volume,
info.entry,
info.sl,
info.tp,
comment);
}
//
if (isPositionOpen)
{
//
// Retrieve Position Ticket ...
ulong ticket = xEATrade.GetLastOpenPositionTicket();
if (ticket == 0)
{
return;
}
//
// Draw Signal ...
ReDrawSignal(ticket, info);
//
// Alert Position ...
LogMessage("Position: " + (string)ticket + " was Open ...");
}
}
//
// Do Guard Actions ...
void Guard()
{
//
// Close Max In Drawdown Position ...
HandleMaxDrawdown();
//
// Trailing Stops ...
HandleTrailing();
//
// Close All Open Positions in Pyramid ...
HandleHedging();
//
// Handle Support Signal Opening ...
HandleSupport();
}
//
// it is a way to Protect Open Signal ...
void HandleTrailing()
{
//
if (xEATrailStopsInPoint <= 0)
{
return;
}
//
XPosition inProfitPositions[];
xEATrade.GetInProfitPositions(inProfitPositions);
int inProfitPositionsCount = ArraySize(inProfitPositions);
if (inProfitPositionsCount <= 0)
{
return;
}
//
for (int i = 0; i < inProfitPositionsCount; i++)
{
//
XPosition iPosition = inProfitPositions[i];
//
bool isLong = IsLong(iPosition.type);
//
// Retrieve Exit Price ...
double exitPrice = GetExit(
iPosition.symbol,
iPosition.type);
//
double entryPrice = GetEntry(
iPosition.symbol,
iPosition.type);
//
// Calculate Price Distance ...
double distancePrice = iPosition.sl == 0
? MathAbs(iPosition.entry - exitPrice)
: MathAbs(iPosition.sl - exitPrice);
double distancePoint = PriceToPoint(
iPosition.symbol,
distancePrice);
//
if (distancePoint >= xEATrailStopsInPoint)
{
//
double trailStepPrice = PointToPrice(
iPosition.symbol,
xEATrailStopsInPoint);
//
double tp =
isLong
? iPosition.tp + trailStepPrice
: iPosition.tp - trailStepPrice;
double sl =
iPosition.sl == 0
? isLong
? entryPrice - trailStepPrice
: entryPrice + trailStepPrice
: isLong
? iPosition.sl + trailStepPrice
: iPosition.sl - trailStepPrice;
//
bool isModified = xEATrade.Modify(
iPosition.ticket,
sl,
tp);
if (isModified)
{
//
// Convert Position to Signal ...
//
XSignalInfo signal = ToSignalInfo(iPosition);
// ReDrawSignal(iPosition.ticket, signal);
//
// Alert Trailing ...
LogMessage("Position: " + (string)iPosition.ticket + ", was Trailed ...");
}
}
}
}
//
// Hedging Close Positions ...
void HandleHedging()
{
//
if (xEAMinProfitForHedging <= 0)
{
return;
}
//
int positionsCount = xEATrade.OpenPositionsCount();
if (positionsCount <= 1)
{
return;
}
//
double profit = xEATrade.GetPositionsProfit();
//
if (profit < xEAMinProfitForHedging)
{
return;
}
//
string comment = "Hedging Pyramid ...";
//
xEATrade.CloseAllPositions(comment);
}
//
// Support Positions ...
void HandleSupport()
{
//
if (xEAMaxDrawdownForSupportPosition <= 0)
{
return;
}
//
int positionsCount = xEATrade.OpenPositionsCount();
if (positionsCount <= 0)
{
return;
}
//
XPosition inDrawdownPositions[];
xEATrade.GetInDrawdownPositions(inDrawdownPositions);
int inDrawdownPositionsCount = ArraySize(inDrawdownPositions);
if (inDrawdownPositionsCount <= 0)
{
return;
}
//
for (int i = 0; i < inDrawdownPositionsCount; i++)
{
//
XPosition iPosition = inDrawdownPositions[i];
//
if (MathAbs(iPosition.profit) >= xEAMaxDrawdownForSupportPosition)
{
//
// Here we have to Open Support Indirectional Position ...
OpenSupportPosition(iPosition);
}
}
}
//
// Close Max In Drawdown Position ...
void HandleMaxDrawdown()
{
//
if (xEAMaxDrawdownForClosePosition <= 0)
{
return;
}
//
int positionsCount = xEATrade.OpenPositionsCount();
if (positionsCount <= 0)
{
return;
}
//
XPosition inDrawdownPositions[];
xEATrade.GetInDrawdownPositions(inDrawdownPositions);
int inDrawdownPositionsCount = ArraySize(inDrawdownPositions);
if (inDrawdownPositionsCount <= 0)
{
return;
}
//
for (int i = 0; i < inDrawdownPositionsCount; i++)
{
//
XPosition iPosition = inDrawdownPositions[i];
//
if (MathAbs(iPosition.profit) >= xEAMaxDrawdownForClosePosition)
{
//
// Here we have to Force Close Position ...
string comment = "Close On Guard ...";
bool isClosed = xEATrade.Close(
iPosition.ticket,
comment);
if (isClosed)
{
LogMessage("Position: " + (string)iPosition.ticket + " was Closed On Guard ...");
}
}
}
}
//
// Draw Signal ...
void ReDrawSignal(const ulong ticket, XSignalInfo &signal)
{
//
return;
//
bool isLong = IsLong(signal.type);
//
string prefix = (string)ticket + "_" + ToString(signal.period);
//
RemoveDraws(prefix);
//
// Retrieve Time ...
datetime time = iTime(
signal.symbol,
signal.period,
0);
//
// Retrieve 3 Time ...
datetime time3 = iTime(
signal.symbol,
signal.period,
3);
//
color posColor = isLong
? clrAqua
: clrMagenta;
color tpColor = clrAqua;
color slColor = clrMagenta;
color entryColor = clrGold;
//
ENUM_LINE_STYLE vLineStyle = STYLE_DOT;
ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID;
ENUM_LINE_STYLE slLineStyle = STYLE_SOLID;
ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID;
//
long chartID = ChartID();
//
// Vertical Line ...
string vlName = prefix + "_" + (string)time;
//
DrawVerticalLine(
chartID,
vlName,
0,
time,
posColor,
vLineStyle);
//
// TP ...
double profit = (MathAbs(signal.tp - signal.entry)) * signal.volume;
string tpName = prefix + "_TP_" + (string)profit;
//
DrawTrendLine(
chartID,
tpName,
0,
time3,
signal.tp,
time,
signal.tp,
tpColor,
tpLineStyle);
//
// SL ...
double lost = (MathAbs(signal.sl - signal.entry)) * signal.volume;
string slName = prefix + "_SL_" + (string)lost;
//
DrawTrendLine(
chartID,
slName,
0,
time3,
signal.sl,
time,
signal.sl,
slColor,
slLineStyle);
//
// ENTRY ...
string entryName = prefix + "_ENTRY_" + (string)lost;
//
DrawTrendLine(
chartID,
entryName,
0,
time3,
signal.entry,
time,
signal.entry,
entryColor,
entryLineStyle);
}
//
// Convert Position to Signal ...
XSignalInfo ToSignalInfo(
XPosition &position)
{
//
XSignalInfo 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;
}
//
string ToString(ENUM_X_SIGNAL_PROVIDERS provider)
{
//
return EnumToString(provider);
}
//
ENUM_X_SIGNAL_PROVIDERS ToProvider(string provider)
{
//
ENUM_X_SIGNAL_PROVIDERS result;
//
if (ToString(XICHI) == provider)
{
result = XICHI;
}
else
{
result = NONE;
}
//
return result;
}
//
// Extract Position Provider ...
ENUM_X_SIGNAL_PROVIDERS ExtractProviderFromComment(string comment)
{
//
ENUM_X_SIGNAL_PROVIDERS result = NONE;
//
if (StringLen(comment) <= 0)
{
return result;
}
//
string providerStr = ExtractString(
comment,
mProviderPrefix + "(",
")");
if (StringLen(providerStr) <= 0)
{
return result;
}
//
result = ToProvider(providerStr);
//
return result;
}
//
// Retrieve Specific Type of Providers Positions ...
void GetSpecificProviderPositions(
XPosition &result[], // Holds Result
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period, // Trading Period
ENUM_X_SIGNAL_PROVIDERS provider // Position Provider
)
{
//
Clear(result);
//
if (StringLen(symbol) == 0 || provider == NONE)
{
return;
}
//
int positionsCount = xEATrade.OpenPositionsCount();
if (positionsCount <= 0)
{
return;
}
//
XPosition symbolPeriodPositions[];
xEATrade.GetPositions(
symbolPeriodPositions,
symbol,
period);
int symbolPeriodPositionsCount = ArraySize(symbolPeriodPositions);
if (symbolPeriodPositionsCount <= 0)
{
return;
}
//
for (int i = 0; i < symbolPeriodPositionsCount; i++)
{
//
XPosition iPosition = symbolPeriodPositions[i];
//
ENUM_X_SIGNAL_PROVIDERS iProvider = ExtractProviderFromComment(iPosition.comment);
if (iProvider == NONE || iProvider != provider)
{
continue;
}
//
Add(
iPosition,
result);
}
}
//
// Find Reversal Position Type ...
ENUM_POSITION_TYPE GetSupportPositionType(ENUM_POSITION_TYPE type)
{
//
ENUM_POSITION_TYPE result = POSITION_TYPE_BUY;
//
if (type == POSITION_TYPE_BUY)
{
result = POSITION_TYPE_SELL;
}
else
{
result = POSITION_TYPE_BUY;
}
//
return result;
}
//
// Check a Position Has Supportable or not ...
bool IsSupportablePosition(XPosition &position)
{
//
bool result = false;
//
if (StringLen(position.comment) <= 0)
{
return result;
}
//
int supStrPos = StringFind(
position.comment,
mSupportPrefix + "(");
//
result = supStrPos < 0;
//
return result;
}
//
// Check a Position has Support Position or not ...
bool HasSupportPosition(XPosition &position)
{
//
bool result = false;
//
int positionsCount = xEATrade.OpenPositionsCount();
//
if (positionsCount <= 0 ||
position.ticket == 0 ||
StringLen(position.comment) <= 0)
{
return result;
}
//
string supCommentStr = mSupportPrefix + "(" + (string)position.ticket + ")";
//
XPosition positions[];
xEATrade.GetPositions(positions);
//
for (int i = 0; i < positionsCount; i++)
{
//
XPosition iPosition = positions[i];
//
int supCommentPos = StringFind(
iPosition.comment,
supCommentStr);
//
result = supCommentPos >= 0;
if (result)
{
break;
}
}
//
return result;
}
//
// Open a Support Position based on Exists ...
void OpenSupportPosition(XPosition &position)
{
//
bool isSupportable = IsSupportablePosition(position);
if (!isSupportable)
{
return;
}
//
bool hasSupport = HasSupportPosition(position);
if (hasSupport)
{
return;
}
//
ENUM_POSITION_TYPE type = GetSupportPositionType(position.type);
double entry = GetEntry(
position.symbol,
type);
//
bool isLong = IsLong(type);
//
double tpPrice = PipsToPrice(
position.symbol,
10);
double slPrice = PipsToPrice(
position.symbol,
5);
//
double tp = 0;
// isLong
// ? entry + tpPrice
// : entry - tpPrice;
//
double sl = 0;
// isLong
// ? entry - slPrice
// : entry + slPrice;
//
string comment = mSupportPrefix + "(" + (string)position.ticket + ")";
//
bool isPositionOpen = false;
//
// Open Signal Position ...
if (isLong)
{
//
isPositionOpen = xEATrade.Buy(
position.symbol,
position.period,
position.volume,
entry,
sl,
tp,
comment);
}
else
{
//
isPositionOpen = xEATrade.Sell(
position.symbol,
position.period,
position.volume,
entry,
sl,
tp,
comment);
}
//
if (isPositionOpen)
{
//
LogMessage("Open Support Psition for: " + position.comment);
}
}
//
// END Functions ...
//