2508 lines
44 KiB
Plaintext
2508 lines
44 KiB
Plaintext
//
|
|
// Structs ...
|
|
|
|
//
|
|
// Model Specified Ticks Info ...
|
|
struct XTick
|
|
{
|
|
//
|
|
string symbol; // Symbol ...
|
|
datetime time; // Time ...
|
|
double bid; // Bid ...
|
|
double ask; // Ask ...
|
|
double spread; // Spread ...
|
|
long volume; // Volume ...
|
|
|
|
//
|
|
// Constructor ...
|
|
void XTick()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools Functions ...
|
|
|
|
/**
|
|
* Initial ...
|
|
*
|
|
* @param _symbol: Symbol ...
|
|
* @param _time: Time ...
|
|
* @param _bid: Bid Price ...
|
|
* @param _ask: Ask Price ...
|
|
* @param _volume: Tick Volume ...
|
|
*/
|
|
bool Init(
|
|
string _symbol,
|
|
datetime _time,
|
|
double _bid,
|
|
double _ask,
|
|
double _spread,
|
|
long _volume //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(_symbol) &&
|
|
IsValid(_time) &&
|
|
_bid > 0 &&
|
|
_ask > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bid = _bid;
|
|
ask = _ask;
|
|
time = _time;
|
|
symbol = _symbol;
|
|
spread = _spread;
|
|
|
|
//
|
|
result = IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Init Tick by Symbol ...
|
|
*
|
|
* @param _symbol: String ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Init(
|
|
string _symbol,
|
|
ENUM_TIMEFRAMES _volumePeriod = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(_symbol);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
datetime _time = TimeCurrent();
|
|
double _bid = GetBid(_symbol);
|
|
double _ask = GetAsk(_symbol);
|
|
double _spread = GetSpread(_symbol);
|
|
|
|
//
|
|
long _volume = 0;
|
|
if (IsValid(_volumePeriod))
|
|
{
|
|
_volume = iTickVolume(_symbol, _volumePeriod, 0);
|
|
}
|
|
|
|
//
|
|
result = Init(
|
|
_symbol,
|
|
_time,
|
|
_bid,
|
|
_ask,
|
|
_spread,
|
|
_volume //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Cleanup ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
bid = 0;
|
|
ask = 0;
|
|
volume = 0;
|
|
time = NULL;
|
|
symbol = NULL;
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Validate ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(symbol) &&
|
|
IsValid(time) &&
|
|
bid > 0 &&
|
|
ask > 0 &&
|
|
volume >= 0;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Model a Market Cycle ...
|
|
struct XMarketCycle
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string prefix; // Prefix Trag ...
|
|
|
|
//
|
|
string symbol; // Market Symbol ...
|
|
|
|
//
|
|
ENUM_TIMEFRAMES period; // Period of Cycle ...
|
|
ENUM_X_PERIOD_METHOD method; // Period Selection Method ...
|
|
ENUM_X_MARKET_CYCLES cycle; // Cycles of MArket ...
|
|
|
|
//
|
|
int length; // Number Of Candles per Current Time Frame ...
|
|
ENUM_TIMEFRAMES hostPeriod; // Current Time Frame ...
|
|
|
|
//
|
|
datetime lastStart; // Last Candle Bar Time ...
|
|
|
|
//
|
|
XBarTracker barTracker; // Bar Tracker ...
|
|
XBarRemainsTime remains; // Current Bar Remains Model ...
|
|
|
|
//
|
|
// Constructor ...
|
|
XMarketCycle()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Init Cycle ...
|
|
bool Init(
|
|
string mSymbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES mHostPeriod, // Host Period
|
|
ENUM_X_MARKET_CYCLES mCycle, // Init Cycle
|
|
string mPrefix = "" // Prefix
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
mSymbol = NormalizeSymbol(mSymbol);
|
|
mHostPeriod = NormalizePeriod(mHostPeriod);
|
|
|
|
//
|
|
result = IsValid(mCycle);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
this.cycle = mCycle;
|
|
|
|
//
|
|
// Set Automatically Prefix ...
|
|
if (StringLen(mPrefix) == 0)
|
|
{
|
|
this.prefix = ToString(cycle);
|
|
}
|
|
|
|
//
|
|
result = IsValid(
|
|
method,
|
|
period //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
this.symbol = mSymbol;
|
|
this.hostPeriod = mHostPeriod;
|
|
|
|
//
|
|
// Find Cycle Period ...
|
|
if (method == X_PERIOD_AUTO)
|
|
{
|
|
//
|
|
// Select Period ...
|
|
this.period = GetCyclePeriod(
|
|
this.cycle,
|
|
this.hostPeriod);
|
|
}
|
|
|
|
//
|
|
// Set Prefix if Provided ...
|
|
if (StringLen(mPrefix) > 0)
|
|
{
|
|
this.prefix = mPrefix;
|
|
}
|
|
|
|
//
|
|
// Calculate Required Info ...
|
|
|
|
//
|
|
// Length ...
|
|
this.length = PeriodSeconds(this.period) / PeriodSeconds(this.hostPeriod);
|
|
|
|
//
|
|
// Update Additional Data ...
|
|
result = this.Update(0);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool Init(
|
|
string mSymbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES mHostPeriod, // Host Period
|
|
ENUM_X_MARKET_CYCLES mCycle, // Init Cycle
|
|
ENUM_X_PERIOD_METHOD mMethod, // Period Selection Method
|
|
ENUM_TIMEFRAMES mPeriod, // Provided Period
|
|
string mPrefix = "" // Prefix
|
|
)
|
|
{
|
|
//
|
|
this.period = mPeriod;
|
|
this.method = mMethod;
|
|
|
|
//
|
|
return Init(
|
|
mSymbol,
|
|
mHostPeriod,
|
|
mCycle,
|
|
mPrefix
|
|
//
|
|
);
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Cleanup ...
|
|
void Clean()
|
|
{
|
|
//
|
|
length = 0;
|
|
lastStart = 0;
|
|
|
|
//
|
|
cycle = NULL;
|
|
prefix = NULL;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
method = NULL;
|
|
hostPeriod = NULL;
|
|
|
|
//
|
|
remains.Clean();
|
|
barTracker.Clean();
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
//
|
|
// Check Structure Valid ...
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(
|
|
method,
|
|
period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
length > 0 &&
|
|
symbol != NULL &&
|
|
period != NULL &&
|
|
method != NULL &&
|
|
hostPeriod != NULL &&
|
|
method != X_PERIOD_NONE
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Update Market Cycle Additional Info ...
|
|
bool Update(int hostBarIndex)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = this.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Init Remains ...
|
|
result = remains.Init(
|
|
this.symbol,
|
|
this.period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Init Bar Tracker ...
|
|
result = barTracker.Init(
|
|
this.symbol,
|
|
this.period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Count Bars ...
|
|
int CountBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = barTracker.CountBars();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check New Bar ...
|
|
bool IsNewBar()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = barTracker.IsNewBar();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Current Bar Index based on Host Period bar Index ...
|
|
int GetBarIndex(int barIndex)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int totalBars = CountBars();
|
|
if (barIndex >= totalBars)
|
|
{
|
|
//
|
|
result = totalBars - 1;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
datetime hostBarTime = iTime(
|
|
this.symbol,
|
|
this.hostPeriod,
|
|
barIndex
|
|
//
|
|
);
|
|
|
|
//
|
|
result = iBarShift(
|
|
this.symbol,
|
|
this.period,
|
|
hostBarTime
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Current Cycles Specific Bar ...
|
|
XOHCL GetBar(int barIndex)
|
|
{
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int totalBars = CountBars();
|
|
if (barIndex >= totalBars)
|
|
{
|
|
barIndex = totalBars - 1;
|
|
}
|
|
|
|
//
|
|
XOHCL result;
|
|
result.Init(
|
|
this.symbol,
|
|
this.period,
|
|
barIndex
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Specific Range of Bars ...
|
|
// using Start Bar Index ...
|
|
int GetBars(
|
|
XOHCL &result[], // Hold Result
|
|
int from = 0, // Start Bar Index
|
|
int count = 1, // Number of Bars
|
|
bool forceClean = true // Clean Result Array
|
|
)
|
|
{
|
|
//
|
|
int mResult = 0;
|
|
|
|
//
|
|
if (from < 0)
|
|
{
|
|
from = 0;
|
|
}
|
|
|
|
//
|
|
int total = Bars(
|
|
symbol,
|
|
period);
|
|
if (from > total - 2)
|
|
{
|
|
from = total - 2;
|
|
}
|
|
|
|
//
|
|
if (count < 0)
|
|
{
|
|
count = 1;
|
|
}
|
|
|
|
//
|
|
int start = from;
|
|
int end = start + count;
|
|
if (end > total - 1)
|
|
{
|
|
end = total - 1;
|
|
}
|
|
|
|
//
|
|
if (forceClean)
|
|
{
|
|
Clean(result);
|
|
}
|
|
|
|
//
|
|
int beforeSize = ArraySize(result);
|
|
|
|
//
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
XOHCL iBar;
|
|
bool isValid = iBar.Init(
|
|
symbol,
|
|
period,
|
|
i
|
|
//
|
|
);
|
|
|
|
//
|
|
if (isValid)
|
|
{
|
|
//
|
|
AddRef(
|
|
iBar,
|
|
result
|
|
//
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
int afterSize = ArraySize(result);
|
|
|
|
//
|
|
mResult = afterSize - beforeSize;
|
|
|
|
//
|
|
return mResult;
|
|
}
|
|
|
|
//
|
|
// Extract Specific Range of Bars ...
|
|
// using Start Bar Time ...
|
|
int GetBars(
|
|
XOHCL &bars[], // Hold Result
|
|
datetime from = NULL, // Start Bar Time
|
|
int count = 1 // Number of Bars
|
|
)
|
|
{
|
|
//
|
|
from = NormalizeTime(from);
|
|
|
|
//
|
|
return GetBars(
|
|
bars,
|
|
symbol,
|
|
period,
|
|
from,
|
|
count //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Retrieve Bar Time ...
|
|
datetime GetBarTime(int barIndex)
|
|
{
|
|
//
|
|
datetime result = NULL;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int totalBars = CountBars();
|
|
if (barIndex >= totalBars)
|
|
{
|
|
barIndex = totalBars - 1;
|
|
}
|
|
|
|
//
|
|
result = iTime(
|
|
this.symbol,
|
|
this.period,
|
|
barIndex
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Chart ID ...
|
|
ulong GetChartID()
|
|
{
|
|
//
|
|
ulong result = 0;
|
|
|
|
//
|
|
long firstChart = ChartFirst();
|
|
result = firstChart;
|
|
|
|
//
|
|
while (result >= 0)
|
|
{
|
|
//
|
|
string chSymbol = ChartSymbol(result);
|
|
ENUM_TIMEFRAMES chPeriod = ChartPeriod(result);
|
|
|
|
//
|
|
bool isOwnChart =
|
|
//
|
|
symbol == chSymbol &&
|
|
period == chPeriod
|
|
//
|
|
;
|
|
if (isOwnChart)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = ChartNext(result);
|
|
if (result < 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Create and String Representation for Unique Taging ...
|
|
string ToString()
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
GetTypeName(this) + "(" +
|
|
"PRFX(" + this.prefix + ")" +
|
|
"SMBL(" + this.symbol + ")" +
|
|
"CYC(" + ToString(this.cycle) + ")" +
|
|
"PRD(" + ToString(this.period) + ")" +
|
|
"PRDHST(" + ToString(this.hostPeriod) + ")" +
|
|
"MTH(" + EnumToString(this.method) + ")" +
|
|
")";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Here we Produce a Summary brief of
|
|
// state of Cycle ...
|
|
string GenerateSummary()
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
bool hasPrefix =
|
|
StringLen(this.prefix) > 0 &&
|
|
this.prefix != ToString(this.cycle);
|
|
result += (hasPrefix ? this.prefix + "[" : "") +
|
|
ToString(this.cycle) +
|
|
(hasPrefix ? "]" : "") + "\n";
|
|
|
|
//
|
|
result += " - PR: " + ToString(this.period) + "\n";
|
|
|
|
//
|
|
XOHCL cBar = GetBar(0);
|
|
|
|
//
|
|
result += " - State: " + (cBar.IsBullish() ? "Bullish" : cBar.IsBearish() ? "Bearish"
|
|
: "Neutural");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Linear Regression ...
|
|
|
|
//
|
|
struct XLinearRegressionWorkStruct
|
|
{
|
|
//
|
|
struct sDataStruct
|
|
{
|
|
//
|
|
double value;
|
|
double sumY;
|
|
double sumXY;
|
|
};
|
|
|
|
//
|
|
sDataStruct data[];
|
|
|
|
//
|
|
int dataSize;
|
|
int period;
|
|
double sumX;
|
|
double sumXX;
|
|
double divisor;
|
|
|
|
//
|
|
// Constructor ...
|
|
XLinearRegressionWorkStruct()
|
|
: dataSize(-1), period(-1)
|
|
{
|
|
}
|
|
};
|
|
|
|
//
|
|
struct XLinearRegression
|
|
{
|
|
//
|
|
XLinearRegressionWorkStruct m_work;
|
|
|
|
//
|
|
// Calculate Linear Regression ...
|
|
double Calculate(
|
|
double value,
|
|
int period,
|
|
double &_slope,
|
|
double &_intercept,
|
|
int r,
|
|
int bars //
|
|
)
|
|
{
|
|
//
|
|
if (m_work.dataSize <= bars)
|
|
{
|
|
m_work.dataSize = ArrayResize(m_work.data, bars + 500, 2000);
|
|
}
|
|
|
|
//
|
|
if (period < 1)
|
|
{
|
|
period = 1;
|
|
}
|
|
|
|
//
|
|
if (m_work.period != (int)period)
|
|
{
|
|
//
|
|
m_work.period = (int)period;
|
|
m_work.sumX = m_work.period * (m_work.period - 1.0) / 2.0;
|
|
m_work.sumXX = m_work.period * (m_work.period - 1.0) * (2.0 * m_work.period - 1.0) / 6.0;
|
|
m_work.divisor = m_work.sumX * m_work.sumX - m_work.period * m_work.sumXX;
|
|
|
|
//
|
|
if (m_work.divisor)
|
|
{
|
|
m_work.divisor = 1.0 / m_work.divisor;
|
|
}
|
|
}
|
|
|
|
//
|
|
m_work.data[r].value = value;
|
|
|
|
//
|
|
if (r >= m_work.period)
|
|
{
|
|
//
|
|
m_work.data[r].sumY = m_work.data[r - 1].sumY + value - m_work.data[r - m_work.period].value;
|
|
m_work.data[r].sumXY = m_work.data[r - 1].sumXY + m_work.data[r].sumY - m_work.data[r - m_work.period].value * (m_work.period - 1.0) - value;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
m_work.data[r].sumY = value;
|
|
m_work.data[r].sumXY = 0;
|
|
|
|
//
|
|
for (int _k = 1; _k < m_work.period && r >= _k; _k++)
|
|
{
|
|
//
|
|
m_work.data[r].sumY += m_work.data[r - _k].value;
|
|
m_work.data[r].sumXY += _k * m_work.data[r - _k].value;
|
|
}
|
|
}
|
|
|
|
//
|
|
_slope = (m_work.period * m_work.data[r].sumXY - m_work.sumX * m_work.data[r].sumY) * m_work.divisor;
|
|
_intercept = (m_work.data[r].sumY - _slope * m_work.sumX) / (double)m_work.period;
|
|
|
|
//
|
|
double result = (_intercept + _slope * (m_work.period - 1.0));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Use To Parse Symbols for
|
|
// Ignore Brokers Additional Suffixes ...
|
|
struct XSymbolParser
|
|
{
|
|
//
|
|
string version; // Temp ...
|
|
|
|
//
|
|
// Symbol Parsing ...
|
|
|
|
//
|
|
// Forext ...
|
|
|
|
//
|
|
bool IsEURUSD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"EUR",
|
|
"USD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsUSDJPY(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"USD",
|
|
"JPY" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsEURJPY(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"EUR",
|
|
"JPY" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsUSDCHF(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"USD",
|
|
"CHF" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsEURCHF(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"EUR",
|
|
"CHF" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsGBPUSD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"GBP",
|
|
"USD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsEURGBP(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"EUR",
|
|
"GBP" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsAUDUSD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"AUD",
|
|
"USD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsEURAUD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"EUR",
|
|
"AUD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsUSDCAD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"USD",
|
|
"CAD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsEURCAD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"EUR",
|
|
"CAD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsNZDUSD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"NZD",
|
|
"USD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsEURNZD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"EUR",
|
|
"NZD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Metals ...
|
|
|
|
//
|
|
bool IsXAUUSD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"XAU",
|
|
"USD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsXAGUSD(string symbol)
|
|
{
|
|
//
|
|
string symbolIdentifiers[] = {
|
|
"XAG",
|
|
"USD" //
|
|
};
|
|
|
|
//
|
|
bool result = Contains(
|
|
symbolIdentifiers,
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Indexes ...
|
|
|
|
//
|
|
bool IsDowJones(string symbol)
|
|
{
|
|
//
|
|
bool result = Contains(
|
|
"DowJones30",
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Oil ...
|
|
|
|
//
|
|
bool IsBrent(string symbol)
|
|
{
|
|
//
|
|
bool result = Contains(
|
|
"BRENT",
|
|
symbol //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Symbol Finder ...
|
|
string GetEURUSDSymbol()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
string symbols[];
|
|
int symbolsCount = GetAllSymbols(
|
|
symbols //
|
|
);
|
|
if (!IsValidSize(symbolsCount))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < symbolsCount; i++)
|
|
{
|
|
//
|
|
string iSymbol = symbols[i];
|
|
if (IsEURUSD(iSymbol))
|
|
{
|
|
//
|
|
result = iSymbol;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
struct XSymbolSessionParser
|
|
{
|
|
//
|
|
string version; // Temp ...
|
|
|
|
//
|
|
// Check Market Is Open for Specific Symbol
|
|
// in Current Time ...
|
|
bool CanTrade(
|
|
string symbol // Trading Symbol
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(symbol);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
MqlDateTime timeStruct;
|
|
result = TimeCurrent(timeStruct);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ENUM_DAY_OF_WEEK dayOfWeek = (ENUM_DAY_OF_WEEK)timeStruct.day_of_week;
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
datetime from;
|
|
datetime to;
|
|
result = SymbolInfoSessionTrade(
|
|
symbol,
|
|
dayOfWeek,
|
|
0, // Session Index ...
|
|
from,
|
|
to //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = cTime > from && cTime < to;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Parsing Market Names ...
|
|
struct XMarketParser
|
|
{
|
|
//
|
|
string _version; // Temp ...
|
|
|
|
//
|
|
bool IsIngot(string market)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// result = IsValid(market) &&
|
|
// market == "";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsErrante(string market)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// result = IsValid(market) &&
|
|
// market == "";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsAMarkets(string market)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid(market) &&
|
|
market == "AMarkets LLC";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsIFCMarkets(string market)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// result = IsValid(market) &&
|
|
// market == "";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsOtetMarkets(string market)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// result = IsValid(market) &&
|
|
// market == "";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
struct XPoint
|
|
{
|
|
//
|
|
// Props ...
|
|
double value;
|
|
datetime at;
|
|
|
|
//
|
|
XPoint()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
void Clean()
|
|
{
|
|
//
|
|
value = 0;
|
|
at = NULL;
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
//
|
|
bool IsValid()
|
|
{
|
|
//
|
|
return value > 0 &&
|
|
IsValid(at);
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
// Specified Swing Point ...
|
|
struct XSwingPoint
|
|
{
|
|
//
|
|
// Props ...
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
double swing;
|
|
datetime time;
|
|
ENUM_X_SWING_TYPE type;
|
|
|
|
//
|
|
// Constructor ...
|
|
XSwingPoint()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleanup Model ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
swing = 0;
|
|
time = NULL;
|
|
|
|
//
|
|
symbol = NULL;
|
|
period = NULL;
|
|
|
|
//
|
|
type = X_NO_SWING;
|
|
}
|
|
|
|
/**
|
|
* Validate Model ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
swing > 0 &&
|
|
IsValid(time) &&
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
type != X_NO_SWING;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Swing is Low or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSwingLow()
|
|
{
|
|
return type == X_SWING_LOW;
|
|
}
|
|
|
|
/**
|
|
* Check Swing is High or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSwingHigh()
|
|
{
|
|
return type == X_SWING_HIGH;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Consolidation Zone ...
|
|
struct XConsolidationZone
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
string symbol; // Symbol ...
|
|
ENUM_TIMEFRAMES period; // Period ...
|
|
|
|
//
|
|
double upper; // Upper ...
|
|
double lower; // Lower ...
|
|
|
|
//
|
|
datetime from; // Start Date
|
|
datetime to; // Breake Date
|
|
|
|
//
|
|
ENUM_X_DIRECTION dir; // Break Direction ...
|
|
|
|
//
|
|
// Constructor ...
|
|
XConsolidationZone()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleanup ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
upper = 0;
|
|
lower = 0;
|
|
|
|
//
|
|
to = NULL;
|
|
from = NULL;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Validate ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
upper > 0 &&
|
|
lower > 0 &&
|
|
IsValid(to) &&
|
|
IsValid(from) &&
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
HasDirection(dir)
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsSameAs(
|
|
XConsolidationZone &item //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid() &&
|
|
item.IsValid() &&
|
|
dir == item.dir &&
|
|
from == item.from &&
|
|
upper == item.upper &&
|
|
lower == item.lower &&
|
|
symbol == item.symbol &&
|
|
period == item.period;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Unique Identifier ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetTag()
|
|
{
|
|
//
|
|
string result =
|
|
//
|
|
"XCZONE" + "_" +
|
|
ToString(dir) + "_" +
|
|
symbol + "_" +
|
|
ToString(period) + "_" +
|
|
ToString(upper) + "_" +
|
|
ToString(lower)
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
class XCRRObject : public XCBaseObject
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
|
|
/**
|
|
* Creator ...
|
|
*
|
|
* @param chart_id: Long, Specified Chart ID ...
|
|
* @param window: Integer, Specified Chart Window ID ...
|
|
* @param rr: XRR instance Reference ...
|
|
* @param prefix: String ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Create(
|
|
long chart_id,
|
|
int window,
|
|
XRR &rr,
|
|
string prefix = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = rr.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string name = rr.GetTag();
|
|
if (IsValid(prefix))
|
|
{
|
|
name = prefix + "_" + name;
|
|
}
|
|
string nameMD5 = ToMD5(name);
|
|
|
|
//
|
|
bool isLong = IsLong(rr.type);
|
|
|
|
//
|
|
double price1 = rr.entry;
|
|
double price2 = rr.sl;
|
|
|
|
//
|
|
datetime time1 = rr.time;
|
|
datetime time2 = (datetime)((int)rr.time + 5 * PeriodSeconds(rr.period));
|
|
|
|
//
|
|
result = mFibo.Create(
|
|
chart_id,
|
|
name,
|
|
window,
|
|
time1,
|
|
price1,
|
|
time2,
|
|
price2 //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mRR = rr;
|
|
ObjName(name);
|
|
|
|
//
|
|
int tpsCount = ArraySize(rr.tps);
|
|
int levels = tpsCount + 2;
|
|
result = mFibo.LevelsCount(levels);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Set Fibo Levels ...
|
|
|
|
//
|
|
result = mFibo.LevelValue(0, 0);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
result = mFibo.LevelDescription(0, "SL");
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = mFibo.LevelValue(1, 1.0);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
result = mFibo.LevelDescription(1, "Entry");
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < tpsCount; i++)
|
|
{
|
|
//
|
|
int idx = i + 2;
|
|
double level = 1.0 + rr.tps[i];
|
|
string description = "TP " + ToString(rr.tps[i]);
|
|
|
|
//
|
|
result = mFibo.LevelValue(
|
|
idx,
|
|
level //
|
|
);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = mFibo.LevelDescription(
|
|
idx,
|
|
description //
|
|
);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Getter(s) / Setter(s) ...
|
|
|
|
//
|
|
// Virtual ...
|
|
|
|
/**
|
|
* Retrieve Object Type ...
|
|
*
|
|
* @return ( ENUM_XCHARTOBJECTS )
|
|
*/
|
|
virtual ENUM_XCHARTOBJECTS Type()
|
|
{
|
|
return X_RR_OBJ;
|
|
}
|
|
|
|
//
|
|
private:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
XRR mRR;
|
|
CChartObjectFibo mFibo;
|
|
|
|
//
|
|
bool SetSLProps(
|
|
int width = 1,
|
|
color clr = clrRed,
|
|
ENUM_LINE_STYLE style = STYLE_SOLID,
|
|
string description = "" //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = SetLevelProps(
|
|
0,
|
|
width,
|
|
clr,
|
|
style,
|
|
description //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool SetEntryProps(
|
|
int width = 1,
|
|
color clr = clrOrange,
|
|
ENUM_LINE_STYLE style = STYLE_SOLID,
|
|
string description = "" //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = SetLevelProps(
|
|
0,
|
|
width,
|
|
clr,
|
|
style,
|
|
description //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool SetTPProps(
|
|
double tpValue,
|
|
int width = 1,
|
|
color clr = clrLime,
|
|
ENUM_LINE_STYLE style = STYLE_SOLID,
|
|
string description = "" //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int tpIDX = FindIndex(
|
|
tpValue,
|
|
mRR.tps //
|
|
);
|
|
result = IsValidIndex(tpIDX);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
tpIDX += 2;
|
|
|
|
//
|
|
result = SetLevelProps(
|
|
tpIDX,
|
|
width,
|
|
clr,
|
|
style,
|
|
description //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool SetLevelProps(
|
|
int id,
|
|
int width = 1,
|
|
color clr = clrYellow,
|
|
ENUM_LINE_STYLE style = STYLE_SOLID,
|
|
string description = "" //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Color ...
|
|
result = mFibo.LevelColor(
|
|
id,
|
|
clr //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Style ...
|
|
result = mFibo.LevelStyle(
|
|
id,
|
|
style //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Width ...
|
|
if (width > 0)
|
|
{
|
|
//
|
|
result = mFibo.LevelWidth(
|
|
id,
|
|
width //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Description ...
|
|
if (IsValid(description))
|
|
{
|
|
//
|
|
result = mFibo.LevelDescription(
|
|
id,
|
|
description //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
class XCTrendObject : public XCBaseObject
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
|
|
/**
|
|
* Creator ...
|
|
*
|
|
* @param chart_id: Long, Specified Chart ID ...
|
|
* @param window: Integer, Specified Chart Window ID ...
|
|
* @param rr: XRR instance Reference ...
|
|
* @param prefix: String ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Create(
|
|
long chart_id,
|
|
int window,
|
|
XPoint &swings[],
|
|
bool useMinAsStart = true,
|
|
string prefix = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int count = ArraySize(swings);
|
|
result =
|
|
count >= 2 &&
|
|
IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double min = 0;
|
|
datetime minAt = NULL;
|
|
|
|
//
|
|
double max = 0;
|
|
datetime maxAt = NULL;
|
|
|
|
//
|
|
// Etract Min/Max ...
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XPoint iPoint = swings[i];
|
|
|
|
//
|
|
if (!iPoint.IsValid())
|
|
{
|
|
//
|
|
iPoint.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
bool canSetMin =
|
|
min == 0
|
|
? true
|
|
: min > iPoint.value;
|
|
if (canSetMin)
|
|
{
|
|
//
|
|
minAt = iPoint.at;
|
|
min = iPoint.value;
|
|
}
|
|
|
|
//
|
|
bool canSetMax =
|
|
max == 0
|
|
? true
|
|
: max < iPoint.value;
|
|
if (canSetMax)
|
|
{
|
|
//
|
|
maxAt = iPoint.at;
|
|
max = iPoint.value;
|
|
}
|
|
|
|
//
|
|
iPoint.Clean();
|
|
}
|
|
|
|
//
|
|
double first =
|
|
useMinAsStart
|
|
? min
|
|
: max;
|
|
datetime firstTime =
|
|
useMinAsStart
|
|
? minAt
|
|
: maxAt;
|
|
|
|
//
|
|
double second =
|
|
useMinAsStart
|
|
? max
|
|
: min;
|
|
datetime secondTime =
|
|
useMinAsStart
|
|
? maxAt
|
|
: minAt;
|
|
|
|
//
|
|
// Validate Points ...
|
|
result =
|
|
//
|
|
first > 0 &&
|
|
second > 0 &&
|
|
(useMinAsStart
|
|
? first <= second
|
|
: first >= second) &&
|
|
IsSpecifiedValid(firstTime) &&
|
|
IsSpecifiedValid(secondTime)
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ENUM_X_DIRECTION dir =
|
|
useMinAsStart
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
string name = "XTRND" + ToString(dir) + "_" + ToString(first) + "_" + ToString(second);
|
|
if (IsValid(prefix))
|
|
{
|
|
name = prefix + "_" + name;
|
|
}
|
|
string nameMD5 = ToMD5(name);
|
|
|
|
//
|
|
result = mTrend.Create(
|
|
chart_id,
|
|
name,
|
|
window,
|
|
firstTime,
|
|
first,
|
|
secondTime,
|
|
second //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ObjName(name);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creator ...
|
|
*
|
|
* @param chart_id: Long, Specified Chart ID ...
|
|
* @param window: Integer, Specified Chart Window ID ...
|
|
* @param rr: XRR instance Reference ...
|
|
* @param prefix: String ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Create(
|
|
long chart_id,
|
|
int window,
|
|
XSwingPoint &swings[],
|
|
string prefix = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int count = ArraySize(swings);
|
|
result =
|
|
count >= 2 &&
|
|
IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ENUM_X_SWING_TYPE type = swings[0].type;
|
|
bool isSwingLows = type == X_SWING_LOW;
|
|
|
|
//
|
|
double values[];
|
|
int valuesCount = ExtractSwings(
|
|
swings,
|
|
values //
|
|
);
|
|
result = valuesCount == count;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int firstIDX = -1;
|
|
double first = 0;
|
|
datetime firstTime = NULL;
|
|
|
|
//
|
|
int secondIDX = -1;
|
|
double second = 0;
|
|
datetime secondTime = NULL;
|
|
|
|
//
|
|
if (isSwingLows)
|
|
{
|
|
//
|
|
first = GetMin(
|
|
values,
|
|
firstIDX,
|
|
0,
|
|
0 //
|
|
);
|
|
if (IsValidIndex(firstIDX))
|
|
{
|
|
//
|
|
firstTime = swings[firstIDX].time;
|
|
|
|
//
|
|
second = FindBiggerThan(
|
|
first,
|
|
values,
|
|
true //
|
|
);
|
|
secondIDX = FindIndex(
|
|
second,
|
|
values //
|
|
);
|
|
if (IsValidIndex(secondIDX))
|
|
{
|
|
secondTime = swings[secondIDX].time;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
first = GetMax(
|
|
values,
|
|
firstIDX,
|
|
0,
|
|
0 //
|
|
);
|
|
if (IsValidIndex(firstIDX))
|
|
{
|
|
//
|
|
firstTime = swings[firstIDX].time;
|
|
|
|
//
|
|
second = FindLesserThan(
|
|
first,
|
|
values,
|
|
true //
|
|
);
|
|
secondIDX = FindIndex(
|
|
second,
|
|
values //
|
|
);
|
|
if (IsValidIndex(secondIDX))
|
|
{
|
|
secondTime = swings[secondIDX].time;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validate Points ...
|
|
result =
|
|
//
|
|
IsValidIndex(firstIDX) &&
|
|
IsValidIndex(secondIDX) &&
|
|
//
|
|
IsSpecifiedValid(firstTime) &&
|
|
IsSpecifiedValid(secondTime) &&
|
|
//
|
|
(isSwingLows
|
|
? first < second
|
|
: first > second)
|
|
//
|
|
;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string name = ToString(type) + "_" + ToString(first) + "_" + ToString(second);
|
|
if (IsValid(prefix))
|
|
{
|
|
name = prefix + "_" + name;
|
|
}
|
|
string nameMD5 = ToMD5(name);
|
|
|
|
//
|
|
result = mTrend.Create(
|
|
chart_id,
|
|
name,
|
|
window,
|
|
firstTime,
|
|
first,
|
|
secondTime,
|
|
second //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ObjName(name);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Getter(s) / Setter(s) ...
|
|
|
|
/**
|
|
* Set Trend Color ...
|
|
*
|
|
* @param value: Color ...
|
|
*/
|
|
void TrendColor(color value)
|
|
{
|
|
mTrend.Color(value);
|
|
}
|
|
|
|
void TrendRayLeft(bool value)
|
|
{
|
|
mTrend.RayLeft(value);
|
|
}
|
|
|
|
void TrendRayRight(bool value)
|
|
{
|
|
mTrend.RayRight(value);
|
|
}
|
|
|
|
//
|
|
// Virtual ...
|
|
|
|
/**
|
|
* Retrieve Object Type ...
|
|
*
|
|
* @return ( ENUM_XCHARTOBJECTS )
|
|
*/
|
|
virtual ENUM_XCHARTOBJECTS Type()
|
|
{
|
|
return X_TREND_OBJ;
|
|
}
|
|
|
|
//
|
|
private:
|
|
//
|
|
|
|
//
|
|
// Props ...
|
|
CChartObjectTrend mTrend;
|
|
};
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
/**
|
|
* Create Trend Line Object ...
|
|
*
|
|
* @param swings: XSwingPoint instance Collection ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool CreateTrend(
|
|
XSwingPoint &swings[],
|
|
XCTrendObject *&object //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
object = NULL;
|
|
|
|
//
|
|
result = ArraySize(swings) >= 2 &&
|
|
IsValidSize(ArraySize(swings));
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string prefix = Prefix();
|
|
long chartID = ChartIdentification();
|
|
int window = SubWindowIdentification();
|
|
|
|
//
|
|
object = new XCTrendObject();
|
|
result = object.Create(
|
|
chartID,
|
|
window,
|
|
swings,
|
|
prefix //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
color clrTrend = swings[0].type == X_SWING_LOW
|
|
? SwingLowColor()
|
|
: SwingHighColor();
|
|
object.TrendColor(clrTrend);
|
|
object.TrendRayRight(true);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Create Trend Line Object ...
|
|
*
|
|
* @param swings: XSwingPoint instance Collection ...
|
|
* @param useMinAsStart: Specified Min Value as Start ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool CreateTrend(
|
|
XPoint &swings[],
|
|
XCTrendObject *&object,
|
|
bool useMinAsStart = true //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
object = NULL;
|
|
|
|
//
|
|
result = ArraySize(swings) >= 2 &&
|
|
IsValidSize(ArraySize(swings));
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string prefix = Prefix();
|
|
long chartID = ChartIdentification();
|
|
int window = SubWindowIdentification();
|
|
|
|
//
|
|
object = new XCTrendObject();
|
|
result = object.Create(
|
|
chartID,
|
|
window,
|
|
swings,
|
|
useMinAsStart,
|
|
prefix //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
color clrTrend = useMinAsStart
|
|
? SwingLowColor()
|
|
: SwingHighColor();
|
|
object.TrendColor(clrTrend);
|
|
object.TrendRayRight(true);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Create Specific Risk Reward (RR) on Chart ...
|
|
*
|
|
* @param rr: XRR instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool CreateRR(
|
|
XRR &rr,
|
|
XCRRObject *&object //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
object = NULL;
|
|
|
|
//
|
|
result = rr.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
string prefix = Prefix();
|
|
long chartID = ChartIdentification();
|
|
int window = SubWindowIdentification();
|
|
|
|
//
|
|
object = new XCRRObject();
|
|
result = object.Create(
|
|
chartID,
|
|
window,
|
|
rr,
|
|
prefix //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
// |