1326 lines
30 KiB
Plaintext
1326 lines
30 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Seriallize Library
|
|
// ---------------------------------------
|
|
// Name: XSeriallizer
|
|
// Description: provides Seriallizing EA abilities ...
|
|
//
|
|
//
|
|
// 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
|
|
|
|
//
|
|
#include "../Libraries/x-saherelm.models.lib.mq5"
|
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
|
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
|
#include "../Classes/x-saherelm.x121.provider.class.mq5"
|
|
|
|
//
|
|
string XProviderToken = "PRV";
|
|
string XSupportToken = "SP";
|
|
string XSLTrailToken = "SLT";
|
|
string XPeriodToken = "PR";
|
|
|
|
//
|
|
string XConfigToken = "XPV";
|
|
string XItemSeparator = "|";
|
|
string XItemContentSeparator = ",";
|
|
|
|
//
|
|
string XFirstGenToken = "0";
|
|
|
|
//
|
|
// PERIOD ...
|
|
|
|
//
|
|
// Detect a Comment has period or not ...
|
|
bool HasPeriod(string comment)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (StringLen(comment) == 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int tokenPos = StringFind(
|
|
comment,
|
|
XPeriodToken);
|
|
result = tokenPos >= 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Period String ...
|
|
string ExtractPeriodString(string comment)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
bool hasPeriod = HasPeriod(comment);
|
|
if (!hasPeriod)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ExtractString(
|
|
comment,
|
|
XPeriodToken + "(",
|
|
")");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Time Frame From Comment ...
|
|
ENUM_TIMEFRAMES ExtractPeriod(string comment)
|
|
{
|
|
//
|
|
ENUM_TIMEFRAMES result = NULL;
|
|
|
|
//
|
|
if (StringLen(comment) <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string periodStr = ExtractPeriodString(comment);
|
|
if (StringLen(periodStr) <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ToPeriod(periodStr);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// PROVIDER ...
|
|
|
|
//
|
|
// Extract a Provider name if exists from a Comment ...
|
|
string ExtractProvider(string comment)
|
|
{
|
|
//
|
|
string result = "";
|
|
if (StringLen(comment) <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ExtractString(
|
|
comment,
|
|
XProviderToken + "(",
|
|
")");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Generate Provider String for Using in Positions Comment ...
|
|
// NOTE: if there is more than One Provider, it takes first
|
|
// provider as main and the others used to increase volume ...
|
|
string GenerateProvidersString(XSignal &signal)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
int providersCount = ArraySize(signal.providers);
|
|
if (providersCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = XProviderToken + "(" + signal.providers[0] + ")";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// SLTRAIL ...
|
|
|
|
//
|
|
string GenerateSLTrailComment(int level)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
if (level <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = XSLTrailToken + "(" + ToString(level) + ")";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int ExtractSLTrailLevel(string comment)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (StringLen(comment) == 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string levelStr = ExtractString(
|
|
comment,
|
|
XSLTrailToken + "(",
|
|
")");
|
|
if (StringLen(levelStr) == 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (int)levelStr;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string PrepareSLTrailComment(
|
|
const string comment // Original Position Comment ...
|
|
)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
if (StringLen(comment) == 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int level = 0;
|
|
result = comment;
|
|
|
|
//
|
|
// Check Comment Contains SL Trailing or not ...
|
|
int lastTrailLevel = ExtractSLTrailLevel(comment);
|
|
if (lastTrailLevel <= 0)
|
|
{
|
|
level++;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
level = lastTrailLevel + 1;
|
|
string lastLevelStr = GenerateSLTrailComment(lastTrailLevel);
|
|
StringReplace(
|
|
result,
|
|
lastLevelStr,
|
|
"");
|
|
}
|
|
|
|
//
|
|
// Generate level Comment ...
|
|
string levelStr = GenerateSLTrailComment(level);
|
|
result += levelStr;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// SUPPORT ...
|
|
|
|
//
|
|
// Generate Specific Position's Support Comment
|
|
// index is number of Supports ...
|
|
string GenerateSupportSignalComment(
|
|
ulong ticket, // Position/Order Ticket
|
|
int index // Support Index ...
|
|
)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
result = XSupportToken + "(" + (string)ticket + "," + ToString(index) + ")";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Support Parameters String from specified Comment ...
|
|
string ExtractSupportParam(string comment)
|
|
{
|
|
//
|
|
string result = "";
|
|
if (StringLen(comment) <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ExtractString(
|
|
comment,
|
|
XSupportToken + "(",
|
|
")");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Support Info as String array for Specific Comment ...
|
|
bool ExtractSupportParams(
|
|
string comment, // Specified Comment ...
|
|
string ¶ms[] // Hold Result ...
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string supParam = ExtractSupportParam(comment);
|
|
if (StringLen(supParam) == 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
SplitContent(
|
|
params,
|
|
supParam);
|
|
int paramsCount = ArraySize(params);
|
|
|
|
//
|
|
result = paramsCount == 2;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Support Parent Ticket ...
|
|
ulong ExtractParentTicket(string comment)
|
|
{
|
|
//
|
|
ulong result = 0;
|
|
|
|
//
|
|
string params[];
|
|
bool isSupport = ExtractSupportParams(
|
|
comment,
|
|
params);
|
|
if (!isSupport)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (ulong)params[0];
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Support Index ...
|
|
int ExtractSupportIndex(string comment)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
string params[];
|
|
bool isSupport = ExtractSupportParams(
|
|
comment,
|
|
params);
|
|
if (!isSupport)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (int)params[1];
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XCONFIG X121Provider Struct ...
|
|
|
|
//
|
|
// Extract Signallers from User Input ...
|
|
int ExtractSignallers(
|
|
string &result[], // Hold Result
|
|
const string source // Source Content
|
|
)
|
|
{
|
|
//
|
|
int mResult = 0;
|
|
|
|
//
|
|
Clean(result);
|
|
|
|
//
|
|
SplitContent(
|
|
result,
|
|
source);
|
|
|
|
//
|
|
mResult = ArraySize(result);
|
|
|
|
//
|
|
return mResult;
|
|
}
|
|
|
|
//
|
|
// Validate Specified Provider Descriptor Model ...
|
|
bool IsValid(X121SignalProvider &item)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
StringLen(item.symbol) > 0 &&
|
|
item.period != NULL &&
|
|
item.riskAmount > 0
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Compare Source item with Dest item to check their Same or not ...
|
|
bool IsSame(
|
|
X121SignalProvider &source, // Source Item
|
|
X121SignalProvider &dest // Dest Item
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bool isValidDest = IsValid(dest);
|
|
bool isValidSource = IsValid(source);
|
|
if (!isValidDest ||
|
|
!isValidSource)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
source.symbol == dest.symbol &&
|
|
source.period == dest.period &&
|
|
source.riskAmount == dest.riskAmount &&
|
|
source.useRiskAmountAsStaticVolume == dest.useRiskAmountAsStaticVolume
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Specified Provider Exists in a Collection or not ...
|
|
bool Contains(
|
|
X121SignalProvider &item, // Specified Item
|
|
X121SignalProvider &items[] // Given Collection
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int itemsCount = ArraySize(items);
|
|
if (itemsCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < itemsCount; i++)
|
|
{
|
|
//
|
|
X121SignalProvider iProvider = items[i];
|
|
|
|
//
|
|
result = IsSame(item, iProvider);
|
|
if (result)
|
|
{
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Provider Descriptor Parts from given Source Input ...
|
|
int ExtractProviderDescriptorItems(
|
|
string &result[], // Hold Result
|
|
const string source // Source Descriptor
|
|
)
|
|
{
|
|
//
|
|
int mResult = 0;
|
|
|
|
//
|
|
Clean(result);
|
|
|
|
//
|
|
SplitContent(
|
|
result,
|
|
source,
|
|
XItemSeparator);
|
|
|
|
//
|
|
mResult = ArraySize(result);
|
|
|
|
//
|
|
return mResult;
|
|
}
|
|
|
|
//
|
|
// Extract Provider Descriptor Items Content from given Source Input ...
|
|
int ExtractProviderDescriptorItemsContent(
|
|
string &result[], // Hold Result
|
|
const string source // Source Descriptor
|
|
)
|
|
{
|
|
//
|
|
int mResult = 0;
|
|
|
|
//
|
|
Clean(result);
|
|
|
|
//
|
|
SplitContent(
|
|
result,
|
|
source,
|
|
XItemContentSeparator);
|
|
|
|
//
|
|
mResult = ArraySize(result);
|
|
|
|
//
|
|
return mResult;
|
|
}
|
|
|
|
//
|
|
// Validate and add provider to providers if not exists ...
|
|
bool AddProviderDescriptor(
|
|
X121SignalProvider &item,
|
|
X121SignalProvider &items[])
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate and add ...
|
|
result = IsValid(item);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isExists = Contains(
|
|
item,
|
|
items);
|
|
if (isExists)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = true;
|
|
|
|
//
|
|
Add(
|
|
item,
|
|
items);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Provider Descriptors from given Source Input ...
|
|
int ExtractProviderConfigurations(
|
|
X121SignalProvider &result[], // Hold Result
|
|
const string source, // Source String
|
|
const string defaultSignallers, // Default Available Signallers for Each Providers
|
|
const double defaultRiskAmount, // Default Risk Amount per Trade for Each Provider
|
|
const bool useRiskAmountAsStaticVolume = true // Use Provided Risk Amount as Static Volume
|
|
)
|
|
{
|
|
//
|
|
int mResult = 0;
|
|
|
|
//
|
|
Clean(result);
|
|
|
|
//
|
|
// if there is no Pairs ...
|
|
// Check as One Model ...
|
|
string descriptors[];
|
|
mResult = ExtractStrings(
|
|
descriptors,
|
|
source,
|
|
XConfigToken + "(",
|
|
")");
|
|
|
|
//
|
|
// Retrieve Signallers ...
|
|
string defaultSignallersArr[];
|
|
ExtractSignallers(
|
|
defaultSignallersArr,
|
|
defaultSignallers);
|
|
|
|
//
|
|
if (mResult == 0)
|
|
{
|
|
//
|
|
// Here we Check given source String Length ...
|
|
// if it is bigger than zero we assuem it is one line descriptor ...
|
|
if (StringLen(source) > 0)
|
|
{
|
|
//
|
|
// One Model ...
|
|
Add(
|
|
source,
|
|
descriptors);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Each Provider Must Contains at least two things :
|
|
// - Asset;
|
|
int descriptorsCount = ArraySize(descriptors);
|
|
if (descriptorsCount > 0)
|
|
{
|
|
//
|
|
// Loop through descriptors to parse models ...
|
|
for (int i = 0; i < descriptorsCount; i++)
|
|
{
|
|
//
|
|
string iDescriptor = descriptors[i];
|
|
|
|
//
|
|
X121SignalProvider iProviderDescriptor;
|
|
iProviderDescriptor.symbol = "";
|
|
iProviderDescriptor.period = NULL;
|
|
iProviderDescriptor.riskAmount = 0;
|
|
Clean(iProviderDescriptor.providers);
|
|
|
|
//
|
|
string iParts[];
|
|
int iPartsCount = ExtractProviderDescriptorItems(
|
|
iParts,
|
|
iDescriptor);
|
|
|
|
//
|
|
// Check Parts Count ...
|
|
// Now we have to Decide How to Config Signal Providers using Parts ...
|
|
|
|
//
|
|
// asset => default;
|
|
// period => default;
|
|
// risk amount => default;
|
|
// signallers => default;
|
|
// use as static volume => default;
|
|
if (iPartsCount == 0)
|
|
{
|
|
//
|
|
// Here we Instance as Current Config Descriptor ...
|
|
iProviderDescriptor.symbol = _Symbol;
|
|
iProviderDescriptor.period = _Period;
|
|
iProviderDescriptor.riskAmount = defaultRiskAmount;
|
|
iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
// Add Default Signallers ...
|
|
Copy(
|
|
defaultSignallersArr,
|
|
iProviderDescriptor.providers);
|
|
|
|
//
|
|
AddProviderDescriptor(
|
|
iProviderDescriptor,
|
|
result);
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// asset => provided;
|
|
// period => default;
|
|
// risk amount => default;
|
|
// signallers => default;
|
|
// use as static volume => default;
|
|
if (iPartsCount == 1)
|
|
{
|
|
|
|
//
|
|
iProviderDescriptor.period = _Period;
|
|
iProviderDescriptor.riskAmount = defaultRiskAmount;
|
|
iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
// Add Default Signallers ...
|
|
Copy(
|
|
defaultSignallersArr,
|
|
iProviderDescriptor.providers);
|
|
|
|
//
|
|
// Extract Provided Assets ...
|
|
string symbols[];
|
|
int symbolsCount = ExtractProviderDescriptorItemsContent(
|
|
symbols,
|
|
iParts[0]);
|
|
for (int j = 0; j < symbolsCount; j++)
|
|
{
|
|
//
|
|
string jSymbol = symbols[j];
|
|
|
|
//
|
|
iProviderDescriptor.symbol = jSymbol;
|
|
|
|
//
|
|
AddProviderDescriptor(
|
|
iProviderDescriptor,
|
|
result);
|
|
}
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// asset => provided;
|
|
// period => provided;
|
|
// risk amount => default;
|
|
// signallers => default;
|
|
// use as static volume => default;
|
|
if (iPartsCount == 2)
|
|
{
|
|
//
|
|
iProviderDescriptor.riskAmount = defaultRiskAmount;
|
|
iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
// Add Default Signallers ...
|
|
Copy(
|
|
defaultSignallersArr,
|
|
iProviderDescriptor.providers);
|
|
|
|
//
|
|
// Extract Provided Assets ...
|
|
string symbols[];
|
|
int symbolsCount = ExtractProviderDescriptorItemsContent(
|
|
symbols,
|
|
iParts[0]);
|
|
for (int j = 0; j < symbolsCount; j++)
|
|
{
|
|
//
|
|
string jSymbol = symbols[j];
|
|
|
|
//
|
|
iProviderDescriptor.symbol = jSymbol;
|
|
|
|
//
|
|
// Extract Periods ...
|
|
string periods[];
|
|
int periodsCount = ExtractProviderDescriptorItemsContent(
|
|
periods,
|
|
iParts[1]);
|
|
for (int k = 0; k < periodsCount; k++)
|
|
{
|
|
//
|
|
string kPeriodStr = periods[k];
|
|
ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr);
|
|
|
|
//
|
|
iProviderDescriptor.period = kPeriod;
|
|
|
|
//
|
|
AddProviderDescriptor(
|
|
iProviderDescriptor,
|
|
result);
|
|
}
|
|
}
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// asset => provided;
|
|
// period => provided;
|
|
// risk amount => provided;
|
|
// signallers => default;
|
|
// use as static volume => default;
|
|
if (iPartsCount == 3)
|
|
{
|
|
//
|
|
iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
// Add Default Signallers ...
|
|
Copy(
|
|
defaultSignallersArr,
|
|
iProviderDescriptor.providers);
|
|
|
|
//
|
|
// Extract Provided Assets ...
|
|
string symbols[];
|
|
int symbolsCount = ExtractProviderDescriptorItemsContent(
|
|
symbols,
|
|
iParts[0]);
|
|
|
|
//
|
|
string riskAmounts[];
|
|
int riskAmountsCount = ExtractProviderDescriptorItemsContent(
|
|
riskAmounts,
|
|
iParts[2]);
|
|
|
|
//
|
|
for (int j = 0; j < symbolsCount; j++)
|
|
{
|
|
//
|
|
string jSymbol = symbols[j];
|
|
|
|
//
|
|
iProviderDescriptor.symbol = jSymbol;
|
|
|
|
//
|
|
// Extract Periods ...
|
|
string periods[];
|
|
int periodsCount = ExtractProviderDescriptorItemsContent(
|
|
periods,
|
|
iParts[1]);
|
|
for (int k = 0; k < periodsCount; k++)
|
|
{
|
|
//
|
|
string kPeriodStr = periods[k];
|
|
ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr);
|
|
|
|
//
|
|
iProviderDescriptor.period = kPeriod;
|
|
|
|
//
|
|
string selectedRiskAmount =
|
|
riskAmountsCount == 0
|
|
? ToString(defaultRiskAmount)
|
|
: riskAmountsCount == periodsCount
|
|
? riskAmounts[k]
|
|
: riskAmounts[0];
|
|
double riskAmount = (double)selectedRiskAmount;
|
|
iProviderDescriptor.riskAmount = riskAmount;
|
|
|
|
//
|
|
AddProviderDescriptor(
|
|
iProviderDescriptor,
|
|
result);
|
|
}
|
|
}
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// asset => provided;
|
|
// period => provided;
|
|
// risk amount => provided;
|
|
// signallers => provided;
|
|
// use as static volume => default;
|
|
if (iPartsCount == 4)
|
|
{
|
|
//
|
|
iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
// Extract Signallers ...
|
|
string signallers[];
|
|
int signallersCount = ExtractSignallers(
|
|
signallers,
|
|
iParts[3]);
|
|
if (signallersCount <= 0)
|
|
{
|
|
//
|
|
Copy(
|
|
defaultSignallersArr,
|
|
signallers);
|
|
}
|
|
|
|
//
|
|
// Set Extracted Signallers in Provider Descriptor ...
|
|
Copy(
|
|
signallers,
|
|
iProviderDescriptor.providers);
|
|
|
|
//
|
|
//
|
|
// Extract Provided Assets ...
|
|
string symbols[];
|
|
int symbolsCount = ExtractProviderDescriptorItemsContent(
|
|
symbols,
|
|
iParts[0]);
|
|
|
|
//
|
|
string riskAmounts[];
|
|
int riskAmountsCount = ExtractProviderDescriptorItemsContent(
|
|
riskAmounts,
|
|
iParts[2]);
|
|
|
|
//
|
|
for (int j = 0; j < symbolsCount; j++)
|
|
{
|
|
//
|
|
string jSymbol = symbols[j];
|
|
|
|
//
|
|
iProviderDescriptor.symbol = jSymbol;
|
|
|
|
//
|
|
// Extract Periods ...
|
|
string periods[];
|
|
int periodsCount = ExtractProviderDescriptorItemsContent(
|
|
periods,
|
|
iParts[1]);
|
|
for (int k = 0; k < periodsCount; k++)
|
|
{
|
|
//
|
|
string kPeriodStr = periods[k];
|
|
ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr);
|
|
|
|
//
|
|
iProviderDescriptor.period = kPeriod;
|
|
|
|
//
|
|
string selectedRiskAmount =
|
|
riskAmountsCount == 0
|
|
? ToString(defaultRiskAmount)
|
|
: riskAmountsCount == periodsCount
|
|
? riskAmounts[k]
|
|
: riskAmounts[0];
|
|
double riskAmount = (double)selectedRiskAmount;
|
|
iProviderDescriptor.riskAmount = riskAmount;
|
|
|
|
//
|
|
AddProviderDescriptor(
|
|
iProviderDescriptor,
|
|
result);
|
|
}
|
|
}
|
|
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// asset => provided;
|
|
// period => provided;
|
|
// risk amount => provided;
|
|
// signallers => provided;
|
|
// use as static volume => provided;
|
|
if (iPartsCount == 5)
|
|
{
|
|
//
|
|
// Extract Signallers ...
|
|
string signallers[];
|
|
int signallersCount = ExtractSignallers(
|
|
signallers,
|
|
iParts[3]);
|
|
if (signallersCount <= 0)
|
|
{
|
|
//
|
|
Copy(
|
|
defaultSignallersArr,
|
|
signallers);
|
|
}
|
|
|
|
//
|
|
// Set Extracted Signallers in Provider Descriptor ...
|
|
Copy(
|
|
signallers,
|
|
iProviderDescriptor.providers);
|
|
|
|
//
|
|
//
|
|
// Extract Provided Assets ...
|
|
string symbols[];
|
|
int symbolsCount = ExtractProviderDescriptorItemsContent(
|
|
symbols,
|
|
iParts[0]);
|
|
|
|
//
|
|
string riskAmounts[];
|
|
int riskAmountsCount = ExtractProviderDescriptorItemsContent(
|
|
riskAmounts,
|
|
iParts[2]);
|
|
|
|
//
|
|
string useRiskAmountAsStaticVolumes[];
|
|
int useRiskAmountAsStaticVolumesCount = ExtractProviderDescriptorItemsContent(
|
|
useRiskAmountAsStaticVolumes,
|
|
iParts[4]);
|
|
|
|
//
|
|
for (int j = 0; j < symbolsCount; j++)
|
|
{
|
|
//
|
|
string jSymbol = symbols[j];
|
|
|
|
//
|
|
iProviderDescriptor.symbol = jSymbol;
|
|
|
|
//
|
|
// Extract Periods ...
|
|
string periods[];
|
|
int periodsCount = ExtractProviderDescriptorItemsContent(
|
|
periods,
|
|
iParts[1]);
|
|
for (int k = 0; k < periodsCount; k++)
|
|
{
|
|
//
|
|
string kPeriodStr = periods[k];
|
|
ENUM_TIMEFRAMES kPeriod = ToPeriod(kPeriodStr);
|
|
|
|
//
|
|
iProviderDescriptor.period = kPeriod;
|
|
|
|
//
|
|
string selectedRiskAmount =
|
|
riskAmountsCount == 0
|
|
? ToString(defaultRiskAmount)
|
|
: riskAmountsCount == periodsCount
|
|
? riskAmounts[k]
|
|
: riskAmounts[0];
|
|
double riskAmount = (double)selectedRiskAmount;
|
|
iProviderDescriptor.riskAmount = riskAmount;
|
|
|
|
//
|
|
string selectedUseRiskAmountAsStaticVolume =
|
|
useRiskAmountAsStaticVolumesCount == 0
|
|
? ToString(useRiskAmountAsStaticVolume)
|
|
: useRiskAmountAsStaticVolumesCount == periodsCount
|
|
? useRiskAmountAsStaticVolumes[k]
|
|
: useRiskAmountAsStaticVolumes[0];
|
|
bool useRiskAmountAsStaticVolume = ToBoolean(selectedUseRiskAmountAsStaticVolume);
|
|
iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
AddProviderDescriptor(
|
|
iProviderDescriptor,
|
|
result);
|
|
}
|
|
}
|
|
|
|
//
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Use All Defaults to Create One Instance ...
|
|
X121SignalProvider iProviderDescriptor;
|
|
iProviderDescriptor.symbol = "";
|
|
iProviderDescriptor.period = NULL;
|
|
iProviderDescriptor.riskAmount = 0;
|
|
Clean(iProviderDescriptor.providers);
|
|
|
|
//
|
|
iProviderDescriptor.symbol = _Symbol;
|
|
iProviderDescriptor.period = _Period;
|
|
iProviderDescriptor.riskAmount = defaultRiskAmount;
|
|
iProviderDescriptor.useRiskAmountAsStaticVolume = useRiskAmountAsStaticVolume;
|
|
|
|
//
|
|
// Add Default Signallers ...
|
|
Copy(
|
|
defaultSignallersArr,
|
|
iProviderDescriptor.providers);
|
|
|
|
//
|
|
AddProviderDescriptor(
|
|
iProviderDescriptor,
|
|
result);
|
|
}
|
|
|
|
//
|
|
mResult = ArraySize(result);
|
|
|
|
//
|
|
return mResult;
|
|
}
|
|
|
|
//
|
|
// START XEQM Support ...
|
|
//
|
|
|
|
//
|
|
string XEQMSupportToken = "XEQM";
|
|
|
|
//
|
|
// Generate String Tag for EQM Support Signals ...
|
|
string GenerateXEQMSupportComment()
|
|
{
|
|
//
|
|
string result = XEQMSupportToken;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check a Comment belongs to a EQM Support or not ...
|
|
bool IsEQMSupport(string comment)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (StringLen(comment) <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int tokenPosition = StringFind(
|
|
comment,
|
|
XEQMSupportToken);
|
|
result = tokenPosition >= 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select EQM Support Orders ...
|
|
int GetEQMSupportOrders(
|
|
XOrder &supports[], // Hold Result ...
|
|
XOrder &orders[], // List of All Orders ...
|
|
ENUM_TIMEFRAMES period = NULL // Specified Period ...
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Cleanup Array ...
|
|
Clean(supports);
|
|
|
|
//
|
|
// Count Orders ...
|
|
int ordersCount = ArraySize(orders);
|
|
if (ordersCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop through Orders ...
|
|
for (int i = 0; i < ordersCount; i++)
|
|
{
|
|
//
|
|
// Select Indexed Order ...
|
|
XOrder iOrder = orders[i];
|
|
|
|
//
|
|
// Check Order is Support or not ...
|
|
bool isSupport = IsEQMSupport(iOrder.comment);
|
|
if (!isSupport)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check Order is not Triggered ...
|
|
if (iOrder.state != ORDER_STATE_PLACED)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check Period ...
|
|
if (period != NULL && iOrder.period != period)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// we now sure this order is EQM Support ...
|
|
Add(
|
|
iOrder,
|
|
supports);
|
|
}
|
|
|
|
//
|
|
// Count Result ...
|
|
result = ArraySize(supports);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Select EQM Support Positions ...
|
|
int GetEQMSupportPositions(
|
|
XPosition &supports[], // Hold Result ...
|
|
XPosition &positions[], // List of All Positions ...
|
|
ENUM_TIMEFRAMES period = NULL // Specified Period ...
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Cleanup Array ...
|
|
Clean(supports);
|
|
|
|
//
|
|
// Count Positions ...
|
|
int positionsCount = ArraySize(positions);
|
|
if (positionsCount <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop through Positions ...
|
|
for (int i = 0; i < positionsCount; i++)
|
|
{
|
|
//
|
|
// Select Indexed Position ...
|
|
XPosition iPosition = positions[i];
|
|
|
|
//
|
|
// Check Position is Support or not ...
|
|
bool isSupport = IsEQMSupport(iPosition.comment);
|
|
if (!isSupport)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check Period ...
|
|
if (period != NULL && iPosition.period != period)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// we now sure this order is EQM Support ...
|
|
Add(
|
|
iPosition,
|
|
supports);
|
|
}
|
|
|
|
//
|
|
// Count Result ...
|
|
result = ArraySize(supports);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// END XEQM Support ...
|
|
//
|
|
|
|
//
|
|
// START FirstGen ...
|
|
//
|
|
|
|
//
|
|
string GenerateFirstGenIdentifier(const string signaller)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
if (StringLen(signaller) <= 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return signaller + XFirstGenToken;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsFirstGenOf(
|
|
const string signaller, // Specified Signaller
|
|
const string comment // Comment
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string id = GenerateFirstGenIdentifier(signaller);
|
|
|
|
//
|
|
int idPos = StringFind(
|
|
comment,
|
|
id
|
|
);
|
|
result = idPos >= 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// END FirstGen ...
|
|
// |