Files
xMQL5/MQLTestWorkspace/Libraries/x-saherelm.xtrade.lib.mq5
T
2024-05-17 04:54:01 +03:30

3019 lines
58 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Seriallize Library
// ---------------------------------------
// Name: XTradeLib
// Description: All models related to Trade ...
//
//
// 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
//
// Imports ...
#include <Trade/Trade.mqh>
#include "../Libraries/x-saherelm.common.lib.mq5"
#include "../Classes/x-saherelm.xdata-collector.mq5"
//
// Definitions ...
//
// a List of Used Tokens ...
//
// Common ...
string XIDToken = "ID";
string XModeToken = "MD";
string XTypeToken = "TY";
string XPeriodToken = "PR";
string XProviderToken = "PRV";
//
string XTPToken = "TP";
string XSLToken = "SL";
string XTimeToken = "TM";
string XEntryToken = "EN";
string XVolumeToken = "VL";
string XSymbolToken = "SMBL";
//
string XSupportToken = "SP";
string XEQMSupportToken = "EQM";
//
// Available Order Modes ...
enum ENUM_X_ORDER_MODES
{
X_ORDER_MODE_NOTHING, // Nothing
X_ORDER_MODE_MARKET, // Market Order
X_ORDER_MODE_STOP, // Pending Stop Order
X_ORDER_MODE_LIMIT, // Pending Limit Order
X_ORDER_MODE_STOP_LIMIT, // Pending Stop Limit Order
};
//
// Select Positions Type ...
enum ENUM_X_POSITION_SELECT_METHODS
{
X_POSITION_SELECT_NONE, // None
X_POSITION_SELECT_MAX, // Max
X_POSITION_SELECT_MIN, // Min
X_POSITION_SELECT_BOTH, // Min and Max
X_POSITION_SELECT_ALL, // All
};
//
// Signal Execution Result ...
// note that some of them must be handles in
// EA's ...
enum ENUM_X_SIGNAL_EXECUTION_RESULT
{
//
X_SIGNAL_EXECUTION_UNKNOWN, // Unknown
X_SIGNAL_EXECUTION_SUCCEED, // Succed
X_SIGNAL_EXECUTION_FAILED_NO_EQUITY, // No Equity for Trade
X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR, // Price Error
X_SIGNAL_EXECUTION_FAILED_MAX_REACHED, // Max Allowed Positions Reached
X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS, // Invalid Params
};
//
// Structs ...
//
// Model a Signal ...
struct XSignal
{
//
// Props ...
//
ulong positionId; // if Executed this filled ...
double entry; // Exntry or Execution Price ...
double volume; // Position Volume ...
//
datetime time; // Issue Time ...
//
double tps[]; // a Collection of TP(s) ...
double sls[]; // a Collection of SL(s) ...
//
string symbol; // Trading Symbol ...
string provider; // Signaller ...
string comment; // Comment ...
//
ENUM_TIMEFRAMES period; // Trading TimeFrame ...
ENUM_POSITION_TYPE type; // Long (Buy) or Short (Sell) ...
ENUM_X_ORDER_MODES mode; // Execution Mode ...
//
XSignal supports[]; // a Collecion of Support Signals ...
XOHCLSupRes supportResistances; // Support and Resistances ...
//
// Constructor ...
XSignal()
{
Clean();
}
//
bool Prepare(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
ENUM_POSITION_TYPE mType, // Long (Buy) or Short (Sell)
ENUM_X_ORDER_MODES mMode, // Execution Mode
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
bool result = false;
//
result =
//
IsValid(mMode) &&
IsValid(mSymbol) &&
IsValid(mPeriod) &&
NotEmpty(mEntry) &&
NotEmpty(mVolume) &&
IsValid(mProvider)
//
;
if (!result)
{
return result;
}
//
type = mType;
mode = mMode;
symbol = mSymbol;
period = mPeriod;
provider = mProvider;
//
// Normalization Values ...
sl = NormalizePrice(sl, mSymbol);
tp = NormalizePrice(tp, mSymbol);
mEntry = NormalizePrice(mEntry, mSymbol);
mVolume = NormalizeVolume(mVolume, mSymbol);
//
entry = mEntry;
volume = mVolume;
//
Add(
sl,
sls
//
);
//
Add(
tp,
tps
//
);
//
time = TimeCurrent();
//
result = IsValid();
//
return result;
}
//
bool PrepareLong(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
ENUM_X_ORDER_MODES mMode, // Execution Mode
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_BUY,
mMode,
mEntry,
mVolume,
sl,
tp
//
);
}
//
bool PrepareShort(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
ENUM_X_ORDER_MODES mMode, // Execution Mode
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_SELL,
mMode,
mEntry,
mVolume,
sl,
tp
//
);
}
//
// Market Mode ...
//
bool PrepareMarketLong(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_BUY,
X_ORDER_MODE_MARKET,
mEntry,
mVolume,
sl,
tp
//
);
}
//
bool PrepareMarketShort(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_SELL,
X_ORDER_MODE_MARKET,
mEntry,
mVolume,
sl,
tp
//
);
}
//
// Stop Mode ...
//
bool PrepareStopLong(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_BUY,
X_ORDER_MODE_STOP,
mEntry,
mVolume,
sl,
tp
//
);
}
//
bool PrepareStopShort(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_SELL,
X_ORDER_MODE_STOP,
mEntry,
mVolume,
sl,
tp
//
);
}
//
// Limit Mode ...
//
bool PrepareLimitLong(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_BUY,
X_ORDER_MODE_LIMIT,
mEntry,
mVolume,
sl,
tp
//
);
}
//
bool PrepareLimitShort(
string mSymbol, // Trading Symbol
string mProvider, // Signal Provider
ENUM_TIMEFRAMES mPeriod, // Trading TimeFrame
double mEntry, // Entry Price
double mVolume, // Volume
double sl = 0, // Stop Loss
double tp = 0 // Take Profit
)
{
//
return Prepare(
mSymbol,
mProvider,
mPeriod,
POSITION_TYPE_SELL,
X_ORDER_MODE_LIMIT,
mEntry,
mVolume,
sl,
tp
//
);
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
entry = 0;
volume = 0;
positionId = 0;
//
time = NULL;
type = NULL;
mode = NULL;
symbol = NULL;
period = NULL;
comment = NULL;
provider = NULL;
//
Clean(tps);
Clean(sls);
Clean(supports);
supportResistances.Clean();
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(period) &&
IsValid(symbol) &&
NotEmpty(volume) &&
NotEmpty(entry) &&
(ArraySize(tps) > 0 ||
ArraySize(sls) > 0)
//
;
//
return result;
}
//
// Check Signal Executed or not ...
bool IsExecuted()
{
//
bool result = false;
//
result =
//
IsValid() &&
NotEmpty(positionId)
//
;
//
return result;
}
//
// Generate Comment for Signal ...
string GenerateComment()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
if (IsValid(provider))
{
//
// Generate Provider Tag ...
result += GenerateProviderTag(provider);
}
//
if (IsValid(period))
{
//
// Generate Period Tag ...
result += GeneratePeriodTag(period);
}
//
return result;
}
//
// Check this instance is Same os Given instance or not ...
bool IsSameAs(
const XSignal &value // instance for Compare
)
{
//
bool result = false;
//
result =
//
type == value.type &&
mode == value.mode &&
entry == value.entry &&
volume == value.volume &&
symbol == value.symbol &&
provider == value.provider &&
positionId == value.positionId &&
ArraySize(sls) == ArraySize(value.sls) &&
ArraySize(tps) == ArraySize(value.tps)
//
;
//
return result;
}
//
// Find index in a Collection ...
int FindIndex(
const XSignal &values[] // Collection to Find
)
{
//
return FindIndex(
this,
values
//
);
}
//
// Check Items Passed Specific Filters or not ...
bool IsFiltersPassed(
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
ENUM_POSITION_TYPE mType = NULL, // Long (Buy), Short (Sell)
ENUM_X_ORDER_MODES mMode = NULL // Execution Mode
)
{
//
bool result = false;
//
result =
//
// Symbol Filter ...
IsSymbolFilterPassed(
mSymbol,
this
//
)
//
&&
//
// Provider Filter ...
IsProviderFilterPassed(
mProvider,
this
//
)
//
&&
//
// Period Filter ...
IsPeriodFilterPassed(
mPeriod,
this
//
)
//
&&
//
// Type Filter ...
IsTypeFilterPassed(
mType,
this
//
)
//
&&
//
// Mode Filter ...
IsModeFilterPassed(
mMode,
this
//
)
//
;
//
return result;
}
//
string GetToken()
{
//
string mType = GetTypeName(this);
//
string result = mType;
//
string parts[];
int partsCount = SplitContent(
parts,
result,
" "
//
);
if (partsCount <= 0)
{
//
result = mType;
return result;
}
//
bool hasLastPart = GetLastItem(
result,
parts
//
);
if (!hasLastPart)
{
//
result = mType;
return result;
}
//
return result;
}
//
// To String Representation ...
string ToString()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
// For Modeling a Signal we Only Used:
// - Period;
// - Provider;
// - Type;
// - Mode;
// - Symbol;
// - PositionID;
// - Entry;
// - Volume;
// - TPS;
// - SLS;
// - Issue Time;
//
int iPeriodInt = (int)period;
//
string periodStr = Surround(XPeriodToken, iPeriodInt);
string providerStr = Surround(XProviderToken, provider);
string typeStr = Surround(XTypeToken, type);
string modeStr = Surround(XModeToken, mode);
string SymbolStr = Surround(XSymbolToken, symbol);
string positionIdStr = Surround(XIDToken, positionId);
string entryStr = Surround(XEntryToken, entry);
string volumeStr = Surround(XVolumeToken, volume);
string timeStr = Surround(XTimeToken, time);
//
// TP ...
string tpsContentStr = ToString(tps);
string tpsStr = Surround(XTPToken, tpsContentStr);
//
// SL ...
string slsContentStr = ToString(sls);
string slsStr = Surround(XSLToken, slsContentStr);
//
result =
//
GetToken() +
"[" +
//
periodStr +
providerStr +
typeStr +
modeStr +
SymbolStr +
positionIdStr +
entryStr +
volumeStr +
tpsStr +
slsStr +
timeStr +
//
"]"
//
;
//
return result;
}
//
// Parse String Model and Fill Available
// Items ...
bool Parse(string value)
{
//
bool result = false;
//
Clean();
//
if (!IsValid(value))
{
return false;
}
//
// For Modeling a Signal we Only Used:
// - Period;
// - Provider;
// - Type;
// - Mode;
// - Symbol;
// - PositionID;
// - Entry;
// - Volume;
// - TPS;
// - SLS;
// - Issue Time;
//
entry = ParseDoubleSurrounded(value, XEntryToken);
volume = ParseDoubleSurrounded(value, XVolumeToken);
positionId = ParseLongSurrounded(value, XIDToken);
//
time = ParseTimeSurrounded(value, XTimeToken);
symbol = ParseStringSurrounded(value, XSymbolToken);
provider = ParseStringSurrounded(value, XProviderToken);
type = ((ENUM_POSITION_TYPE)ParseIntSurrounded(value, XTypeToken));
mode = ((ENUM_X_ORDER_MODES)ParseIntSurrounded(value, XModeToken));
period = ((ENUM_TIMEFRAMES)ParseIntSurrounded(value, XPeriodToken));
//
// TPS ...
ParseDoubleArraySurrounded(
tps,
value,
XTPToken
//
);
//
// SLS ...
ParseDoubleArraySurrounded(
sls,
value,
XSLToken
//
);
//
// Validate ...
result = IsValid();
;
//
return result;
}
};
//
// Model an Open Position ...
struct XPosition
{
//
// Props ...
//
// Magic Number ...
ulong magic;
//
// Ticket ID ...
ulong ticket;
//
// Tradinng Symbol ...
string symbol;
//
// Trading Period ...
ENUM_TIMEFRAMES period;
//
// Position Type ...
ENUM_POSITION_TYPE type;
//
// Take Profit ...
double tp;
//
// Stop Loss ...
double sl;
//
// Position Current Profit ...
double profit;
//
// Position Open Price ...
double entry;
//
// Current Symbol Price ...
double price;
//
// Position Swap ...
double swap;
//
// Position Commission ...
double commission;
//
// Volume ...
double volume;
//
// Position Open Time ...
datetime openAt;
//
// Sifnal Provider ...
string provider;
//
// Position Comment ...
string comment;
//
// Constructor ...
XPosition()
{
Clean();
}
//
// Initializers ...
bool ByIndex(int index)
{
//
bool result = false;
//
static CPositionInfo mPositionInfo;
//
result = mPositionInfo.SelectByIndex(index);
if (!result)
{
return result;
}
//
ulong mTicket = mPositionInfo.Ticket();
//
result = ByTicket(mTicket);
//
return result;
}
bool ByTicket(ulong mTicket)
{
//
bool result = false;
//
static CPositionInfo mPositionInfo;
//
result = mPositionInfo.SelectByTicket(mTicket);
if (!result)
{
return result;
}
//
swap = mPositionInfo.Swap();
magic = mPositionInfo.Magic();
openAt = mPositionInfo.Time();
sl = mPositionInfo.StopLoss();
ticket = mPositionInfo.Ticket();
symbol = mPositionInfo.Symbol();
tp = mPositionInfo.TakeProfit();
profit = mPositionInfo.Profit();
volume = mPositionInfo.Volume();
comment = mPositionInfo.Comment();
entry = mPositionInfo.PriceOpen();
type = mPositionInfo.PositionType();
price = mPositionInfo.PriceCurrent();
commission = mPositionInfo.Commission();
//
period = ExtractPeriod(comment);
provider = ExtractProvider(comment);
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
magic = 0;
ticket = 0;
tp = 0;
sl = 0;
swap = 0;
entry = 0;
price = 0;
profit = 0;
volume = 0;
openAt = 0;
commission = 0;
//
type = NULL;
period = NULL;
//
symbol = NULL;
comment = NULL;
provider = NULL;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
NotEmpty(ticket)
//
;
//
return result;
}
//
// Calculate Age ...
int GetAge(
ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period
)
{
return GetAge(this, mPeriod);
}
//
// Check this instance is Same os Given instance or not ...
bool IsSameAs(
const XPosition &value // instance for Compare
)
{
//
bool result = false;
//
result =
//
type == value.type &&
magic == value.magic &&
entry == value.entry &&
ticket == value.ticket &&
volume == value.volume &&
symbol == value.symbol &&
provider == value.provider
//
;
//
return result;
}
//
// Find index in a Collection ...
int FindIndex(
const XPosition &values[] // Collection to Find
)
{
//
return FindIndex(
this,
values
//
);
}
//
// Check Items Passed Specific Filters or not ...
bool IsFiltersPassed(
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
ENUM_POSITION_TYPE mType = NULL, // Long (Buy), Short (Sell)
ulong mMagic = NULL, // Magic Number
bool mFilterByMagic = true // Get Only Self Open Positions
)
{
//
bool result = false;
//
result =
//
// Magic Filter ...
IsMagicFilterPassed(
mMagic,
mFilterByMagic,
this
//
)
//
&&
//
// Symbol Filter ...
IsSymbolFilterPassed(
mSymbol,
this
//
)
//
&&
//
// Provider Filter ...
IsProviderFilterPassed(
mProvider,
this
//
)
//
&&
//
// Period Filter ...
IsPeriodFilterPassed(
mPeriod,
this
//
)
//
&&
//
// Type Filter ...
IsTypeFilterPassed(
mType,
this
//
)
//
;
//
return result;
}
};
//
// Model an Order ...
struct XOrder
{
//
// Time of order placement ...
datetime setupAt;
//
// Time of order expiration ...
datetime expiredAt;
//
// Time of order execution or cancellation ...
datetime executedAt;
//
// Order type ...
ENUM_ORDER_TYPE type;
//
// Order state ...
ENUM_ORDER_STATE state;
//
// Type of execution by remainder ...
ENUM_ORDER_TYPE_FILLING filling;
//
// Order lifetime ...
ENUM_ORDER_TYPE_TIME lifetime;
//
// Order ticket ...
ulong ticket;
//
// Magic Number ...
long magic;
//
// Position id, that is placed on order,
// when it is executed. Each executed order invokes a
// deal, that opens new or changes existing
// position. Id of that position is placed on
// executed order in this moment.
long positionId;
//
// Initial volume on order placement ...
double initialVolume;
//
// Unfilled volume ...
double currentVolume;
//
// Price, specified in the order ...
double openPrice;
//
// Current price by order symbol ...
double currentPrice;
//
// Price of placing Limit order when StopLimit order is triggered ...
double stopLimitPrice;
//
// Take Profit level ...
double tp;
//
// Stop Loss level ...
double sl;
//
// Trading Symbol ...
string symbol;
//
// Signal Provider ...
string provider;
//
// Order Comment ...
string comment;
//
ENUM_TIMEFRAMES period;
//
// Constructor ...
XOrder()
{
Clean();
}
//
// Initializers ...
bool ByIndex(
int index // Fill By Index ...
)
{
//
bool result = false;
//
int ordersCount = OrdersTotal();
if (ordersCount <= 0)
{
return result;
}
//
static COrderInfo mOrderInfo;
//
result = mOrderInfo.SelectByIndex(index);
if (!result)
{
return result;
}
//
// Reading Order Info ...
magic = mOrderInfo.Magic();
sl = mOrderInfo.StopLoss();
tp = mOrderInfo.TakeProfit();
ticket = mOrderInfo.Ticket();
openPrice = mOrderInfo.PriceOpen();
positionId = mOrderInfo.PositionId();
currentPrice = mOrderInfo.PriceCurrent();
initialVolume = mOrderInfo.VolumeInitial();
currentVolume = mOrderInfo.VolumeCurrent();
stopLimitPrice = mOrderInfo.PriceStopLimit();
//
symbol = mOrderInfo.Symbol();
comment = mOrderInfo.Comment();
//
state = mOrderInfo.State();
type = mOrderInfo.OrderType();
lifetime = mOrderInfo.TypeTime();
filling = mOrderInfo.TypeFilling();
//
setupAt = mOrderInfo.TimeSetup();
executedAt = mOrderInfo.TimeDone();
expiredAt = mOrderInfo.TimeExpiration();
//
period = ExtractPeriod(comment);
provider = ExtractProvider(comment);
//
result = IsValid();
//
return result;
}
//
// Retrieve Specific History Order ...
bool HistoryByIndex(
int index // Fill By Index ...
)
{
//
bool result = false;
//
int ordersCount = HistoryOrdersTotal();
if (ordersCount <= 0)
{
return result;
}
//
static CHistoryOrderInfo mOrderInfo;
//
result = mOrderInfo.SelectByIndex(index);
if (!result)
{
return result;
}
//
// Reading Order Info ...
magic = mOrderInfo.Magic();
sl = mOrderInfo.StopLoss();
tp = mOrderInfo.TakeProfit();
ticket = mOrderInfo.Ticket();
openPrice = mOrderInfo.PriceOpen();
positionId = mOrderInfo.PositionId();
currentPrice = mOrderInfo.PriceCurrent();
initialVolume = mOrderInfo.VolumeInitial();
currentVolume = mOrderInfo.VolumeCurrent();
stopLimitPrice = mOrderInfo.PriceStopLimit();
//
symbol = mOrderInfo.Symbol();
comment = mOrderInfo.Comment();
//
state = mOrderInfo.State();
type = mOrderInfo.OrderType();
lifetime = mOrderInfo.TypeTime();
filling = mOrderInfo.TypeFilling();
//
setupAt = mOrderInfo.TimeSetup();
executedAt = mOrderInfo.TimeDone();
expiredAt = mOrderInfo.TimeExpiration();
//
period = ExtractPeriod(comment);
provider = ExtractProvider(comment);
//
result = IsValid();
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
tp = 0;
sl = 0;
magic = 0;
ticket = 0;
positionId = 0;
openPrice = 0;
currentPrice = 0;
initialVolume = 0;
currentVolume = 0;
stopLimitPrice = 0;
//
setupAt = NULL;
expiredAt = NULL;
executedAt = NULL;
//
symbol = NULL;
comment = NULL;
provider = NULL;
//
type = NULL;
state = NULL;
period = NULL;
filling = NULL;
lifetime = NULL;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
NotEmpty(ticket) &&
NotEmpty(positionId)
//
;
//
return result;
}
//
// Calculate Age ...
int GetAge(
ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period
)
{
return GetAge(this, mPeriod);
}
//
// Check this instance is Same os Given instance or not ...
bool IsSameAs(
const XOrder &value // instance for Compare
)
{
//
bool result = false;
//
result =
//
type == value.type &&
state == value.state &&
magic == value.magic &&
ticket == value.ticket &&
symbol == value.symbol &&
provider == value.provider &&
positionId == value.positionId
//
;
//
return result;
}
//
// Find index in a Collection ...
int FindIndex(
const XOrder &values[] // Collection to Find
)
{
//
return FindIndex(
this,
values
//
);
}
//
// Check Items Passed Specific Filters or not ...
bool IsFiltersPassed(
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
ENUM_ORDER_TYPE mType = NULL, // Long (Buy), Short (Sell)
ENUM_ORDER_STATE mState = NULL, // Order State
ulong mMagic = NULL, // Magic Number
bool mFilterByMagic = true // Get Only Self Open Positions
)
{
//
bool result = false;
//
result =
//
// Magic Filter ...
IsMagicFilterPassed(
mMagic,
mFilterByMagic,
this
//
)
//
&&
//
// Symbol Filter ...
IsSymbolFilterPassed(
mSymbol,
this
//
)
//
&&
//
// Provider Filter ...
IsProviderFilterPassed(
mProvider,
this
//
)
//
&&
//
// Period Filter ...
IsPeriodFilterPassed(
mPeriod,
this
//
)
//
&&
//
// Type Filter ...
IsTypeFilterPassed(
mType,
this
//
)
//
&&
//
// State Filter ...
IsStateFilterPassed(
mState,
this
//
)
//
;
//
return result;
}
};
//
// Model a Deal ...
struct XDeal
{
//
// the ID of the Expert Advisor, that executed the deal ...
ulong magic;
//
// the ID of position, in which the deal was involved ...
ulong positionId;
//
// Ticket ...
ulong ticket;
//
// the name of the deal symbol ...
string symbol;
//
// order by which the deal is executed ...
ulong order;
//
// the time of deal execution ...
datetime time;
//
// Deal price ...
double price;
//
// the financial result of the deal (in deposit currency) ...
double profit;
//
// the amount of swap when position is closed ...
double swap;
//
// the amount of commission of the deal ...
double commission;
//
// the volume of deal ...
double volume;
//
// the deal comment ...
string comment;
//
string provider;
//
ENUM_TIMEFRAMES period;
//
// the deal type ...
// ------------------------------------------------------------------
// DEAL_TYPE_BUY => Buy ...
// DEAL_TYPE_SELL => Sell ...
// DEAL_TYPE_BUY_CANCELED => Canceled buy deal ...
// There can be a situation when a previously executed buy deal is canceled. In this case,
// the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED,
// and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ...
//
// DEAL_TYPE_SELL_CANCELED => Canceled sell deal ...
// There can be a situation when a previously executed sell deal is canceled. In this case,
// the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED,
// and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation
//
// DEAL_TYPE_BALANCE => Balance ...
// DEAL_TYPE_CREDIT => Credit ...
// DEAL_TYPE_CHARGE => Additional charge ...
// DEAL_TYPE_CORRECTION => Correction ...
// DEAL_TAX => Tax charges ...
// DEAL_TYPE_BONUS => Bonus ...
// DEAL_TYPE_INTEREST => Interest rate ...
// DEAL_DIVIDEND => Dividend operations...
// DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ...
// DEAL_TYPE_COMMISSION => Additional commission ...
// DEAL_TYPE_COMMISSION_DAILY => Daily commission ...
// DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ...
// DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ...
// DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission
ENUM_DEAL_TYPE type;
//
// the deal direction ...
// ----------------------------------
// DEAL_ENTRY_IN => Entry in ...
// DEAL_ENTRY_OUT => Entry out ...
// DEAL_ENTRY_INOUT => Reverse ...
// DEAL_ENTRY_OUT_BY => Close a position by an opposite one ...
ENUM_DEAL_ENTRY entry;
//
// deal reson ...
// ---------------------
// DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ...
// DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ...
// DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ...
// DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ...
// DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ...
// DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ...
// DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ...
// DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ...
// DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ...
// DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ...
ENUM_DEAL_REASON reason;
//
// Constructor ...
XDeal()
{
Clean();
}
//
// Initializers ...
bool ByIndex(
int index // Deal Index
)
{
//
bool result = false;
//
int dealsCount = HistoryDealsTotal();
result = dealsCount > 0;
if (!result)
{
return result;
}
//
static CDealInfo mDealInfo;
//
result = mDealInfo.SelectByIndex(index);
if (!result)
{
//
return result;
}
//
// Reading Order Info ...
swap = mDealInfo.Swap();
magic = mDealInfo.Magic();
order = mDealInfo.Order();
ticket = mDealInfo.Ticket();
time = mDealInfo.Time();
price = mDealInfo.Price();
symbol = mDealInfo.Symbol();
profit = mDealInfo.Profit();
volume = mDealInfo.Volume();
comment = mDealInfo.Comment();
positionId = mDealInfo.PositionId();
entry = mDealInfo.Entry();
commission = mDealInfo.Commission();
type = mDealInfo.DealType();
reason = (ENUM_DEAL_REASON)HistoryDealGetInteger(
ticket,
DEAL_REASON);
//
period = ExtractPeriod(comment);
provider = ExtractProvider(comment);
//
result = IsValid();
//
return result;
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
magic = 0;
positionId = 0;
ticket = 0;
order = 0;
time = 0;
price = 0;
profit = 0;
swap = 0;
commission = 0;
volume = 0;
//
symbol = NULL;
comment = NULL;
provider = NULL;
//
type = NULL;
entry = NULL;
period = NULL;
reason = NULL;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(symbol) &&
NotEmpty(ticket) &&
NotEmpty(positionId)
//
;
//
return result;
}
//
// Calculate Age ...
int GetAge(
ENUM_TIMEFRAMES mPeriod // Calculate Age based on this period
)
{
return GetAge(this, mPeriod);
}
//
// Check this instance is Same os Given instance or not ...
bool IsSameAs(
const XDeal &value // instance for Compare
)
{
//
bool result = false;
//
result =
//
type == value.type &&
magic == value.magic &&
entry == value.entry &&
reason == value.reason &&
ticket == value.ticket &&
volume == value.volume &&
symbol == value.symbol &&
provider == value.provider &&
positionId == value.positionId
//
;
//
return result;
}
//
// Find index in a Collection ...
int FindIndex(
const XDeal &values[] // Collection to Find
)
{
//
return FindIndex(
this,
values
//
);
}
//
// Check Items Passed Specific Filters or not ...
bool IsFiltersPassed(
string mSymbol = NULL, // Trading Symbol
string mProvider = NULL, // Signal Provider
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Timeframe
ENUM_DEAL_TYPE mType = NULL, // Deal Type
ENUM_DEAL_ENTRY mEntry = NULL, // Deal Entry
ENUM_DEAL_REASON mReason = NULL, // Deal Reason
ulong mMagic = NULL, // Magic Number
bool mFilterByMagic = true // Get Only Self Open Positions
)
{
//
bool result = false;
//
result =
//
// Magic Filter ...
IsMagicFilterPassed(
mMagic,
mFilterByMagic,
this
//
)
//
&&
//
// Symbol Filter ...
IsSymbolFilterPassed(
mSymbol,
this
//
)
//
&&
//
// Provider Filter ...
IsProviderFilterPassed(
mProvider,
this
//
)
//
&&
//
// Period Filter ...
IsPeriodFilterPassed(
mPeriod,
this
//
)
//
&&
//
// Type Filter ...
IsTypeFilterPassed(
mType,
this
//
)
//
&&
//
// Entry Filter ...
IsEntryFilterPassed(
mEntry,
this
//
)
//
&&
//
// Reason Filter ...
IsReasonFilterPassed(
mReason,
this
//
)
//
;
//
return result;
}
};
//
// Model OnTrade Event Handler Result on XCTrade Class ...
struct XOnTradeHandlerState
{
//
bool hasNewDeal;
int newDeals;
//
bool hasNewOrder;
int newOrders;
//
bool hasNewPosition;
int newPositions;
//
bool hasNewHistoryOrder;
int newHistoryOrders;
//
// Constructor ...
XOnTradeHandlerState()
{
Clean();
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
hasNewDeal = false;
hasNewOrder = false;
hasNewPosition = false;
hasNewHistoryOrder = false;
//
newDeals = 0;
newOrders = 0;
newPositions = 0;
newHistoryOrders = 0;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
(
//
hasNewDeal
? newDeals > 0
: true
//
)
//
&&
//
(
//
hasNewOrder
? newOrders > 0
: true
//
)
//
&&
//
(
//
hasNewPosition
? newPositions > 0
: true
//
)
//
&&
//
(
//
hasNewHistoryOrder
? newHistoryOrders > 0
: true
//
)
//
;
//
return result;
}
};
//
// Model a Position with all of it's Supports ...
struct XPositionPack
{
//
ulong ticket; // Main Position's Ticket
//
XPosition position; // Main Position (if Exists)
//
int supportOrdersCount; // Supported Orders (Untriggered)
int supportPositionsCount; // Supported Positions
//
XOrder supportOrders[]; // Supported Orders (Untriggered)
XPosition supportPositions[]; // Supported Positions
//
// Constructor ...
XPositionPack()
{
Clean();
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
ticket = 0;
//
position.Clean();
//
supportOrdersCount = 0;
supportPositionsCount = 0;
//
Clean(supportOrders);
Clean(supportPositions);
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
NotEmpty(ticket) &&
(
//
supportOrdersCount > 0
? ArraySize(supportOrders) == supportOrdersCount
: true
//
)
//
&&
//
(
//
supportPositionsCount > 0
? ArraySize(supportPositions) == supportPositionsCount
: true
//
)
//
;
//
return result;
}
};
//
// TypeDefs ...
//
typedef void (*TOnDealsChanged)(int count);
//
typedef void (*TOnOrdersChanged)(int count);
//
typedef void (*TOnPositionsChanged)(int count);
//
typedef void (*TOnStopLoss)(const XDeal &deal);
typedef void (*TOnTakeProfit)(const XDeal &deal);
//
typedef void (*TOnTradeStateChanged)(const XOnTradeHandlerState &state);
//
// Classes ...
//
// Create a Signal Specfic Data Collector ...
class XSCSignalCollector
{
//
// Public ...
public:
//
// Props ...
//
// Constructor ...
void XSCSignalCollector()
{
//
XSCDataCollector<XSignal> mBase;
mBase.Clear();
}
//
// Deconstructor ...
//
// Tools ...
//
// Inheritanced Functions ...
//
// Cleaning Store ...
void Clear()
{
//
XSCDataCollector<XSignal> mBase;
//
mBase.Clear();
}
//
// Collect All Store ...
int Collect(XSignal &result[])
{
//
int mResult = 0;
//
XSCDataCollector<XSignal> mBase;
//
mResult = mBase.Collect(result);
//
return mResult;
}
//
// Add Item To Store ...
bool Add(XSignal &item)
{
//
bool result = false;
//
XSCDataCollector<XSignal> mBase;
//
result = mBase.Add(item);
//
return result;
}
//
// Add Item(s) To Store ...
int Add(XSignal &items[])
{
//
int result = 0;
//
XSCDataCollector<XSignal> mBase;
//
result = mBase.Add(items);
//
return result;
}
//
// Remove an Item from Store ...
bool Remove(XSignal &item)
{
//
bool result = false;
//
XSCDataCollector<XSignal> mBase;
//
result = mBase.Remove(item);
//
return result;
}
//
// Custom Functions ...
//
int CollectSignals(
XSignal &result[], // Hold Result
string symbol = NULL, // Trading Symbol
string provider = NULL, // Signal Provider
ENUM_TIMEFRAMES period = NULL, // Trading Timeframe
ENUM_POSITION_TYPE type = NULL, // Long (Buy), Short (Sell)
ENUM_X_ORDER_MODES mode = NULL // Execution Mode
)
{
//
int mResult = 0;
// //
// XSignal signals[];
// int signalsCount = Collect(signals);
// if (signalsCount <= 0)
// {
// return mResult;
// }
// //
// mResult = ArraySize(result);
// //
// // Now we Have to Apply Filters ...
// for (int i = 0; i < signalsCount; i++)
// {
// //
// XSignal iSignal = signals[i];
// // //
// // bool isFiltersPassed =
// // iSignal.IsFilteresPassed(
// // symbol,
// // provider,
// // period,
// // type,
// // mode
// // //
// // );
// // if (!isFiltersPassed)
// // {
// // continue;
// // }
// // //
// // AddRef(
// // iPosition,
// // result
// // //
// // );
// }
//
return mResult;
}
//
// Protected ...
protected:
//
// Tools ...
//
// Private ...
private:
//
// Props ...
//
// Tools ...
};
//
// Tools ...
//
bool IsValid(ENUM_X_ORDER_MODES value)
{
return value != X_ORDER_MODE_NOTHING;
}
//
// Ages ...
//
// Retrieve a Position Age ...
int GetAge(
XPosition &position, // Selected Position ...
ENUM_TIMEFRAMES period = NULL // Dest Time Frame ...
)
{
//
int result = -1;
//
if (period == NULL)
{
period = _Period;
}
//
result = iBarShift(
position.symbol,
period,
position.openAt);
//
return result;
}
//
// Retrieve an Order Age ...
int GetAge(
XOrder &order, // Selected Order ...
ENUM_TIMEFRAMES period = NULL // Dest Time Frame ...
)
{
//
int result = -1;
//
if (period == NULL)
{
period = _Period;
}
//
result = iBarShift(
order.symbol,
period,
order.setupAt);
//
return result;
}
//
// Retrieve a Deal Age ...
int GetAge(
XDeal &deal, // Selected Deal ...
ENUM_TIMEFRAMES period = NULL // Dest Time Frame ...
)
{
//
int result = -1;
//
if (period == NULL)
{
period = _Period;
}
//
result = iBarShift(
deal.symbol,
period,
deal.time);
//
return result;
}
//
// Get Oldest Deal ...
int GetOldest(
XDeal &item, // Hold Result ...
XDeal &items[] // Source Array ...
)
{
//
int result = -1;
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
int tmpAge = 0;
XDeal tmpItem;
for (int i = 0; i < itemsCount; i++)
{
//
XDeal iItem = items[i];
//
int iAge = GetAge(iItem);
if (iAge > 0 &&
(tmpAge == 0 || tmpAge < iAge))
{
//
tmpAge = iAge;
tmpItem = iItem;
}
}
//
if (tmpAge > 0)
{
//
result = tmpAge;
item = tmpItem;
}
//
return result;
}
//
// Get Youngest Deal ...
int GetYoungest(
XDeal &item, // Hold Result ...
XDeal &items[] // Source Array ...
)
{
//
int result = -1;
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
int tmpAge = 0;
XDeal tmpItem;
for (int i = 0; i < itemsCount; i++)
{
//
XDeal iItem = items[i];
//
int iAge = GetAge(iItem);
if (iAge > 0 &&
(tmpAge == 0 || tmpAge > iAge))
{
//
tmpAge = iAge;
tmpItem = iItem;
}
}
//
if (tmpAge > 0)
{
//
result = tmpAge;
item = tmpItem;
}
//
return result;
}
//
// Get Oldest Order ...
int GetOldest(
XOrder &item, // Hold Result ...
XOrder &items[] // Source Array ...
)
{
//
int result = -1;
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
int tmpAge = 0;
XOrder tmpItem;
for (int i = 0; i < itemsCount; i++)
{
//
XOrder iItem = items[i];
//
int iAge = GetAge(iItem);
if (iAge > 0 &&
(tmpAge == 0 || tmpAge < iAge))
{
//
tmpAge = iAge;
tmpItem = iItem;
}
}
//
if (tmpAge > 0)
{
//
result = tmpAge;
item = tmpItem;
}
//
return result;
}
//
// Get Youngest Order ...
int GetYoungest(
XOrder &item, // Hold Result ...
XOrder &items[] // Source Array ...
)
{
//
int result = -1;
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
int tmpAge = 0;
XOrder tmpItem;
for (int i = 0; i < itemsCount; i++)
{
//
XOrder iItem = items[i];
//
int iAge = GetAge(iItem);
if (iAge > 0 &&
(tmpAge == 0 || tmpAge > iAge))
{
//
tmpAge = iAge;
tmpItem = iItem;
}
}
//
if (tmpAge > 0)
{
//
result = tmpAge;
item = tmpItem;
}
//
return result;
}
//
// Get Oldes Position ...
int GetOldest(
XPosition &item, // Hold Result ...
XPosition &items[] // Source Array ...
)
{
//
int result = -1;
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
int tmpAge = 0;
XPosition tmpItem;
for (int i = 0; i < itemsCount; i++)
{
//
XPosition iItem = items[i];
//
int iAge = GetAge(iItem);
if (iAge > 0 &&
(tmpAge == 0 || tmpAge < iAge))
{
//
tmpAge = iAge;
tmpItem = iItem;
}
}
//
if (tmpAge > 0)
{
//
result = tmpAge;
item = tmpItem;
}
//
return result;
}
//
// Get Youngest Position ...
int GetYoungest(
XPosition &item, // Hold Result ...
XPosition &items[] // Source Array ...
)
{
//
int result = -1;
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
int tmpAge = 0;
XPosition tmpItem;
for (int i = 0; i < itemsCount; i++)
{
//
XPosition iItem = items[i];
//
int iAge = GetAge(iItem);
if (iAge > 0 &&
(tmpAge == 0 || tmpAge > iAge))
{
//
tmpAge = iAge;
tmpItem = iItem;
}
}
//
if (tmpAge > 0)
{
//
result = tmpAge;
item = tmpItem;
}
//
return result;
}
//
// Check Filters ...
//
// Magic Filter ...
template <typename T>
bool IsMagicFilterPassed(
ulong magic,
bool filterByMagic,
T &item
//
)
{
//
return !filterByMagic
? true
: !NotEmpty(magic)
? false
: magic == item.magic;
}
//
// Symbol Filter ...
template <typename T>
bool IsSymbolFilterPassed(
string symbol,
T &item
//
)
{
//
return !IsValid(symbol)
? true
: symbol == item.symbol;
}
//
// Provider Filter ...
template <typename T>
bool IsProviderFilterPassed(
string provider,
T &item
//
)
{
//
return !IsValid(provider)
? true
: provider == item.provider;
}
//
// Period Filter ...
template <typename T>
bool IsPeriodFilterPassed(
ENUM_TIMEFRAMES period,
T &item
//
)
{
//
return !IsValid(period)
? true
: period == item.period;
}
//
// Type Filter ...
template <typename T>
bool IsTypeFilterPassed(
ENUM_POSITION_TYPE type,
T &item
//
)
{
//
return type == NULL
? true
: type == item.type;
}
template <typename T>
bool IsTypeFilterPassed(
ENUM_ORDER_TYPE type,
T &item
//
)
{
//
return type == NULL
? true
: type == item.type;
}
template <typename T>
bool IsTypeFilterPassed(
ENUM_DEAL_TYPE type,
T &item
//
)
{
//
return type == NULL
? true
: type == item.type;
}
//
// Mode Filter ...
template <typename T>
bool IsModeFilterPassed(
ENUM_X_ORDER_MODES mode,
T &item
//
)
{
//
return mode == NULL
? true
: mode == item.mode;
}
//
// Entry Filter ...
template <typename T>
bool IsEntryFilterPassed(
ENUM_DEAL_ENTRY entry,
T &item
//
)
{
//
return entry == NULL
? true
: entry == item.entry;
}
//
// Reason Filter ...
template <typename T>
bool IsReasonFilterPassed(
ENUM_DEAL_REASON reason,
T &item
//
)
{
//
return reason == NULL
? true
: reason == item.reason;
}
//
// State Filter ...
template <typename T>
bool IsStateFilterPassed(
ENUM_ORDER_STATE state,
T &item
//
)
{
//
return state == NULL
? true
: state == item.state;
}
//
//
// Find Specific Item Index inside a Collection ...
template <typename T>
int FindIndex(
T &item, // Item to Find
const T &items[] // Items for Search
)
{
//
int result = -1;
//
// Check Item Validation ...
if (!item.IsValid())
{
return result;
}
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
for (int i = 0; i < itemsCount; i++)
{
//
T iItem = items[i];
//
// Validate Item ...
if (!iItem.IsValid())
{
continue;
}
//
bool isSame = item.IsSameAs(iItem);
if (isSame && result <= -1)
{
//
result = i;
break;
}
}
//
return result;
}
//
// Tagging ...
//
// Generate Specified Tag for Using in Comments ...
string GeneratePeriodTag(ENUM_TIMEFRAMES period)
{
//
string strPeriod = ToString(period);
return Surround(
XPeriodToken,
strPeriod
//
);
}
//
// Extract Period from a Tagged string ...
ENUM_TIMEFRAMES ExtractPeriod(string value)
{
//
ENUM_TIMEFRAMES result = NULL;
//
string pStr = ParseStringSurrounded(
value,
XPeriodToken
//
);
if (!IsValid(pStr))
{
return result;
}
//
result = ToPeriod(pStr);
//
return result;
}
// Generate Specified Tag for Using in Comments ...
string GenerateProviderTag(string provider)
{
//
return Surround(
XProviderToken,
provider
//
);
}
//
// Extract Provider from a Tagged string ...
string ExtractProvider(string value)
{
//
return ParseStringSurrounded(
value,
XProviderToken
//
);
}
//
// Generate Support Comment Tag ...
string GenerateSupportTag(ulong ticket)
{
//
return Surround(
XSupportToken,
ticket
//
);
}
//
// Extract Support Positions from a Tagged string ...
ulong ExtractSupportedTicket(string value)
{
//
return ParseLongSurrounded(
value,
XSupportToken
//
);
}
//
// Generate EQM Support Comment Tag ...
string GenerateEQMSupportTag(ulong ticket)
{
//
return Surround(
XEQMSupportToken,
ticket
//
);
}
//
// Extract EQM Support Positions from a Tagged string ...
ulong ExtractEQMSupportedTicket(string value)
{
//
return ParseLongSurrounded(
value,
XEQMSupportToken
//
);
}
//