1352 lines
22 KiB
Plaintext
1352 lines
22 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Common Library
|
|
// --------------------------------------
|
|
// Name: XOHCLLib
|
|
// Description: provide all commonly used functions ...
|
|
//
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// Describe an Specific Candle ...
|
|
struct XOHCL
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
double high;
|
|
double open;
|
|
double close;
|
|
double low;
|
|
|
|
//
|
|
string symbol;
|
|
datetime time;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
// Constructor ...
|
|
XOHCL()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Init a Bar ...
|
|
// Using Bar Index ...
|
|
bool Init(
|
|
string mSymbol = NULL, // Trading Symbol
|
|
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
|
|
int barIndex = 0 // Bar Index
|
|
)
|
|
{
|
|
//
|
|
mSymbol = NormalizeSymbol(mSymbol);
|
|
mPeriod = NormalizePeriod(mPeriod);
|
|
|
|
//
|
|
symbol = mSymbol;
|
|
period = mPeriod;
|
|
|
|
//
|
|
time = iTime(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
open = iOpen(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
open = NormalizePrice(open, mSymbol);
|
|
|
|
//
|
|
close = iClose(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
close = NormalizePrice(close, mSymbol);
|
|
|
|
//
|
|
high = iHigh(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
high = NormalizePrice(high, mSymbol);
|
|
|
|
//
|
|
low = iLow(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
low = NormalizePrice(low, mSymbol);
|
|
|
|
//
|
|
bool result = IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Init a Bar ...
|
|
// Using Bar Time ...
|
|
bool Init(
|
|
string mSymbol = NULL, // Trading Symbol
|
|
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
|
|
datetime mTime = NULL // Bar Time
|
|
)
|
|
{
|
|
//
|
|
mTime = NormalizeTime(mTime);
|
|
|
|
//
|
|
int barIndex = iBarShift(
|
|
mSymbol,
|
|
mPeriod,
|
|
mTime,
|
|
false //
|
|
);
|
|
|
|
//
|
|
bool result = Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool Init(
|
|
string mSymbol = NULL, // Trading Symbol
|
|
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
|
|
double mOpen = 0, // Open
|
|
double mHigh = 0, // High
|
|
double mClose = 0, // Close
|
|
double mLow = 0, // Low
|
|
int barIndex = 0 // Bar Index
|
|
)
|
|
{
|
|
//
|
|
mSymbol = NormalizeSymbol(mSymbol);
|
|
mPeriod = NormalizePeriod(mPeriod);
|
|
|
|
//
|
|
symbol = mSymbol;
|
|
period = mPeriod;
|
|
|
|
//
|
|
time = iTime(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex
|
|
//
|
|
);
|
|
|
|
//
|
|
open = mOpen;
|
|
high = mHigh;
|
|
close = mClose;
|
|
low = mLow;
|
|
|
|
//
|
|
return IsValid();
|
|
}
|
|
|
|
//
|
|
bool Init(
|
|
string mSymbol = NULL, // Trading Symbol
|
|
ENUM_TIMEFRAMES mPeriod = NULL, // Trading Period
|
|
double mOpen = 0, // Open
|
|
double mHigh = 0, // High
|
|
double mClose = 0, // Close
|
|
double mLow = 0, // Low
|
|
datetime mTime = NULL // Bar Time
|
|
)
|
|
{
|
|
//
|
|
mSymbol = NormalizeSymbol(mSymbol);
|
|
mPeriod = NormalizePeriod(mPeriod);
|
|
|
|
//
|
|
symbol = mSymbol;
|
|
period = mPeriod;
|
|
|
|
//
|
|
int barIndex = iBarShift(
|
|
symbol,
|
|
period,
|
|
mTime);
|
|
|
|
//
|
|
time = iTime(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex
|
|
//
|
|
);
|
|
|
|
//
|
|
open = mOpen;
|
|
high = mHigh;
|
|
close = mClose;
|
|
low = mLow;
|
|
|
|
//
|
|
return IsValid();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
void Clean()
|
|
{
|
|
//
|
|
high = 0;
|
|
open = 0;
|
|
close = 0;
|
|
low = 0;
|
|
|
|
//
|
|
time = NULL;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
//
|
|
// Validate Bar ...
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
high > 0 &&
|
|
open > 0 &&
|
|
close > 0 &&
|
|
low > 0
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int TotalBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
result = iBars(
|
|
symbol,
|
|
period //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate X_PRICE Specified Type ...
|
|
double GetPrice(ENUM_X_PRICE mPType)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
switch (mPType)
|
|
{
|
|
//
|
|
case X_PRICE_OPEN:
|
|
result = open;
|
|
break;
|
|
//
|
|
case X_PRICE_HIGH:
|
|
result = high;
|
|
break;
|
|
//
|
|
case X_PRICE_CLOSE:
|
|
result = close;
|
|
break;
|
|
//
|
|
case X_PRICE_LOW:
|
|
result = low;
|
|
break;
|
|
//
|
|
case X_PRICE_UP:
|
|
result = GetUp();
|
|
break;
|
|
//
|
|
case X_PRICE_DOWN:
|
|
result = GetDown();
|
|
break;
|
|
}
|
|
// case PRICE_MEDIAN:
|
|
// return ((high[i] + low[i]) / 2.0);
|
|
// case PRICE_TYPICAL:
|
|
// return ((high[i] + low[i] + close[i]) / 3.0);
|
|
// case PRICE_WEIGHTED:
|
|
// return ((high[i] + low[i] + close[i] + close[i]) / 4.0);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Price base On Series Mode ...
|
|
double GetPrice(ENUM_SERIESMODE mMode)
|
|
{
|
|
//
|
|
ENUM_X_PRICE mXMode = ToPrice(mMode);
|
|
|
|
//
|
|
return GetPrice(mXMode);
|
|
}
|
|
|
|
//
|
|
// Calculate Applied Price ...
|
|
double GetPrice(
|
|
ENUM_APPLIED_PRICE mAppliedTo // Select Application Method
|
|
)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
// Calculate Applied Price ...
|
|
switch (mAppliedTo)
|
|
{
|
|
//
|
|
case PRICE_CLOSE:
|
|
result = close;
|
|
break;
|
|
|
|
//
|
|
case PRICE_OPEN:
|
|
result = open;
|
|
break;
|
|
|
|
//
|
|
case PRICE_HIGH:
|
|
result = high;
|
|
break;
|
|
|
|
//
|
|
case PRICE_LOW:
|
|
result = low;
|
|
break;
|
|
|
|
//
|
|
case PRICE_MEDIAN:
|
|
result = (high + low) / 2;
|
|
break;
|
|
|
|
//
|
|
case PRICE_TYPICAL:
|
|
result = (high + low + close) / 3;
|
|
break;
|
|
|
|
//
|
|
case PRICE_WEIGHTED:
|
|
result = (high + low + close + close) / 4;
|
|
break;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Specific Price ...
|
|
bool FindHigherPriceBar(
|
|
XOHCL &bar,
|
|
double price,
|
|
ENUM_X_PRICE _type = X_PRICE_HIGH //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int totalBars = TotalBars();
|
|
result = IsValidSize(totalBars);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int start = Index();
|
|
int maxAllowedLoopback = totalBars / 5;
|
|
for (int i = start; i < maxAllowedLoopback; i++)
|
|
{
|
|
//
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
i //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
double iPrice = bar.GetPrice(_type);
|
|
|
|
//
|
|
result =
|
|
//
|
|
iPrice > 0 &&
|
|
iPrice > price
|
|
//
|
|
;
|
|
if (result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
bar.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Specific Price ...
|
|
bool FindLowerPriceBar(
|
|
XOHCL &bar,
|
|
double price,
|
|
ENUM_X_PRICE _type = X_PRICE_HIGH //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int totalBars = TotalBars();
|
|
result = IsValidSize(totalBars);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int start = Index();
|
|
int maxAllowedLoopback = totalBars / 5;
|
|
for (int i = start; i < maxAllowedLoopback; i++)
|
|
{
|
|
//
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
i //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
double iPrice = bar.GetPrice(_type);
|
|
|
|
//
|
|
result =
|
|
//
|
|
iPrice > 0 &&
|
|
iPrice < price
|
|
//
|
|
;
|
|
if (result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
bar.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Bar Mid Line ...
|
|
double GetMid()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (high + low) / 2;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate up Price ...
|
|
double GetUp()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = MathMax(open, close);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Down Price ...
|
|
double GetDown()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = MathMin(open, close);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Required Price for Zone Checking ...
|
|
// For Bullish Zones => low;
|
|
// For Bearish Zones => high;
|
|
double GetZoneCheckValue(ENUM_X_DIRECTION forDir)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid() ||
|
|
!HasDirection(forDir))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsBullish(forDir);
|
|
|
|
//
|
|
result =
|
|
isBullish
|
|
? low
|
|
: high;
|
|
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Bar Body ...
|
|
double GetBody()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = GetUp() - GetDown();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Bar Range ...
|
|
double GetRange()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = high - low;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Bar Shadows ...
|
|
double GetShadows()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = GetRange() - GetBody();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Bar High Shadow ...
|
|
double GetHighShadow()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
high - GetUp()
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Bar Low Shadow ...
|
|
double GetLowShadow()
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
//
|
|
GetDown() - low;
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Bar is Bullish ...
|
|
bool IsBullish()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = open < close;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Bar is Bearish ...
|
|
bool IsBearish()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = open > close;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Get Direction of Bar ...
|
|
ENUM_X_DIRECTION GetDirection()
|
|
{
|
|
//
|
|
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
|
|
|
//
|
|
bool isBullish = IsBullish();
|
|
bool isBearish = IsBearish();
|
|
|
|
//
|
|
result =
|
|
isBullish && isBearish
|
|
? X_DIRECTION_ALL
|
|
: !isBullish && !isBearish
|
|
? X_DIRECTION_NONE
|
|
: isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Next Bar Time ...
|
|
datetime NextAt()
|
|
{
|
|
//
|
|
datetime result = NULL;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int prSeconds = PeriodSeconds(period);
|
|
|
|
//
|
|
result = time + prSeconds;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Prev Bar Time ...
|
|
datetime BeforeOn()
|
|
{
|
|
//
|
|
datetime result = NULL;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int prSeconds = PeriodSeconds(period);
|
|
|
|
//
|
|
result = time - prSeconds;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Last Bar Open Time in Smaller Period ...
|
|
datetime GetLastBarTimeOfPeriod(
|
|
ENUM_TIMEFRAMES smallerPeriod //
|
|
)
|
|
{
|
|
//
|
|
datetime result = NULL;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int sourceSeconds = PeriodSeconds(period);
|
|
int destSeconds = PeriodSeconds(smallerPeriod);
|
|
if (destSeconds >= sourceSeconds)
|
|
{
|
|
//
|
|
result = time;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = (datetime)((((int)time) + sourceSeconds) - destSeconds);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Close Time ...
|
|
datetime GetCloseTime()
|
|
{
|
|
//
|
|
datetime result = NULL;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int seconds = PeriodSeconds(period);
|
|
|
|
//
|
|
result = (datetime)(((int)time) + seconds);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool BarAt(
|
|
int index,
|
|
XOHCL &bar //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (index < 0)
|
|
{
|
|
index = 0;
|
|
}
|
|
|
|
//
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool BarIn(
|
|
ENUM_TIMEFRAMES _period,
|
|
XOHCL &bar //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsSpecifiedValid(_period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int index = Index(_period);
|
|
result = bar.Init(
|
|
symbol,
|
|
_period,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Current Bar Index on Chart ...
|
|
int Index()
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBarShift(
|
|
symbol,
|
|
period,
|
|
time
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int Index(datetime value)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBarShift(
|
|
symbol,
|
|
period,
|
|
value //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int Index(ENUM_TIMEFRAMES value)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsSpecifiedValid(value);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBarShift(
|
|
symbol,
|
|
value,
|
|
time //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool GetNextBar(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = Index();
|
|
result = idx > 0;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = bar.Init(
|
|
this.symbol,
|
|
this.period,
|
|
idx - 1 //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
bar.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool GetPreviousBar(XOHCL &bar)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = Index();
|
|
|
|
//
|
|
result = bar.Init(
|
|
this.symbol,
|
|
this.period,
|
|
idx + 1 //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
bar.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Highest Bar Index ...
|
|
int FindHighestIndex(
|
|
int mLength, // Loopback ...
|
|
ENUM_SERIESMODE mMode // Calculation mode
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (mLength < 2)
|
|
{
|
|
mLength = 2;
|
|
}
|
|
|
|
//
|
|
result = iHighest(
|
|
symbol,
|
|
period,
|
|
mMode,
|
|
mLength,
|
|
Index());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Highest ...
|
|
double FindHighest(
|
|
int mLength, // Loopback ...
|
|
ENUM_SERIESMODE mMode // Calculation mode
|
|
)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = FindHighestIndex(
|
|
mLength,
|
|
mMode);
|
|
if (idx <= -1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iH;
|
|
result = iH.Init(
|
|
symbol,
|
|
period,
|
|
idx
|
|
//
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iH.GetPrice(mMode);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Highest ...
|
|
double FindHighestUp(
|
|
int mLength // Loopback ...
|
|
)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = FindHighest(mLength, MODE_OPEN);
|
|
result = MathMax(mLength, FindHighest(mLength, MODE_CLOSE));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Lowest Bar Index ...
|
|
int FindLowestIndex(
|
|
int mLength, // Loopback ...
|
|
ENUM_SERIESMODE mMode // Calculation mode
|
|
)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (mLength < 2)
|
|
{
|
|
mLength = 2;
|
|
}
|
|
|
|
//
|
|
result = iLowest(
|
|
symbol,
|
|
period,
|
|
mMode,
|
|
mLength,
|
|
Index());
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Lowest ...
|
|
double FindLowest(
|
|
int mLength, // Loopback ...
|
|
ENUM_SERIESMODE mMode // Calculation mode
|
|
)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = FindLowestIndex(
|
|
mLength,
|
|
mMode);
|
|
if (idx <= -1)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iL;
|
|
result = iL.Init(
|
|
symbol,
|
|
period,
|
|
idx
|
|
//
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iL.GetPrice(mMode);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Find Lowest ...
|
|
double FindLowesttDown(
|
|
int mLength // Loopback ...
|
|
)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = FindLowest(mLength, MODE_OPEN);
|
|
result = MathMax(mLength, FindLowest(mLength, MODE_CLOSE));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Other ...
|
|
string GetTag(string prefix = "")
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
result =
|
|
(IsValid(prefix)
|
|
? prefix + "_"
|
|
: "") +
|
|
"XOHCL_" + symbol + "_" + ToString(period) + "_" + ToFormatString(time);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Convert to String Representation ...
|
|
string ToString()
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
result = GetTypeName(this) +
|
|
"(O(" + ToString(open) + "),H(" + ToString(high) + "),C(" + ToString(close) + "),L(" + ToString(low) + "))";
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
// |