825 lines
16 KiB
Plaintext
825 lines
16 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// ----------------------------------------------
|
|
// Name: XSCX121SetupCycle
|
|
// Description: provides implementation of X121
|
|
// Setup on Specified Market Cycle ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
|
|
//
|
|
#include <Arrays/ArrayObj.mqh>
|
|
#include "../Classes/x-saherelm.x121.setup.class.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Inputs ...
|
|
struct X121SetupCycleInputs
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
XMarketCycle cycle; // Market Cycle
|
|
|
|
//
|
|
X121SetupInputs inputs; // Inputs
|
|
|
|
//
|
|
XSCX121Setup *setup; // Setup
|
|
|
|
//
|
|
// Constructor ...
|
|
void X121SetupCycleInputs()
|
|
{
|
|
}
|
|
|
|
//
|
|
// Initialization ...
|
|
bool Init(
|
|
X121SetupInputs &_inputs, // Configurations
|
|
ENUM_TIMEFRAMES _hostPeriod, // Host Period
|
|
ENUM_X_MARKET_CYCLES _cycle, // Init Cycle
|
|
ENUM_X_PERIOD_METHOD _method, // Period Selection Method
|
|
ENUM_TIMEFRAMES _period, // Provided Period
|
|
string _prefix = "" // Prefix
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Validate Inputs ...
|
|
result =
|
|
//
|
|
IsValid(_inputs.symbol)
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Init Cycle ...
|
|
result = cycle.Init(
|
|
inputs.symbol,
|
|
_hostPeriod,
|
|
_cycle,
|
|
_method,
|
|
_period,
|
|
_prefix //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
cycle.Update(0);
|
|
|
|
//
|
|
_inputs.period = cycle.period;
|
|
|
|
//
|
|
result = _inputs.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
this.inputs = _inputs;
|
|
|
|
//
|
|
setup = new XSCX121Setup();
|
|
result = setup.Init(
|
|
inputs //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
string GetSymbol()
|
|
{
|
|
return inputs.symbol;
|
|
}
|
|
|
|
//
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
return inputs.period;
|
|
}
|
|
|
|
//
|
|
bool CanProcessBar()
|
|
{
|
|
return cycle.barTracker.CanProcessBar();
|
|
}
|
|
|
|
//
|
|
void WaitsUntilNextBar()
|
|
{
|
|
cycle.barTracker.Waits();
|
|
}
|
|
|
|
//
|
|
bool GetConditions(
|
|
X121SetupConditions &conditions, //
|
|
int barIndex = 0, //
|
|
int loopback = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = cycle.Update(
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
result = setup.GetConditions(
|
|
conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Class ...
|
|
class XSCX121SetupCycles : public XSCBaseAlert
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
X121SignalGenerator signalGenerator;
|
|
|
|
//
|
|
X121SetupCycleInputs cCycle; // Current (Host) Cycle
|
|
X121SetupCycleInputs sCycle; // Short Cycle
|
|
X121SetupCycleInputs mCycle; // Medium Cycle
|
|
X121SetupCycleInputs lCycle; // Long Cycle
|
|
X121SetupCycleInputs hCycle; // Hind Cycle
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
void XSCX121SetupCycles() {}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XSCX121SetupCycles() {}
|
|
|
|
//
|
|
// Initialized ...
|
|
bool Init(
|
|
X121SetupInputs &_inputs, // Configurations
|
|
string _symbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES _hostPeriod, // Host Period
|
|
ENUM_X_PERIOD_METHOD _sMethod = X_PERIOD_AUTO, // Short Period Selection Method
|
|
ENUM_TIMEFRAMES _sPeriod = NULL, // Short Provided Period
|
|
ENUM_X_PERIOD_METHOD _mMethod = X_PERIOD_AUTO, // Medium Period Selection Method
|
|
ENUM_TIMEFRAMES _mPeriod = NULL, // Medium Provided Period
|
|
ENUM_X_PERIOD_METHOD _lMethod = X_PERIOD_AUTO, // Long Period Selection Method
|
|
ENUM_TIMEFRAMES _lPeriod = NULL, // Long Provided Period
|
|
ENUM_X_PERIOD_METHOD _hMethod = X_PERIOD_AUTO, // Hind Period Selection Method
|
|
ENUM_TIMEFRAMES _hPeriod = NULL // Hind Provided Period
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Check Validation of Symbol and Period ...
|
|
result =
|
|
//
|
|
IsValid(_symbol) &&
|
|
IsValid(_hostPeriod)
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Initialize Market Cycles ...
|
|
|
|
//
|
|
// Current ...
|
|
_inputs.symbol = _symbol;
|
|
result = cCycle.Init(
|
|
_inputs,
|
|
_hostPeriod,
|
|
X_MARKET_CYCLE_SHORT,
|
|
X_PERIOD_MANUALLY,
|
|
_hostPeriod,
|
|
"CURR" //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = cBarTracker.Init(
|
|
_inputs.symbol,
|
|
_hostPeriod //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Short ...
|
|
result = sCycle.Init(
|
|
_inputs,
|
|
_hostPeriod,
|
|
X_MARKET_CYCLE_SHORT,
|
|
_sMethod,
|
|
_sPeriod //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = sBarTracker.Init(
|
|
_inputs.symbol,
|
|
sCycle.cycle.period //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Medium ...
|
|
result = mCycle.Init(
|
|
_inputs,
|
|
_hostPeriod,
|
|
X_MARKET_CYCLE_MEDIUM,
|
|
_mMethod,
|
|
_mPeriod //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = mBarTracker.Init(
|
|
_inputs.symbol,
|
|
mCycle.cycle.period //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Long ...
|
|
result = lCycle.Init(
|
|
_inputs,
|
|
_hostPeriod,
|
|
X_MARKET_CYCLE_LONG,
|
|
_lMethod,
|
|
_lPeriod //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = lBarTracker.Init(
|
|
_inputs.symbol,
|
|
lCycle.cycle.period //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Hind ...
|
|
result = hCycle.Init(
|
|
_inputs,
|
|
_hostPeriod,
|
|
X_MARKET_CYCLE_HIND,
|
|
_hMethod,
|
|
_hPeriod //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = hBarTracker.Init(
|
|
_inputs.symbol,
|
|
hCycle.cycle.period //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
_inputs.period = cCycle.GetPeriod();
|
|
|
|
//
|
|
this.inputs = _inputs;
|
|
result = inputs.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Getter(s) / Setter(s) ...
|
|
|
|
//
|
|
X121SetupInputs GetInputs()
|
|
{
|
|
return this.inputs;
|
|
}
|
|
|
|
//
|
|
bool SetInputs(
|
|
X121SetupInputs &_inputs // Cycles Configurations
|
|
)
|
|
{
|
|
//
|
|
bool result = Init(
|
|
_inputs,
|
|
_inputs.symbol,
|
|
_inputs.period //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string GetSymbol()
|
|
{
|
|
return cCycle.GetSymbol();
|
|
}
|
|
|
|
//
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
return cCycle.GetPeriod();
|
|
}
|
|
|
|
//
|
|
bool CanProcessBar(
|
|
ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
switch (cycle)
|
|
{
|
|
//
|
|
case X_MARKET_CYCLE_SHORT:
|
|
//
|
|
result = sBarTracker.CanProcessBar();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_MEDIUM:
|
|
//
|
|
result = mBarTracker.CanProcessBar();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_LONG:
|
|
//
|
|
result = lBarTracker.CanProcessBar();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_HIND:
|
|
//
|
|
result = hBarTracker.CanProcessBar();
|
|
break;
|
|
|
|
//
|
|
default:
|
|
case X_MARKET_CYCLE_UNKNOWN:
|
|
//
|
|
result = cBarTracker.CanProcessBar();
|
|
break;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
datetime GetNextSignalTime(
|
|
ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN //
|
|
)
|
|
{
|
|
//
|
|
datetime result = NULL;
|
|
|
|
//
|
|
switch (cycle)
|
|
{
|
|
//
|
|
case X_MARKET_CYCLE_SHORT:
|
|
result = sNextValidSignal;
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_MEDIUM:
|
|
result = mNextValidSignal;
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_LONG:
|
|
result = lNextValidSignal;
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_HIND:
|
|
result = hNextValidSignal;
|
|
break;
|
|
|
|
//
|
|
default:
|
|
case X_MARKET_CYCLE_UNKNOWN:
|
|
result = cNextValidSignal;
|
|
break;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void WaitsUntilNextBar(
|
|
ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN //
|
|
)
|
|
{
|
|
//
|
|
switch (cycle)
|
|
{
|
|
//
|
|
case X_MARKET_CYCLE_SHORT:
|
|
//
|
|
FillNextBarTime(
|
|
sNextValidSignal,
|
|
sBarTracker //
|
|
);
|
|
sBarTracker.Waits();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_MEDIUM:
|
|
//
|
|
FillNextBarTime(
|
|
mNextValidSignal,
|
|
mBarTracker //
|
|
);
|
|
mBarTracker.Waits();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_LONG:
|
|
//
|
|
FillNextBarTime(
|
|
lNextValidSignal,
|
|
lBarTracker //
|
|
);
|
|
lBarTracker.Waits();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_HIND:
|
|
//
|
|
FillNextBarTime(
|
|
hNextValidSignal,
|
|
hBarTracker //
|
|
);
|
|
hBarTracker.Waits();
|
|
break;
|
|
|
|
//
|
|
default:
|
|
case X_MARKET_CYCLE_UNKNOWN:
|
|
//
|
|
FillNextBarTime(
|
|
cNextValidSignal,
|
|
cBarTracker //
|
|
);
|
|
cBarTracker.Waits();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
bool GetConditions(
|
|
X121SetupConditions &conditions, //
|
|
ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN, //
|
|
int barIndex = 0, //
|
|
int loopback = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
switch (cycle)
|
|
{
|
|
//
|
|
case X_MARKET_CYCLE_SHORT:
|
|
//
|
|
result = sCycle.GetConditions(
|
|
conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_MEDIUM:
|
|
//
|
|
result = mCycle.GetConditions(
|
|
conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_LONG:
|
|
//
|
|
result = lCycle.GetConditions(
|
|
conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_HIND:
|
|
//
|
|
result = hCycle.GetConditions(
|
|
conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
break;
|
|
|
|
//
|
|
default:
|
|
case X_MARKET_CYCLE_UNKNOWN:
|
|
//
|
|
result = cCycle.GetConditions(
|
|
conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
break;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XSCZones *GetZones(
|
|
ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN, //
|
|
int barIndex = 0, //
|
|
int numberOfZones = 10 //
|
|
)
|
|
{
|
|
//
|
|
XSCZonesInput zInputs;
|
|
zInputs.numberOfZones = numberOfZones;
|
|
|
|
//
|
|
int length = 0;
|
|
ENUM_TIMEFRAMES zPeriod = NULL;
|
|
switch (cycle)
|
|
{
|
|
//
|
|
case X_MARKET_CYCLE_SHORT:
|
|
//
|
|
zPeriod = sCycle.GetPeriod();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_MEDIUM:
|
|
//
|
|
zPeriod = mCycle.GetPeriod();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_LONG:
|
|
//
|
|
zPeriod = lCycle.GetPeriod();
|
|
break;
|
|
|
|
//
|
|
case X_MARKET_CYCLE_HIND:
|
|
//
|
|
zPeriod = hCycle.GetPeriod();
|
|
break;
|
|
|
|
//
|
|
default:
|
|
case X_MARKET_CYCLE_UNKNOWN:
|
|
//
|
|
zPeriod = cCycle.GetPeriod();
|
|
break;
|
|
}
|
|
|
|
//
|
|
ENUM_TIMEFRAMES cPeriod = GetPeriod();
|
|
length = (PeriodSeconds(zPeriod) / PeriodSeconds(cPeriod)) + 1;
|
|
|
|
//
|
|
zInputs.length = length;
|
|
XSCZones *result = new XSCZones(
|
|
GetSymbol(),
|
|
cPeriod //
|
|
);
|
|
if (!result.Init(zInputs))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool ProcessMarket(
|
|
XSignal &signal,
|
|
X121SetupConditions &conditions,
|
|
int &pushers,
|
|
string &provider,
|
|
ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN,
|
|
bool allowSupports = false, // Allow Support Signal Generating ...
|
|
bool allowLong = false,
|
|
bool allowShort = false,
|
|
double volume = 0.01,
|
|
double slPoint = 100,
|
|
bool ignoreSL = false,
|
|
double tpPoint = 100,
|
|
bool ignoreTP = false,
|
|
int barIndex = 0,
|
|
int loopback = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = CanProcessBar(
|
|
cycle //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = GetConditions(
|
|
conditions,
|
|
cycle, // Current Market ...
|
|
barIndex, // Bar Index ...
|
|
loopback // Loop Back ...
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parse Conditions for Signal ...
|
|
result = signalGenerator.HasSignal(
|
|
conditions,
|
|
signal,
|
|
pushers,
|
|
provider,
|
|
allowSupports,
|
|
allowLong,
|
|
allowShort,
|
|
volume,
|
|
slPoint,
|
|
ignoreSL,
|
|
tpPoint,
|
|
ignoreTP //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
WaitsUntilNextBar(
|
|
cycle //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
X121SetupInputs inputs; // Cycles Configurations
|
|
|
|
//
|
|
// Bar Trackers ...
|
|
XBarTracker cBarTracker;
|
|
XBarTracker sBarTracker;
|
|
XBarTracker mBarTracker;
|
|
XBarTracker lBarTracker;
|
|
XBarTracker hBarTracker;
|
|
|
|
//
|
|
datetime cNextValidSignal;
|
|
datetime sNextValidSignal;
|
|
datetime mNextValidSignal;
|
|
datetime lNextValidSignal;
|
|
datetime hNextValidSignal;
|
|
|
|
//
|
|
void FillNextBarTime(
|
|
datetime &next,
|
|
XBarTracker &tracker)
|
|
{
|
|
//
|
|
next = iTime(
|
|
tracker.symbol,
|
|
tracker.period,
|
|
0) +
|
|
PeriodSeconds(tracker.period);
|
|
}
|
|
|
|
// //
|
|
// bool ProcessCurrentMarket(
|
|
// XSignal &signal,
|
|
// X121SetupConditions &conditions,
|
|
// int &pushers,
|
|
// string &provider,
|
|
// int barIndex = 0,
|
|
// int loopback = 5 //
|
|
// )
|
|
// {
|
|
// //
|
|
// bool result = false;
|
|
|
|
// //
|
|
// return result;
|
|
// }
|
|
};
|
|
|
|
// |