2956 lines
86 KiB
Plaintext
2956 lines
86 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class
|
|
// -------------------------------------------------
|
|
// Name: XCXCATBEAExpert ...
|
|
// Description: XCATB Expert Class ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://saherelm.ir"
|
|
#property version "1.00"
|
|
#property description "SaherElm XCATB Expert Class"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../../Classes/x-saherelm.x-guard.class.mq5"
|
|
#include "../../Classes/x-saherelm.x-trade.class.mq5"
|
|
#include "../../Classes/x-saherelm.x-volume.class.mq5"
|
|
#include "../Classes/xcatbea.signaller.class.mq5"
|
|
#include "../Classes/xcatbea.x-trade.manager.class.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
#define XCATBEA_INPUTS_PREFIX "X121XCATBEA"
|
|
|
|
//
|
|
// Implementation ...
|
|
|
|
//
|
|
class XCXCATBEASignallerInputParser : public XCBase
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XCXCATBEASignallerInputParser(
|
|
XCAlert *_alert //
|
|
)
|
|
{
|
|
//
|
|
alert = _alert;
|
|
|
|
//
|
|
// Instantiate Data Collector ...
|
|
collector = new XCDataCollector();
|
|
|
|
//
|
|
// Generate Path and Attached to Data Collector ...
|
|
// string mPath = alert.GetPrefix();
|
|
collector.Path("");
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXCATBEASignallerInputParser()
|
|
{
|
|
//
|
|
delete collector;
|
|
ZeroMemory(collector);
|
|
}
|
|
|
|
//
|
|
// Tools and Actions ...
|
|
|
|
/**
|
|
* Retrieve Specified Symbol / Period Signaller Inputs ...
|
|
*
|
|
* @param symbol: string, Specified Signaller Symbol ...
|
|
* @param period: ENUM_TIMEFRAMES member, Specified Signaller Period ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
string GetFileName(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period //
|
|
)
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
// Validate Args ...
|
|
if (!IsValid(symbol) ||
|
|
!IsValid(period))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = XCATBEA_INPUTS_PREFIX + "_" + symbol + "_" + ToXString(period);
|
|
result = collector.GetFilePath(result);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Symbol / Period Signaller Inputs File Exists ...
|
|
*
|
|
* @param symbol: string, Specified Signaller Symbol ...
|
|
* @param period: ENUM_TIMEFRAMES member, Specified Signaller Period ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSignallerInputsFileExists(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string fileName = GetFileName(
|
|
symbol,
|
|
period //
|
|
);
|
|
result = IsValid(fileName);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = collector.IsExists(fileName);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Parse Specified Symbol / Period Signaller Inputs file ...
|
|
*
|
|
* @param inputs: XCATBEASignallerInputs instance reference, To Fill Loaded Configs ...
|
|
* @param symbol: string, Specified Signaller Symbol ...
|
|
* @param period: ENUM_TIMEFRAMES member, Specified Signaller Period ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ParseSignallerInputs(
|
|
XCATBEASignallerInputs &inputs,
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Args ...
|
|
result =
|
|
IsValid(symbol) &&
|
|
IsValid(period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
inputs.symbol = symbol;
|
|
inputs.period = period;
|
|
|
|
//
|
|
// Prepare File Name and Check File Exists ...
|
|
string fileName = GetFileName(symbol, period);
|
|
result = collector.IsExists(fileName);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Read Content ...
|
|
string content[];
|
|
result = collector.Read(fileName, content);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Try to Parse Content ...
|
|
result = HasChild(content);
|
|
if (result)
|
|
{
|
|
//
|
|
int count = ArraySize(content);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
string iLine = content[i];
|
|
|
|
//
|
|
Parse(iLine, inputs);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
XCAlert *alert;
|
|
XCDataCollector *collector;
|
|
|
|
/**
|
|
* Parse Condition and Attached to related Properties if Exists ...
|
|
*/
|
|
void Parse(
|
|
string line,
|
|
XCATBEASignallerInputs &inputs //
|
|
)
|
|
{
|
|
//
|
|
string parts[];
|
|
bool has = false;
|
|
int partsCount = 0;
|
|
|
|
//
|
|
// Validations ...
|
|
|
|
//
|
|
// eaForceHasSwing ...
|
|
has = Contains(
|
|
"eaForceHasSwing",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.validations.forceHasSwing = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceOBBarType ...
|
|
has = Contains(
|
|
"eaForceOBBarType",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.validations.forceOBBarType = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceFVGBarType ...
|
|
has = Contains(
|
|
"eaForceFVGBarType",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.validations.forceFVGBarType = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasFLiquidity ...
|
|
has = Contains(
|
|
"eaForceHasFLiquidity",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.validations.forceHasFLiquidity = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasRLiquidity ...
|
|
has = Contains(
|
|
"eaForceHasRLiquidity",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.validations.forceHasRLiquidity = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaValidateGapSequence ...
|
|
has = Contains(
|
|
"eaValidateGapSequence",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.validations.validateGapSequence = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaValidateBlockEdgeBreakout ...
|
|
has = Contains(
|
|
"eaValidateBlockEdgeBreakout",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.validations.validateBlockEdgeBreakout = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Filters ...
|
|
|
|
//
|
|
// eaFilterBasedOnKI ...
|
|
has = Contains(
|
|
"eaFilterBasedOnKI",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnKI = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnPV ...
|
|
has = Contains(
|
|
"eaFilterBasedOnPV",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnPV = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnSar ...
|
|
has = Contains(
|
|
"eaFilterBasedOnSar",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnSar = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceSarSwitched ...
|
|
has = Contains(
|
|
"eaForceSarSwitched",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceSarSwitched = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceSarOnBothSide ...
|
|
has = Contains(
|
|
"eaForceSarOnBothSide",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceSarOnBothSide = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceSarHasBreakout ...
|
|
has = Contains(
|
|
"eaForceSarHasBreakout",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceSarHasBreakout = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceSarHasReversalSide ...
|
|
has = Contains(
|
|
"eaForceSarHasReversalSide",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceSarHasReversalSide = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnRSI ...
|
|
has = Contains(
|
|
"eaFilterBasedOnRSI",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnRSI = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasRSITrending ...
|
|
has = Contains(
|
|
"eaForceHasRSITrending",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasRSITrending = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasRSIVPattern ...
|
|
has = Contains(
|
|
"eaForceHasRSIVPattern",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasRSIVPattern = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasRSICrossing ...
|
|
has = Contains(
|
|
"eaForceHasRSICrossing",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasRSICrossing = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnADX ...
|
|
has = Contains(
|
|
"eaFilterBasedOnADX",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnADX = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasADXTrending ...
|
|
has = Contains(
|
|
"eaForceHasADXTrending",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasADXTrending = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasADXCrossing ...
|
|
has = Contains(
|
|
"eaForceHasADXCrossing",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasADXCrossing = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnATR ...
|
|
has = Contains(
|
|
"eaFilterBasedOnATR",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnATR = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasATRTrending ...
|
|
has = Contains(
|
|
"eaForceHasATRTrending",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasATRTrending = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasATRBreakout ...
|
|
has = Contains(
|
|
"eaForceHasATRBreakout",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasATRBreakout = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnTrend ...
|
|
has = Contains(
|
|
"eaFilterBasedOnTrend",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnTrend = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasTrendDir ...
|
|
has = Contains(
|
|
"eaForceHasTrendDir",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasTrendDir = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasTrendPlace ...
|
|
has = Contains(
|
|
"eaForceHasTrendPlace",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasTrendPlace = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasTrendChange ...
|
|
has = Contains(
|
|
"eaForceHasTrendChange",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasTrendChange = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasTrendTrending ...
|
|
has = Contains(
|
|
"eaForceHasTrendTrending",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasTrendTrending = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasTrendRejection ...
|
|
has = Contains(
|
|
"eaForceHasTrendRejection",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasTrendRejection = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasTrendLineInside ...
|
|
has = Contains(
|
|
"eaForceHasTrendLineInside",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasTrendLineInside = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaForceHasTrendDirOnBothSide ...
|
|
has = Contains(
|
|
"eaForceHasTrendDirOnBothSide",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.forceHasTrendDirOnBothSide = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnDelta ...
|
|
has = Contains(
|
|
"eaFilterBasedOnDelta",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnDelta = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnVolume ...
|
|
has = Contains(
|
|
"eaFilterBasedOnVolume",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnVolume = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnSignalBar ...
|
|
has = Contains(
|
|
"eaFilterBasedOnSignalBar",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnSignalBar = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// eaFilterBasedOnHKSignalBar ...
|
|
has = Contains(
|
|
"eaFilterBasedOnHKSignalBar",
|
|
line,
|
|
false //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Split Content ...
|
|
partsCount = SplitContent(
|
|
parts,
|
|
line,
|
|
":" //
|
|
);
|
|
has = partsCount == 2;
|
|
if (has)
|
|
{
|
|
//
|
|
has = ToBoolean(parts[1]);
|
|
if (has)
|
|
{
|
|
inputs.filters.filterBasedOnHKSignalBar = has;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
class XCXCATBEAExpert : public XCBase
|
|
{
|
|
//
|
|
// public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Common ...
|
|
long eaMagicNumber; // Magic Number
|
|
int eaSlippage; // Slippgae
|
|
string eaLogSuffix; // Log Suffix
|
|
|
|
//
|
|
// Detector ...
|
|
|
|
//
|
|
// Validating ...
|
|
bool eaForceHasSwing; // Force Block to Has Propper Swing
|
|
bool eaForceOBBarType; // Force Order Block to Has InDirectional Bars
|
|
int eaMinRequiredOBBar; // Min Required OB Bar
|
|
bool eaForceFVGBarType; // Force Fair Value Gaps Bars Type
|
|
int eaLiquidityLoopback; // Liquidity Detection Loopback
|
|
double eaMaxAllowedRange; // Max Allowed Order Block Range
|
|
double eaMinAllowedRange; // Min Allowed Order Block Range
|
|
bool eaForceHasFLiquidity; // Force Order Block To Has Reversal Liquidity
|
|
bool eaForceHasRLiquidity; // Force Order Block to Has Following Liquidity
|
|
bool eaValidateGapSequence; // Validate Fair Value Gaps Bar Sequences
|
|
int eaMinAllowedBlockLength; // Min Allowed Block Length
|
|
bool eaValidateBlockEdgeBreakout; // Validate Order Block Edge Breakeout
|
|
|
|
//
|
|
// Filtering ...
|
|
bool eaFilterBasedOnKI; // Filter Based On KI Flats
|
|
bool eaFilterBasedOnPV; // Filter Based On PV
|
|
int eaBosLoopback; // PV Based Filtering BOS Lookup
|
|
bool eaFilterBasedOnSar; // Filter Based On SAR
|
|
bool eaForceSarSwitched; // SAR Switched on Sides for Filtering
|
|
bool eaForceSarOnBothSide; // SAR Check on Both Sides for Filtering
|
|
bool eaForceSarHasBreakout; // SAR Must Breakout
|
|
bool eaForceSarHasReversalSide; // SAR Must Has Reversal Direction
|
|
bool eaFilterBasedOnRSI; // Filter Based On RSI
|
|
bool eaForceHasRSITrending; // RSI Must Has Trending
|
|
bool eaForceHasRSIVPattern; // RSI Must Has Pattern
|
|
bool eaForceHasRSICrossing; // RSI Must Has Crossing Levels
|
|
bool eaFilterBasedOnADX; // Filter Based On ADX
|
|
bool eaForceHasADXTrending; // ADX Must Has Trending
|
|
bool eaForceHasADXCrossing; // ADX Must Has Crossing +DI/-DI
|
|
bool eaFilterBasedOnATR; // Filter Based On ATR
|
|
bool eaForceHasATRTrending; // ATR Must Has Trending
|
|
bool eaForceHasATRBreakout; // ATR Must Has Breakout
|
|
bool eaFilterBasedOnTrend; // Filter Based On Trend
|
|
bool eaForceHasTrendDir; // TREND Must Has Following Direction
|
|
bool eaForceHasTrendPlace; // TREND Place Based Filtering
|
|
bool eaForceHasTrendChange; // TREND Change Filtering
|
|
bool eaForceHasTrendTrending; // TREND Must Has Trending
|
|
bool eaForceHasTrendRejection; // TREND Line Must Rejected
|
|
bool eaForceHasTrendLineInside; // TREND Line has Inside
|
|
bool eaForceHasTrendDirOnBothSide; // TREND Must Has Following Direction in Both Side
|
|
bool eaFilterBasedOnDelta; // Filter Based On Delta
|
|
bool eaFilterBasedOnVolume; // Filter Based On Volume
|
|
bool eaFilterBasedOnSignalBar; // Filter Based on Signal Bar
|
|
bool eaFilterBasedOnHKSignalBar; // Filter Based On HK Signal Bar
|
|
|
|
//
|
|
// Signal ...
|
|
int eaSignalR2R; // Risk Reward Ratio
|
|
double eaSLATRMultiplier; // ATR Multiplier for SL
|
|
bool eaAllowSignallingBasedOnConditions; // Signalling Based on Market Conditions
|
|
bool eaAllowSignallingBasedOnTriggerBlocks; // Signalling Based on Trigger Blocks
|
|
bool eaAllowSignallingBasedOnTriggerBlocksInsideOther; // Signalling Based on Trigger Blocks Seccond inputs
|
|
bool eaSecondsTriggersSLUsingFirstTriggerBlock; // Use First Trigger Block for SL of Seconds Trigger Block Signalss
|
|
bool eaApplyValidateAndFilterOnSelectInsideOthers; // Select Trigger Blocks by Applying Validations and Filterss
|
|
bool eaAllowSignallingConditions1; // Allow Market Conditions Signaller to Using Sar Starter Signals
|
|
bool eaAllowSignallingConditions2; // Allow Market Conditions Signaller to Using Trend Starter Signals
|
|
bool eaAllowSignallingConditions3; // Allow Market Conditions Signaller to Using Delta Starter Signals
|
|
bool eaAllowSignallingConditions4; // Allow Market Conditions Signaller to Using Volume Starter Signals
|
|
bool eaAllowSignallingConditions5; // Allow Market Conditions Signaller to Using Signal Bar Starter Signals
|
|
bool eaAllowSignallingConditions6; // Allow Market Conditions Signaller to Using HK Signal Bar Starter Signals
|
|
|
|
//
|
|
// Volume ...
|
|
ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect; // Volume Applying Type
|
|
double eaStaticVoluem; // Static Volume
|
|
double eaDynamicVolumeStepBalance; // Step of Balance for Increase Volume
|
|
double eaDynamicVolumeStepVolume; // Step of Volume Increasing
|
|
double eaConstantRiskBalance; // Constant Risk Balance per Trade
|
|
double eaConstantPercent; // Constant Percent of Balance Per Trade
|
|
double eaConstantBalance; // Constant Balance for Calculations
|
|
|
|
//
|
|
// Management ...
|
|
string eaSymbols; // Allowed Trading Symbols
|
|
bool eaAllowGuards; // Allow Guards
|
|
bool eaAllowTrade; // Allow Trade on Signals
|
|
bool eaAllowLongs; // Allow Long Trades
|
|
bool eaAllowShorts; // Allow Short Trades
|
|
string eaSessions; // Active Sessions
|
|
ENUM_XCATBEA_TRADE_RESTRICTION_PERIOD eaRestrictionsPeriod; // Restrictions Period
|
|
int eaMaxAllowedTPs; // Max Allowed TP(s) in Restrictions Period
|
|
int eaMaxAllowedSLs; // Max Allowed SL(s) in Restrictions Period
|
|
int eaMaxAllowedTrades; // Max Allowed Trades in Restrictions Period
|
|
int eaMaxAllowedPositions; // Max Allowed Same Time Trades
|
|
double eaMaxAllowedSpread; // Max Allowed Spread For Trade
|
|
double eaMaxAllowedDrawdownFactor; // Max Allowed DrawDown for Trade
|
|
string eaCloseAllOpenTradesAt; // Close All Open Trades per Day At Specified Time
|
|
|
|
//
|
|
// Alert ...
|
|
bool eaEnableAlerts; // Enable Alerts
|
|
bool eaSaveAlerts; // Save Alerts
|
|
bool eaLogAlerts; // Log Alerts
|
|
bool eaMailAlerts; // Mail Alerts
|
|
bool eaPushAlerts; // Push Alerts
|
|
bool eaTerminalAlerts; // Terminal Alerts
|
|
|
|
//
|
|
// Time Report ...
|
|
bool eaReportNewMonths; // Report New Month
|
|
bool eaReportNewWeeks; // Report New Weeks
|
|
bool eaReportNewDays; // Report New Days
|
|
bool eaReportNewHours; // Report New Hours
|
|
bool eaReportTrades; // Report Trades
|
|
bool eaReportSignals; // Report Signals
|
|
bool eaReportProtector; // Report Protector Actions
|
|
bool eaReportRestrictions; // Report Restrictions
|
|
bool eaReportAfterTradesBalance; // Report Balance after a Trade Finished
|
|
|
|
//
|
|
// Collector ...
|
|
bool eaSaveTrades; // Save Trades
|
|
bool eaSaveSignals; // Save Signals
|
|
bool eaSaveWins; // Save Winning Conditions
|
|
bool eaSaveLosts; // Save Lost Conditions
|
|
bool eaSaveRestrictions; // Save Restriction Reports
|
|
|
|
//
|
|
// Requirements ...
|
|
|
|
//
|
|
XCAlert *eaAlert; // EA Scope Alert Handler ...
|
|
XCTrade *eaTrade; // EA Scope Trade Handler ...
|
|
XCGuard *eaGuard; // EA Scope Guard Handler ...
|
|
XCVolume *eaVolume; // EA Scope Voluem Handler ...
|
|
XTimeTracker eaTimeTracker; // EA Scope Time Tracker ...
|
|
XCDataCollector *eaCollector; // EA Scope Data Collector ...
|
|
XCXCATBEASignaller *eaSignallers[]; // EA Signallers Collection ...
|
|
XCXCATBEATradeManager *eaTradeManager; // EA Scope Trade Manager ...
|
|
XCXCATBEASignallerInputParser *eaSignallerInputParser; // EA Scope Signaller Input Parser ...
|
|
|
|
//
|
|
// Tools / Actions / Handlers ...
|
|
|
|
//
|
|
// Trade Event Handlers ...
|
|
|
|
//
|
|
void AddOnStopLossEventHandler(TOnStopLoss handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mStopLossEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnTakeProfitEventHandler(TOnTakeProfit handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mTakeProfitEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnDealsChangedEventHandler(TOnDealsChanged handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mDealsChangedEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mOrdersChangedEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnModifyPositionEventHandler(TOnModify handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mOnModifyEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mPositionsChangedEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mTradeStateChangedEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnForceClosePositionEventHandler(TOnForceClose handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mOnForceCloseEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
void AddOnPartialClosePositionEventHandler(TOnPartialClose handler)
|
|
{
|
|
//
|
|
if (handler == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
handler,
|
|
mOnPartialCloseEventHandlers
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Validators ...
|
|
|
|
/**
|
|
* Validate Inputs ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateInputs()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Implement all Inputs Validation ...
|
|
result = eaMagicNumber > 0 &&
|
|
eaSignalR2R > 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Expert Advisor Event Handlers ...
|
|
|
|
/**
|
|
* Handle Initialization of Expert ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HandleOnInit()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Inputs ...
|
|
result = ValidateInputs();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool has = false;
|
|
int count = -1;
|
|
|
|
//
|
|
// Initialize Alert Handler ...
|
|
eaAlert = new XCAlert();
|
|
eaAlert.SetPrefix(eaLogSuffix);
|
|
eaAlert.SetLogAlerts(eaLogAlerts);
|
|
eaAlert.SetMailAlerts(eaMailAlerts);
|
|
eaAlert.SetPushAlerts(eaPushAlerts);
|
|
eaAlert.SetSaveAlerts(eaSaveAlerts);
|
|
eaAlert.SetEnableAlerts(eaEnableAlerts);
|
|
eaAlert.SetTerminalAlerts(eaTerminalAlerts);
|
|
|
|
//
|
|
// Initialize Volume Manager ...
|
|
eaVolume = new XCVolume();
|
|
result = eaVolume.Init(
|
|
eaVolumeSelect,
|
|
eaStaticVoluem,
|
|
eaDynamicVolumeStepBalance,
|
|
eaDynamicVolumeStepVolume,
|
|
eaConstantRiskBalance,
|
|
eaConstantPercent,
|
|
eaConstantBalance //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Initialize Trader ...
|
|
eaTrade = new XCTrade(
|
|
eaSlippage,
|
|
eaMagicNumber,
|
|
eaMaxAllowedSpread,
|
|
eaMaxAllowedPositions,
|
|
eaMaxAllowedDrawdownFactor //
|
|
);
|
|
|
|
//
|
|
// Trade Handler Attachments ...
|
|
|
|
//
|
|
// Position Modifiy Event Handlers ...
|
|
count = ArraySize(mOnModifyEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnModifyPositionEventHandler(mOnModifyEventHandlers[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Position Stop Loss Event Handlers ...
|
|
if (has)
|
|
{
|
|
//
|
|
count = ArraySize(mStopLossEventHandlers);
|
|
has = IsValidSize(count);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnStopLossEventHandler(mStopLossEventHandlers[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Position Take Profit Event Handlers ...
|
|
count = ArraySize(mTakeProfitEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnTakeProfitEventHandler(mTakeProfitEventHandlers[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Position Force Close Event Handlers ...
|
|
count = ArraySize(mOnForceCloseEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnForceClosePositionEventHandler(mOnForceCloseEventHandlers[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Deals Changed Event Handlers ...
|
|
count = ArraySize(mDealsChangedEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnDealsChangedEventHandler(mDealsChangedEventHandlers[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Orders Changed Event Handlers ...
|
|
count = ArraySize(mOrdersChangedEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnOrdersChangedEventHandler(mOrdersChangedEventHandlers[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Positions Changed Event Handlers ...
|
|
count = ArraySize(mPositionsChangedEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnPositionsChangedEventHandler(mPositionsChangedEventHandlers[i]);
|
|
}
|
|
}
|
|
//
|
|
// Trade Changed Event Handlers ...
|
|
count = ArraySize(mTradeStateChangedEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnTradeStateChangedEventHandler(mTradeStateChangedEventHandlers[i]);
|
|
}
|
|
}
|
|
//
|
|
// Postion Partially Close Event Handlers ...
|
|
count = ArraySize(mOnPartialCloseEventHandlers);
|
|
has = IsValidSize(count);
|
|
if (has)
|
|
{
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
eaTrade.AddOnPartialClosePositionEventHandler(mOnPartialCloseEventHandlers[i]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initialize Guard Handler ...
|
|
eaGuard = new XCGuard(
|
|
eaAlert,
|
|
eaTrade //
|
|
);
|
|
|
|
//
|
|
// Initialize Data Collector ...
|
|
eaCollector = new XCDataCollector();
|
|
string mPath = eaAlert.GetPrefix() + "\\" + "Configs";
|
|
eaCollector.Path(mPath);
|
|
|
|
//
|
|
// Instantiating Signaller Input Parser ...
|
|
eaSignallerInputParser = new XCXCATBEASignallerInputParser(eaAlert);
|
|
|
|
//
|
|
// Initialize Trae Manager ...
|
|
eaTradeManager = new XCXCATBEATradeManager(
|
|
eaAlert,
|
|
eaTrade //
|
|
);
|
|
|
|
//
|
|
eaTradeManager.SaveWins(eaSaveWins);
|
|
eaTradeManager.SaveLosts(eaSaveLosts);
|
|
eaTradeManager.SaveTrades(eaSaveTrades);
|
|
eaTradeManager.SaveSignals(eaSaveSignals);
|
|
eaTradeManager.SaveRestrictions(eaSaveRestrictions);
|
|
|
|
//
|
|
// Enable Force Close At ...
|
|
eaTradeManager.SetForceCloseTradesAt(eaCloseAllOpenTradesAt);
|
|
|
|
//
|
|
// Setting Trade Reports ...
|
|
eaTradeManager
|
|
.SetTradeReports(
|
|
eaReportTrades,
|
|
eaReportSignals,
|
|
eaReportProtector,
|
|
eaReportRestrictions,
|
|
eaReportAfterTradesBalance //
|
|
);
|
|
|
|
//
|
|
// Setting Trade Permissions ...
|
|
eaTradeManager
|
|
.SetTradePermissions(
|
|
eaAllowTrade,
|
|
eaAllowLongs,
|
|
eaAllowShorts //
|
|
);
|
|
|
|
//
|
|
// Setting Trade Restrictions ...
|
|
eaTradeManager
|
|
.SetTradeRestrictions(
|
|
eaRestrictionsPeriod,
|
|
eaMaxAllowedTPs,
|
|
eaMaxAllowedSLs,
|
|
eaMaxAllowedTrades //
|
|
);
|
|
|
|
//
|
|
// Parsing Symbols ...
|
|
|
|
//
|
|
string symbols[];
|
|
int symbolsCount = 0;
|
|
if (IsValid(eaSymbols))
|
|
{
|
|
//
|
|
symbolsCount = SplitContent(
|
|
symbols,
|
|
eaSymbols,
|
|
"," //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Adding Default Symbol, if eaSymbols not Filled ...
|
|
if (!HasChild(symbols))
|
|
{
|
|
//
|
|
Add(
|
|
_Symbol,
|
|
symbols //
|
|
);
|
|
|
|
//
|
|
symbolsCount = ArraySize(symbols);
|
|
}
|
|
bool hasSymbols = HasChild(symbols);
|
|
|
|
//
|
|
// Initializing Sessions ...
|
|
string sessions[];
|
|
int sessionsCount = 0;
|
|
bool hasSession = IsValid(eaSessions);
|
|
if (hasSession)
|
|
{
|
|
//
|
|
// Extract Per Symbol Sessions ...
|
|
sessionsCount = SplitContent(
|
|
sessions,
|
|
eaSessions,
|
|
"," //
|
|
);
|
|
|
|
//
|
|
// Try to Extract Start and End Times Series ...
|
|
hasSession = IsValidSize(sessionsCount);
|
|
if (hasSession)
|
|
{
|
|
//
|
|
// Iterate Sessions ...
|
|
for (int i = 0; i < sessionsCount; i++)
|
|
{
|
|
//
|
|
// Ignore unused Cases and Extracts only Content ...
|
|
string iSessionDescriptorStr = ExtractString(sessions[i]);
|
|
bool isInited = IsValid(iSessionDescriptorStr);
|
|
if (isInited)
|
|
{
|
|
//
|
|
// Extract Session Descriptor Data ...
|
|
string parts[];
|
|
int partsCount = SplitContent(
|
|
parts,
|
|
iSessionDescriptorStr,
|
|
"_" //
|
|
);
|
|
isInited = IsValidSize(partsCount) && partsCount == 3;
|
|
if (isInited)
|
|
{
|
|
//
|
|
string iName = parts[0];
|
|
string iStart = parts[1];
|
|
string iEnd = parts[2];
|
|
isInited = IsValid(iName) &&
|
|
IsValid(iStart) &&
|
|
IsValid(iEnd);
|
|
if (isInited)
|
|
{
|
|
//
|
|
// Set Active Session Per Symbols ...
|
|
if (hasSymbols)
|
|
{
|
|
//
|
|
for (int j = 0; j < symbolsCount; j++)
|
|
{
|
|
//
|
|
eaTradeManager
|
|
.SetTradeSession(
|
|
symbols[j],
|
|
iStart,
|
|
iEnd,
|
|
iName //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initialize Signallers ...
|
|
if (hasSymbols)
|
|
{
|
|
//
|
|
// Prepare Signaller Inputs ...
|
|
XCATBEASignallerInputs iSignallerInputs;
|
|
|
|
//
|
|
// Common Configs ...
|
|
|
|
//
|
|
// Provider Name ...
|
|
iSignallerInputs.period = _Period;
|
|
iSignallerInputs.allowDraws = true;
|
|
iSignallerInputs.provider = "XTRGB";
|
|
iSignallerInputs.allowGuards = eaAllowGuards;
|
|
iSignallerInputs.riskToRewardRatio = eaSignalR2R;
|
|
iSignallerInputs.slATRMultiplier = eaSLATRMultiplier;
|
|
|
|
//
|
|
// CATB Indicator ...
|
|
iSignallerInputs.catbInputs.Default();
|
|
iSignallerInputs.catbInputs.Hide();
|
|
|
|
//
|
|
// Make Available all Requirement Buffers of XCATB indicator ...
|
|
iSignallerInputs.catbInputs.showPV = true;
|
|
iSignallerInputs.catbInputs.showKI = true;
|
|
iSignallerInputs.catbInputs.showSar = true;
|
|
iSignallerInputs.catbInputs.showTrend = true;
|
|
iSignallerInputs.catbInputs.showATRBand = true;
|
|
iSignallerInputs.catbInputs.showPVGolden = true;
|
|
|
|
//
|
|
// Signalling Configurations ...
|
|
iSignallerInputs.signallerConfigs.allowSignallingBasedOnConditions = eaAllowSignallingBasedOnConditions;
|
|
iSignallerInputs.signallerConfigs.allowSignallingBasedOnTriggerBlocks = eaAllowSignallingBasedOnTriggerBlocks;
|
|
iSignallerInputs.signallerConfigs.secondsTriggersSLUsingFirstTriggerBlock = eaSecondsTriggersSLUsingFirstTriggerBlock;
|
|
iSignallerInputs.signallerConfigs.applyValidateAndFilterOnSelectInsideOthers = eaApplyValidateAndFilterOnSelectInsideOthers;
|
|
iSignallerInputs.signallerConfigs.allowSignallingBasedOnTriggerBlocksInsideOther = eaAllowSignallingBasedOnTriggerBlocksInsideOther;
|
|
iSignallerInputs.signallerConfigs.allowSignallingConditions1 = eaAllowSignallingConditions1;
|
|
iSignallerInputs.signallerConfigs.allowSignallingConditions2 = eaAllowSignallingConditions2;
|
|
iSignallerInputs.signallerConfigs.allowSignallingConditions3 = eaAllowSignallingConditions3;
|
|
iSignallerInputs.signallerConfigs.allowSignallingConditions4 = eaAllowSignallingConditions4;
|
|
iSignallerInputs.signallerConfigs.allowSignallingConditions5 = eaAllowSignallingConditions5;
|
|
iSignallerInputs.signallerConfigs.allowSignallingConditions6 = eaAllowSignallingConditions6;
|
|
//
|
|
// Prepare Trigger Block Validations ...
|
|
|
|
//
|
|
iSignallerInputs.validations.forceHasSwing = eaForceHasSwing;
|
|
iSignallerInputs.validations.forceOBBarType = eaForceOBBarType;
|
|
iSignallerInputs.validations.minRequiredOBBar = eaMinRequiredOBBar;
|
|
iSignallerInputs.validations.forceFVGBarType = eaForceFVGBarType;
|
|
iSignallerInputs.validations.liquidityLoopback = eaLiquidityLoopback;
|
|
iSignallerInputs.validations.maxAllowedRange = eaMaxAllowedRange;
|
|
iSignallerInputs.validations.minAllowedRange = eaMinAllowedRange;
|
|
iSignallerInputs.validations.forceHasFLiquidity = eaForceHasFLiquidity;
|
|
iSignallerInputs.validations.forceHasRLiquidity = eaForceHasRLiquidity;
|
|
iSignallerInputs.validations.validateGapSequence = eaValidateGapSequence;
|
|
iSignallerInputs.validations.minAllowedBlockLength = eaMinAllowedBlockLength;
|
|
iSignallerInputs.validations.validateBlockEdgeBreakout = eaValidateBlockEdgeBreakout;
|
|
|
|
//
|
|
// Prepare Trigger Block Filters ...
|
|
|
|
//
|
|
iSignallerInputs.filters.filterBasedOnPV = eaFilterBasedOnPV;
|
|
iSignallerInputs.filters.bosLoopback = eaBosLoopback;
|
|
|
|
//
|
|
iSignallerInputs.filters.filterBasedOnSar = eaFilterBasedOnSar;
|
|
iSignallerInputs.filters.forceSarSwitched = eaForceSarSwitched;
|
|
iSignallerInputs.filters.forceSarOnBothSide = eaForceSarOnBothSide;
|
|
iSignallerInputs.filters.forceSarHasBreakout = eaForceSarHasBreakout;
|
|
iSignallerInputs.filters.forceSarHasReversalSide = eaForceSarHasReversalSide;
|
|
|
|
//
|
|
iSignallerInputs.filters.filterBasedOnRSI = eaFilterBasedOnRSI;
|
|
iSignallerInputs.filters.forceHasRSITrending = eaForceHasRSITrending;
|
|
iSignallerInputs.filters.forceHasRSIVPattern = eaForceHasRSIVPattern;
|
|
iSignallerInputs.filters.forceHasRSICrossing = eaForceHasRSICrossing;
|
|
|
|
//
|
|
iSignallerInputs.filters.filterBasedOnADX = eaFilterBasedOnADX;
|
|
iSignallerInputs.filters.forceHasADXTrending = eaForceHasADXTrending;
|
|
iSignallerInputs.filters.forceHasADXCrossing = eaForceHasADXCrossing;
|
|
|
|
//
|
|
iSignallerInputs.filters.filterBasedOnATR = eaFilterBasedOnATR;
|
|
iSignallerInputs.filters.forceHasATRTrending = eaForceHasATRTrending;
|
|
iSignallerInputs.filters.forceHasATRBreakout = eaForceHasATRBreakout;
|
|
|
|
//
|
|
iSignallerInputs.filters.filterBasedOnTrend = eaFilterBasedOnTrend;
|
|
iSignallerInputs.filters.forceHasTrendDir = eaForceHasTrendDir;
|
|
iSignallerInputs.filters.forceHasTrendPlace = eaForceHasTrendPlace;
|
|
iSignallerInputs.filters.forceHasTrendChange = eaForceHasTrendChange;
|
|
iSignallerInputs.filters.forceHasTrendTrending = eaForceHasTrendTrending;
|
|
iSignallerInputs.filters.forceHasTrendRejection = eaForceHasTrendRejection;
|
|
iSignallerInputs.filters.forceHasTrendLineInside = eaForceHasTrendLineInside;
|
|
iSignallerInputs.filters.forceHasTrendDirOnBothSide = eaForceHasTrendDirOnBothSide;
|
|
|
|
//
|
|
iSignallerInputs.filters.filterBasedOnKI = eaFilterBasedOnKI;
|
|
iSignallerInputs.filters.filterBasedOnDelta = eaFilterBasedOnDelta;
|
|
iSignallerInputs.filters.filterBasedOnVolume = eaFilterBasedOnVolume;
|
|
iSignallerInputs.filters.filterBasedOnSignalBar = eaFilterBasedOnSignalBar;
|
|
iSignallerInputs.filters.filterBasedOnHKSignalBar = eaFilterBasedOnHKSignalBar;
|
|
|
|
//
|
|
// Loop through Symbols and Initialize Signaller
|
|
// for it, then Attached it to eaSignallers ...
|
|
for (int i = 0; i < symbolsCount; i++)
|
|
{
|
|
//
|
|
// Attach Symbol ...
|
|
iSignallerInputs.symbol = symbols[i];
|
|
|
|
//
|
|
// Check if Provided Inputs File Exists ...
|
|
// if Exists, Load and Parse it ...
|
|
LoadConfig(iSignallerInputs);
|
|
|
|
//
|
|
// Check Inputs Validation ...
|
|
if (iSignallerInputs.IsValid())
|
|
{
|
|
//
|
|
// Initialize Signaller ...
|
|
XCXCATBEASignaller *iSignaller = new XCXCATBEASignaller(iSignallerInputs);
|
|
|
|
//
|
|
// Add it to the Signallers List ...
|
|
Add(
|
|
iSignaller,
|
|
eaSignallers //
|
|
);
|
|
|
|
//
|
|
ZeroMemory(iSignaller);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iSignallerInputs.Clean();
|
|
}
|
|
|
|
//
|
|
// since atleast one Signaller must
|
|
// exists to Expert works ...
|
|
// we check it as Last Step ...
|
|
result = hasSymbols &&
|
|
HasChild(eaSignallers);
|
|
if (result)
|
|
{
|
|
//
|
|
string message = "Initialized Successfully ...";
|
|
eaAlert.SendAlert(message);
|
|
|
|
//
|
|
SaveConfigs();
|
|
}
|
|
else
|
|
{
|
|
//
|
|
string message = "Initialization Failed ...";
|
|
eaAlert.SendAlert(message);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Handle De Initialization of Expert ...
|
|
*/
|
|
void HandleOnDeInit()
|
|
{
|
|
//
|
|
delete eaTrade;
|
|
ZeroMemory(eaTrade);
|
|
|
|
//
|
|
delete eaGuard;
|
|
ZeroMemory(eaGuard);
|
|
|
|
//
|
|
delete eaVolume;
|
|
ZeroMemory(eaVolume);
|
|
|
|
//
|
|
eaTimeTracker.Clean();
|
|
|
|
//
|
|
Clean(eaSignallers);
|
|
|
|
//
|
|
delete eaTradeManager;
|
|
ZeroMemory(eaTradeManager);
|
|
|
|
//
|
|
delete eaCollector;
|
|
ZeroMemory(eaCollector);
|
|
|
|
//
|
|
delete eaSignallerInputParser;
|
|
ZeroMemory(eaSignallerInputParser);
|
|
|
|
//
|
|
string message = "DeInitialized Successfully ...";
|
|
eaAlert.SendAlert(message);
|
|
|
|
//
|
|
delete eaAlert;
|
|
ZeroMemory(eaAlert);
|
|
}
|
|
|
|
/**
|
|
* Handle Tick ...
|
|
*/
|
|
void HandleOnTick()
|
|
{
|
|
//
|
|
// Time Report Handling ...
|
|
HandleTimeReport();
|
|
|
|
//
|
|
// Position Management / Protections Handling ...
|
|
eaTradeManager.Manage();
|
|
|
|
//
|
|
// Check Signallers Registered ...
|
|
bool has = HasChild(eaSignallers);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Define Collection of Requirements ...
|
|
XGuard guards[];
|
|
XCATBEAStrategyConditions conditions[];
|
|
|
|
//
|
|
// Loop through Registered Signallers to Proccess Ticks and
|
|
// Collect:
|
|
// - Guards;
|
|
// - Triggered Conditions;
|
|
// - ...
|
|
int count = ArraySize(eaSignallers);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Retrieve indexed Signaller ...
|
|
XCXCATBEASignaller *iSignaller = eaSignallers[i];
|
|
|
|
//
|
|
string iSymbol = iSignaller.GetSymbol();
|
|
string iProvider = iSignaller.GetProvider();
|
|
ENUM_TIMEFRAMES iPeriod = iSignaller.GetPeriod();
|
|
|
|
//
|
|
// Now we Have to Check Handle Tick Resoult ...
|
|
|
|
//
|
|
// Requirements ...
|
|
XGuard iGuards[]; // Hold Provided Guards ...
|
|
XPosition iPositions[]; // Retrieve Signaller Positions ...
|
|
XCATBEAStrategyConditions iConditions; // Recieve Triggered Conditions ...
|
|
|
|
//
|
|
// Check Active Session ...
|
|
bool isActiveSession = eaTradeManager.IsActiveSession(iSymbol);
|
|
|
|
//
|
|
// Reading Signaller Positions ...
|
|
eaTradeManager.GetPositions(
|
|
iPositions,
|
|
iSymbol,
|
|
iProvider,
|
|
iPeriod //
|
|
);
|
|
|
|
//
|
|
// Processing Tick for Signaller ...
|
|
iSignaller.ProcessTick(
|
|
iPositions,
|
|
iGuards,
|
|
iConditions,
|
|
isActiveSession //
|
|
);
|
|
|
|
//
|
|
// Check Results ...
|
|
has = HasChild(iGuards);
|
|
if (has)
|
|
{
|
|
//
|
|
Copy(
|
|
iGuards,
|
|
guards,
|
|
false // Force Clean ...
|
|
);
|
|
}
|
|
|
|
//
|
|
// Check Triggered Conditions ...
|
|
has = iConditions.IsValid() &&
|
|
iConditions.IsSetuped() &&
|
|
iConditions.CanTrigger();
|
|
if (has)
|
|
{
|
|
//
|
|
AddRef(
|
|
iConditions,
|
|
conditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
Clean(iGuards);
|
|
Clean(iPositions);
|
|
iConditions.Clean();
|
|
}
|
|
|
|
//
|
|
// Do Actions Based on Provided Info ...
|
|
|
|
//
|
|
// Guards ...
|
|
has = HasChild(guards);
|
|
if (has)
|
|
{
|
|
//
|
|
// Handle Guards Firing ...
|
|
eaGuard.DoGuards(guards);
|
|
}
|
|
|
|
//
|
|
// Triggers ...
|
|
has = HasChild(conditions);
|
|
if (has)
|
|
{
|
|
//
|
|
// Handle Conditions Triggering ...
|
|
TriggerConditions(conditions);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
Clean(guards);
|
|
Clean(conditions);
|
|
}
|
|
|
|
/**
|
|
* Handle Trade ...
|
|
*/
|
|
void HandleOnTrade()
|
|
{
|
|
eaTrade.HandleOnTrade();
|
|
}
|
|
|
|
/**
|
|
* Handle Timer ...
|
|
*/
|
|
void HandleOnTimer()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle Chart Event ...
|
|
*
|
|
* @param id: int, Event id ...
|
|
* @param lparam: long, Event Long Parameter ...
|
|
* @param dparam: double, Event Double Parameter ...
|
|
* @param sparam: string, Event String Parameter ...
|
|
*/
|
|
void HandleOnChartEvent(
|
|
const int id,
|
|
const long &lparam,
|
|
const double &dparam,
|
|
const string &sparam //
|
|
)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Trade Event Handlers ...
|
|
|
|
/**
|
|
* Handle Stop Loss Event Triggered ...
|
|
*
|
|
* @param deal: XDeal instance refrence, provides Triggered Deal info ...
|
|
*/
|
|
void HandleOnStopLossTriggered(const XDeal &deal)
|
|
{
|
|
eaTradeManager.HandleSL(deal);
|
|
}
|
|
|
|
/**
|
|
* Handle Take Profit Event Triggered ...
|
|
*
|
|
* @param deal: XDeal instance refrence, provides Triggered Deal info ...
|
|
*/
|
|
void HandleOnTakeProfitTriggered(const XDeal &deal)
|
|
{
|
|
eaTradeManager.HandleTP(deal);
|
|
}
|
|
|
|
/**
|
|
* Handle Position Force Closed Event ...
|
|
*
|
|
* @param ticket: ulong, triggered Positions ticket ...
|
|
* @param position: XPosition instance refrence, Triggered Position ...
|
|
* @param comment: string, Comment ...
|
|
*/
|
|
void HandleOnPositionForceClosed(
|
|
const ulong ticket,
|
|
const XPosition &position,
|
|
const string comment //
|
|
)
|
|
{
|
|
eaTradeManager.HandleForceClose(position);
|
|
}
|
|
|
|
/**
|
|
* Handle Position Partially Closed Event ...
|
|
*
|
|
* @param ticket: ulong, triggered Positions ticket ...
|
|
* @param profit: double, Position Profit ...
|
|
* @param comment: string, Comment ...
|
|
*/
|
|
void HandleOnPositionPartialClosed(
|
|
const ulong ticket,
|
|
const double profit,
|
|
const string comment //
|
|
)
|
|
{
|
|
//
|
|
eaTradeManager.HandlePartiallyClosed(
|
|
ticket,
|
|
profit,
|
|
comment //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Handle Deals Changed ...
|
|
*
|
|
* @param count: int, number of changes ...
|
|
* if the count is positive, means new added ...
|
|
* if the count is negative, means removed ...
|
|
*/
|
|
void HandleOnDealsChanged(int count)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle Orders Changed ...
|
|
*
|
|
* @param count: int, number of changes ...
|
|
* if the count is positive, means new added ...
|
|
* if the count is negative, means removed ...
|
|
*/
|
|
void HandleOnOrdersChanged(int count)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle Positions Changed ...
|
|
*
|
|
* @param count: int, number of changes ...
|
|
* if the count is positive, means new added ...
|
|
* if the count is negative, means removed ...
|
|
*/
|
|
void HandleOnPositionsChanged(int count)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle Position Modified Event ...
|
|
*
|
|
* @param ticket: ulong, triggered Positions ticket ...
|
|
* @param profit: double, Position Profit ...
|
|
* @param comment: string, Comment ...
|
|
*/
|
|
void HandleOnPositionModified(
|
|
const ulong ticket,
|
|
const double profit,
|
|
const string comment //
|
|
)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Handle all Trades States Changed Event ...
|
|
*
|
|
* @param state: XOnTradeHandlerState instance refrence, Changed Trade State data ...
|
|
*/
|
|
void HandleOnTradeStateChanged(const XOnTradeHandlerState &state)
|
|
{
|
|
}
|
|
|
|
//
|
|
// protected ...
|
|
protected:
|
|
//
|
|
|
|
/**
|
|
* Report Time Changes based on Given Configurations ...
|
|
*/
|
|
void HandleTimeReport()
|
|
{
|
|
//
|
|
if (eaAlert == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Monthly Report ....
|
|
if (eaReportNewMonths &&
|
|
eaTimeTracker.IsNewMonth())
|
|
{
|
|
//
|
|
string msg = "New Month ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
|
|
//
|
|
// Weekly Report ....
|
|
if (eaReportNewWeeks &&
|
|
eaTimeTracker.IsNewWeek())
|
|
{
|
|
//
|
|
string msg = "New Week ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
|
|
//
|
|
// Daily Report ....
|
|
if (eaReportNewDays &&
|
|
eaTimeTracker.IsNewDay())
|
|
{
|
|
//
|
|
string msg = "New Day ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
|
|
//
|
|
// Hourly Report ....
|
|
if (eaReportNewHours &&
|
|
eaTimeTracker.IsNewHour())
|
|
{
|
|
//
|
|
string msg = "New Hour ...";
|
|
|
|
//
|
|
eaAlert.SendAlert(msg);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update Signal Targets ...
|
|
*/
|
|
void UpdateSignalTargets(XSignal &signal)
|
|
{
|
|
//
|
|
bool has = signal.IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Clean Signal Targets ...
|
|
Clean(signal.targets);
|
|
|
|
//
|
|
// Calculate Requirements ...
|
|
double r2r = eaSignalR2R > 0
|
|
? eaSignalR2R
|
|
: 1;
|
|
double risk = signal.GetRisk();
|
|
double reward = risk * r2r;
|
|
|
|
//
|
|
double isLong = IsLong(signal.type);
|
|
|
|
//
|
|
// Handling Signal TP ...
|
|
signal.tp =
|
|
isLong
|
|
? signal.entry + reward
|
|
: signal.entry - reward;
|
|
|
|
//
|
|
// Try to Apply Money Management ...
|
|
|
|
//
|
|
// Sort Targets ...
|
|
ENUM_X_DIRECTION sortingDir =
|
|
isLong
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
ApplySortOnTargets(
|
|
sortingDir,
|
|
signal.targets //
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Convert a Triggered Conditions to Signal and
|
|
* Execute it ...
|
|
*/
|
|
void TriggerConditions(XCATBEAStrategyConditions &conditions[])
|
|
{
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
has = HasChild(conditions);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
count = ArraySize(conditions);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
// Retrieve Indexed Conditions ...
|
|
XCATBEAStrategyConditions iConditions = conditions[i];
|
|
|
|
//
|
|
// Define Signal Structure ...
|
|
XSignal iSignal;
|
|
|
|
//
|
|
// Check Conditions is Valid Triggered Conditions ...
|
|
has =
|
|
iConditions.IsValid() &&
|
|
iConditions.IsSetuped() &&
|
|
iConditions.CanTrigger();
|
|
if (has)
|
|
{
|
|
//
|
|
// Preparing Signal ...
|
|
has = ToSignal(
|
|
iSignal,
|
|
iConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Validate Signal ...
|
|
has = iSignal.IsValid();
|
|
if (has)
|
|
{
|
|
//
|
|
// Retrieve Signal Type ...
|
|
bool isLong = IsLong(iSignal.type);
|
|
|
|
//
|
|
// Update Signal Entry ...
|
|
iSignal.entry = GetEntry(
|
|
iSignal.symbol,
|
|
iSignal.type //
|
|
);
|
|
|
|
//
|
|
// Update Signal Targets ...
|
|
UpdateSignalTargets(iSignal);
|
|
|
|
//
|
|
// Handle Volume Management ...
|
|
double iVolume = eaVolume.CalculateVolume(iSignal);
|
|
has = iVolume > X_MIN_VOLUME &&
|
|
iVolume != iSignal.volume;
|
|
if (has)
|
|
{
|
|
iSignal.volume = iVolume;
|
|
}
|
|
|
|
//
|
|
// Execute Signal ...
|
|
has = eaTradeManager.Execute(
|
|
iSignal,
|
|
iConditions //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
|
|
//
|
|
iSignal.Clean();
|
|
iConditions.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// private ...
|
|
private:
|
|
//
|
|
|
|
//
|
|
TOnModify mOnModifyEventHandlers[];
|
|
TOnStopLoss mStopLossEventHandlers[];
|
|
TOnTakeProfit mTakeProfitEventHandlers[];
|
|
TOnForceClose mOnForceCloseEventHandlers[];
|
|
TOnDealsChanged mDealsChangedEventHandlers[];
|
|
TOnOrdersChanged mOrdersChangedEventHandlers[];
|
|
TOnPartialClose mOnPartialCloseEventHandlers[];
|
|
TOnPositionsChanged mPositionsChangedEventHandlers[];
|
|
TOnTradeStateChanged mTradeStateChangedEventHandlers[];
|
|
|
|
//
|
|
void SaveConfigs()
|
|
{
|
|
//
|
|
string content = NULL;
|
|
|
|
//
|
|
string separator = "\n";
|
|
bool ignoreFalseConditions = false;
|
|
|
|
//
|
|
// Preparng Condtions ...
|
|
content +=
|
|
//
|
|
"-----------------------" + separator +
|
|
"Validating: " + separator +
|
|
"-----------------------" + separator +
|
|
ToXString("eaForceHasSwing", eaForceHasSwing, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceOBBarType", eaForceOBBarType, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceFVGBarType", eaForceFVGBarType, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasFLiquidity", eaForceHasFLiquidity, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRLiquidity", eaForceHasRLiquidity, ignoreFalseConditions, separator) +
|
|
ToXString("eaValidateGapSequence", eaValidateGapSequence, ignoreFalseConditions, separator) +
|
|
ToXString("eaValidateBlockEdgeBreakout", eaValidateBlockEdgeBreakout, ignoreFalseConditions, separator) +
|
|
//
|
|
"-----------------------" + separator +
|
|
"Filtering: " + separator +
|
|
"-----------------------" + separator +
|
|
ToXString("eaFilterBasedOnKI", eaFilterBasedOnKI, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnPV", eaFilterBasedOnPV, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnSar", eaFilterBasedOnSar, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarSwitched", eaForceSarSwitched, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarOnBothSide", eaForceSarOnBothSide, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarHasBreakout", eaForceSarHasBreakout, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarHasReversalSide", eaForceSarHasReversalSide, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnRSI", eaFilterBasedOnRSI, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRSITrending", eaForceHasRSITrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRSIVPattern", eaForceHasRSIVPattern, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRSICrossing", eaForceHasRSICrossing, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnADX", eaFilterBasedOnADX, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasADXTrending", eaForceHasADXTrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasADXCrossing", eaForceHasADXCrossing, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnATR", eaFilterBasedOnATR, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasATRTrending", eaForceHasATRTrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasATRBreakout", eaForceHasATRBreakout, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnTrend", eaFilterBasedOnTrend, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendDir", eaForceHasTrendDir, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendPlace", eaForceHasTrendPlace, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendChange", eaForceHasTrendChange, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendTrending", eaForceHasTrendTrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendRejection", eaForceHasTrendRejection, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendLineInside", eaForceHasTrendLineInside, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendDirOnBothSide", eaForceHasTrendDirOnBothSide, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnDelta", eaFilterBasedOnDelta, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnVolume", eaFilterBasedOnVolume, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnSignalBar", eaFilterBasedOnSignalBar, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnHKSignalBar", eaFilterBasedOnHKSignalBar, ignoreFalseConditions, separator) +
|
|
//
|
|
""
|
|
//
|
|
;
|
|
|
|
//
|
|
// Try to Save Condtions ...
|
|
string fileName = eaCollector.GetFilePath("XConfigs");
|
|
bool has = IsValid(fileName);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
eaCollector.Save(
|
|
fileName,
|
|
content //
|
|
);
|
|
|
|
//
|
|
// Try to Save Inputs ...
|
|
fileName = eaCollector.GetFilePath("XInputs");
|
|
has = IsValid(fileName);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Preparing Inputs String Reperesentation ...
|
|
content = NULL;
|
|
content +=
|
|
//
|
|
"//" + separator +
|
|
"// Common ..." + separator +
|
|
ToXString("eaMagicNumber", eaMagicNumber, separator) +
|
|
ToXString("eaSlippage", eaSlippage, separator) +
|
|
ToXString("eaLogSuffix", eaLogSuffix, separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Detector ..." + separator +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Validating ..." + separator +
|
|
ToXString("eaForceHasSwing", eaForceHasSwing, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceOBBarType", eaForceOBBarType, ignoreFalseConditions, separator) +
|
|
ToXString("eaMinRequiredOBBar", eaMinRequiredOBBar, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceFVGBarType", eaForceFVGBarType, ignoreFalseConditions, separator) +
|
|
ToXString("eaLiquidityLoopback", eaLiquidityLoopback, ignoreFalseConditions, separator) +
|
|
ToXString("eaMaxAllowedRange", ToXString(eaMaxAllowedRange), separator) +
|
|
ToXString("eaMinAllowedRange", ToXString(eaMinAllowedRange), separator) +
|
|
ToXString("eaForceHasFLiquidity", eaForceHasFLiquidity, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRLiquidity", eaForceHasRLiquidity, ignoreFalseConditions, separator) +
|
|
ToXString("eaValidateGapSequence", eaValidateGapSequence, ignoreFalseConditions, separator) +
|
|
ToXString("eaMinAllowedBlockLength", eaMinAllowedBlockLength, ignoreFalseConditions, separator) +
|
|
ToXString("eaValidateBlockEdgeBreakout", eaValidateBlockEdgeBreakout, ignoreFalseConditions, separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Filtering ..." + separator +
|
|
ToXString("eaFilterBasedOnKI", eaFilterBasedOnKI, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnPV", eaFilterBasedOnPV, ignoreFalseConditions, separator) +
|
|
ToXString("eaBosLoopback", eaBosLoopback, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnSar", eaFilterBasedOnSar, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarSwitched", eaForceSarSwitched, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarOnBothSide", eaForceSarOnBothSide, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarHasBreakout", eaForceSarHasBreakout, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceSarHasReversalSide", eaForceSarHasReversalSide, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnRSI", eaFilterBasedOnRSI, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRSITrending", eaForceHasRSITrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRSIVPattern", eaForceHasRSIVPattern, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasRSICrossing", eaForceHasRSICrossing, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnADX", eaFilterBasedOnADX, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasADXTrending", eaForceHasADXTrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasADXCrossing", eaForceHasADXCrossing, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnATR", eaFilterBasedOnATR, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasATRTrending", eaForceHasATRTrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasATRBreakout", eaForceHasATRBreakout, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnTrend", eaFilterBasedOnTrend, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendDir", eaForceHasTrendDir, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendPlace", eaForceHasTrendPlace, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendChange", eaForceHasTrendChange, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendTrending", eaForceHasTrendTrending, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendRejection", eaForceHasTrendRejection, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendLineInside", eaForceHasTrendLineInside, ignoreFalseConditions, separator) +
|
|
ToXString("eaForceHasTrendDirOnBothSide", eaForceHasTrendDirOnBothSide, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnDelta", eaFilterBasedOnDelta, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnVolume", eaFilterBasedOnVolume, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnSignalBar", eaFilterBasedOnSignalBar, ignoreFalseConditions, separator) +
|
|
ToXString("eaFilterBasedOnHKSignalBar", eaFilterBasedOnHKSignalBar, ignoreFalseConditions, separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Signal ..." + separator +
|
|
ToXString("eaSignalR2R", eaSignalR2R, ignoreFalseConditions, separator) +
|
|
ToXString("eaSLATRMultiplier", ToXString(eaSLATRMultiplier), separator) +
|
|
ToXString("eaAllowSignallingBasedOnConditions", eaAllowSignallingBasedOnConditions, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingBasedOnTriggerBlocks", eaAllowSignallingBasedOnTriggerBlocks, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingBasedOnTriggerBlocksInsideOther", eaAllowSignallingBasedOnTriggerBlocksInsideOther, ignoreFalseConditions, separator) +
|
|
ToXString("eaSecondsTriggersSLUsingFirstTriggerBlock", eaSecondsTriggersSLUsingFirstTriggerBlock, ignoreFalseConditions, separator) +
|
|
ToXString("eaApplyValidateAndFilterOnSelectInsideOthers", eaApplyValidateAndFilterOnSelectInsideOthers, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingConditions1", eaAllowSignallingConditions1, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingConditions2", eaAllowSignallingConditions2, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingConditions3", eaAllowSignallingConditions3, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingConditions4", eaAllowSignallingConditions4, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingConditions5", eaAllowSignallingConditions5, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowSignallingConditions6", eaAllowSignallingConditions6, ignoreFalseConditions, separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Volume ..." + separator +
|
|
ToXString("eaVolumeSelect", ToXString(eaVolumeSelect), separator) +
|
|
ToXString("eaStaticVoluem", ToXString(eaStaticVoluem), separator) +
|
|
ToXString("eaDynamicVolumeStepBalance", ToXString(eaDynamicVolumeStepBalance), separator) +
|
|
ToXString("eaDynamicVolumeStepVolume", ToXString(eaDynamicVolumeStepVolume), separator) +
|
|
ToXString("eaConstantRiskBalance", ToXString(eaConstantRiskBalance), separator) +
|
|
ToXString("eaConstantPercent", ToXString(eaConstantPercent), separator) +
|
|
ToXString("eaConstantBalance", ToXString(eaConstantBalance), separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Management ..." + separator +
|
|
ToXString("eaSymbols", eaSymbols, separator) +
|
|
ToXString("eaAllowGuards", eaAllowGuards, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowTrade", eaAllowTrade, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowLongs", eaAllowLongs, ignoreFalseConditions, separator) +
|
|
ToXString("eaAllowShorts", eaAllowShorts, ignoreFalseConditions, separator) +
|
|
ToXString("eaSessions", eaSessions, separator) +
|
|
ToXString("eaRestrictionsPeriod", ToXString(eaRestrictionsPeriod), separator) +
|
|
ToXString("eaMaxAllowedTPs", eaMaxAllowedTPs, ignoreFalseConditions, separator) +
|
|
ToXString("eaMaxAllowedSLs", eaMaxAllowedSLs, ignoreFalseConditions, separator) +
|
|
ToXString("eaMaxAllowedTrades", eaMaxAllowedTrades, ignoreFalseConditions, separator) +
|
|
ToXString("eaMaxAllowedPositions", eaMaxAllowedPositions, ignoreFalseConditions, separator) +
|
|
ToXString("eaMaxAllowedSpread", ToXString(eaMaxAllowedSpread), separator) +
|
|
ToXString("eaMaxAllowedDrawdownFactor", ToXString(eaMaxAllowedDrawdownFactor), separator) +
|
|
ToXString("eaCloseAllOpenTradesAt", eaCloseAllOpenTradesAt, separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Alert ..." + separator +
|
|
ToXString("eaEnableAlerts", eaEnableAlerts, ignoreFalseConditions, separator) +
|
|
ToXString("eaSaveAlerts", eaSaveAlerts, ignoreFalseConditions, separator) +
|
|
ToXString("eaLogAlerts", eaLogAlerts, ignoreFalseConditions, separator) +
|
|
ToXString("eaMailAlerts", eaMailAlerts, ignoreFalseConditions, separator) +
|
|
ToXString("eaPushAlerts", eaPushAlerts, ignoreFalseConditions, separator) +
|
|
ToXString("eaTerminalAlerts", eaTerminalAlerts, ignoreFalseConditions, separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Time Report ..." + separator +
|
|
ToXString("eaReportNewMonths", eaReportNewMonths, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportNewWeeks", eaReportNewWeeks, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportNewDays", eaReportNewDays, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportNewHours", eaReportNewHours, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportTrades", eaReportTrades, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportSignals", eaReportSignals, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportProtector", eaReportProtector, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportRestrictions", eaReportRestrictions, ignoreFalseConditions, separator) +
|
|
ToXString("eaReportAfterTradesBalance", eaReportAfterTradesBalance, ignoreFalseConditions, separator) +
|
|
"" + separator +
|
|
"//" + separator +
|
|
"// Collector ..." + separator +
|
|
ToXString("eaSaveTrades", eaSaveTrades, ignoreFalseConditions, separator) +
|
|
ToXString("eaSaveSignals", eaSaveSignals, ignoreFalseConditions, separator) +
|
|
ToXString("eaSaveWins", eaSaveWins, ignoreFalseConditions, separator) +
|
|
ToXString("eaSaveLosts", eaSaveLosts, ignoreFalseConditions, separator) +
|
|
ToXString("eaSaveRestrictions", eaSaveRestrictions, ignoreFalseConditions, separator) +
|
|
//
|
|
""
|
|
//
|
|
;
|
|
|
|
//
|
|
eaCollector.Save(
|
|
fileName,
|
|
content //
|
|
);
|
|
}
|
|
|
|
//
|
|
bool LoadConfig(XCATBEASignallerInputs &inputs)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Args ...
|
|
result =
|
|
IsValid(inputs.period) &&
|
|
IsValid(inputs.symbol);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check the Provided File Exists or not ...
|
|
result =
|
|
eaSignallerInputParser
|
|
.IsSignallerInputsFileExists(
|
|
inputs.symbol,
|
|
inputs.period //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse File Content ...
|
|
result =
|
|
eaSignallerInputParser
|
|
.ParseSignallerInputs(
|
|
inputs,
|
|
inputs.symbol,
|
|
inputs.period //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |