825 lines
30 KiB
Plaintext
825 lines
30 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// ----------------------------------------------
|
|
// Name: XSCBaseHelper
|
|
// Description: provides all Base Indicator
|
|
// Helper requirements ...
|
|
//
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// Includes ...
|
|
#include "../Classes/x-saherelm.base.class.mq5"
|
|
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
enum ENUM_X_SCORE
|
|
{
|
|
X_SCORE_NONE = 0,
|
|
X_SCORE_MIN = 1,
|
|
X_SCORE_NORMAL = 2,
|
|
X_SCORE_MAX = 3,
|
|
};
|
|
|
|
// #region Generics ...
|
|
//
|
|
// State Handler Generic Functions ...
|
|
#define DECLARE_STATE_FUNCTIONS(name, state_reader, bar_normalizer_func) \
|
|
bool Is##name##Bullish(int barIndex = 0) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return state_reader(barIndex) >= 1; \
|
|
} \
|
|
bool Is##name##Bearish(int barIndex = 0) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return state_reader(barIndex) <= -1; \
|
|
} \
|
|
bool Is##name##SwitchedToBullish(int barIndex = 0) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##name##Bullish(barIndex) && !Is##name##Bullish(barIndex + 1); \
|
|
} \
|
|
bool Is##name##SwitchedToBearish(int barIndex = 0) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##name##Bearish(barIndex) && !Is##name##Bearish(barIndex + 1); \
|
|
}
|
|
|
|
//
|
|
// State Handler Based On Price Type Generic Functions ...
|
|
#define DECLARE_PRICE_BASED_STATE_FUNCTIONS(name, value_reader, bar_normalizer_func, point_reader_func, price_reader_func) \
|
|
bool Is##name##Bullish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
double threshold = point_reader_func() * tolerance; \
|
|
return price_reader_func(barIndex, priceType) > value_reader(barIndex) + threshold || \
|
|
price_reader_func(barIndex, priceType) > value_reader(barIndex) - threshold; \
|
|
} \
|
|
bool Is##name##Bearish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
double threshold = point_reader_func() * tolerance; \
|
|
return price_reader_func(barIndex, priceType) < value_reader(barIndex) + threshold || \
|
|
price_reader_func(barIndex, priceType) < value_reader(barIndex) - threshold; \
|
|
} \
|
|
bool Is##name##SwitchedToBullish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##name##Bullish(barIndex, priceType, tolerance) && !Is##name##Bullish(barIndex + 1, priceType, tolerance); \
|
|
} \
|
|
bool Is##name##SwitchedToBearish(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##name##Bearish(barIndex, priceType, tolerance) && !Is##name##Bearish(barIndex + 1, priceType, tolerance); \
|
|
}
|
|
|
|
//
|
|
// Value Comparator Generic Functions ...
|
|
#define DECLARE_VALUE_COMPARATOR_FUNCTIONS(name, value_reader, bar_normalizer_func, point_reader_func) \
|
|
bool Is##name##OverLast(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return IsOver( \
|
|
value_reader(barIndex), \
|
|
value_reader(barIndex + 1), \
|
|
point_reader_func() * tolerance); \
|
|
} \
|
|
bool Is##name##UnderLast(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return IsUnder( \
|
|
value_reader(barIndex), \
|
|
value_reader(barIndex + 1), \
|
|
point_reader_func() * tolerance); \
|
|
} \
|
|
bool Is##name##SameAsLast(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return IsSame( \
|
|
value_reader(barIndex), \
|
|
value_reader(barIndex + 1), \
|
|
point_reader_func() * tolerance); \
|
|
} \
|
|
bool Is##name##CrossedOverLast(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##name##OverLast(barIndex, tolerance) && !Is##name##OverLast(barIndex + 1, tolerance); \
|
|
} \
|
|
bool Is##name##CrossedUnderLast(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##name##UnderLast(barIndex, tolerance) && !Is##name##UnderLast(barIndex + 1, tolerance); \
|
|
}
|
|
|
|
//
|
|
// Price Comparator Generic Functions ...
|
|
#define DECLARE_PRICE_COMPARATOR_FUNCTIONS(name, value_reader, bar_normalizer_func, price_reader_func) \
|
|
bool IsPriceOver##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return price_reader_func(barIndex, priceType) > value_reader(barIndex); \
|
|
} \
|
|
bool IsPriceUnder##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return price_reader_func(barIndex, priceType) < value_reader(barIndex); \
|
|
} \
|
|
bool IsPriceCrossedOver##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return IsPriceOver##name(barIndex, priceType) && !IsPriceOver##name(barIndex + 1, priceType); \
|
|
} \
|
|
bool IsPriceCrossedUnder##name(int barIndex = 0, ENUM_X_PRICE priceType = X_PRICE_CLOSE) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return IsPriceUnder##name(barIndex, priceType) && !IsPriceUnder##name(barIndex + 1, priceType); \
|
|
}
|
|
|
|
//
|
|
// Crossing Comparator Generic Functions ...
|
|
#define DECLARE_CROSSING_COMPARATOR_FUNCTIONS(baseName, fastName, slowName, fast_reader_func, slow_reader_func, bar_normalizer_func, point_reader_func) \
|
|
bool Is##baseName##fastName##Over##Slow(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
double fast = fast_reader_func(barIndex); \
|
|
double slow = slow_reader_func(barIndex); \
|
|
double distance = tolerance * point_reader_func(); \
|
|
return fast > slow && MathAbs(fast - slow) >= distance; \
|
|
} \
|
|
bool Is##baseName##fastName##Under##Slow(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
double fast = fast_reader_func(barIndex); \
|
|
double slow = slow_reader_func(barIndex); \
|
|
double distance = tolerance * point_reader_func(); \
|
|
return fast < slow && MathAbs(fast - slow) >= distance; \
|
|
} \
|
|
bool Is##baseName##fastName##CrossedOver##Slow(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##baseName##fastName##Over##Slow(barIndex, tolerance) && !Is##baseName##fastName##Over##Slow(barIndex + 1, tolerance); \
|
|
} \
|
|
bool Is##baseName##fastName##CrossedUnder##Slow(int barIndex = 0, double tolerance = 2) \
|
|
{ \
|
|
barIndex = bar_normalizer_func(barIndex); \
|
|
return Is##baseName##fastName##Under##Slow(barIndex, tolerance) && !Is##baseName##fastName##Under##Slow(barIndex + 1, tolerance); \
|
|
}
|
|
// #endregion
|
|
|
|
//
|
|
// a Class for Handle base requirements ...
|
|
// for indicators ...
|
|
class XCBaseHelper : public XCBase
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Constructor ...
|
|
XCBaseHelper(
|
|
string symbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES period // Trading Time Frame
|
|
)
|
|
{
|
|
//
|
|
mSymbol = symbol;
|
|
mPeriod = period;
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCBaseHelper()
|
|
{
|
|
//
|
|
IndicatorRelease(mHandler);
|
|
}
|
|
|
|
//
|
|
// Setter(s) / Getter(s) ...
|
|
|
|
//
|
|
// Symbol ...
|
|
string GetSymbol()
|
|
{
|
|
return mSymbol;
|
|
}
|
|
|
|
//
|
|
// Period ...
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
return mPeriod;
|
|
}
|
|
|
|
//
|
|
// Retrieve Bars ...
|
|
int CountBars()
|
|
{
|
|
//
|
|
int result =
|
|
Bars(
|
|
mSymbol,
|
|
mPeriod
|
|
//
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Indicator Calculated Bars ...
|
|
int CountCalculatedBars()
|
|
{
|
|
return BarsCalculated(mHandler);
|
|
}
|
|
|
|
//
|
|
virtual void Free()
|
|
{
|
|
}
|
|
|
|
//
|
|
// Generate Tag ...
|
|
virtual string GetTag()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
result =
|
|
//
|
|
GetToken() +
|
|
"[" +
|
|
GetSymbol() + "|" +
|
|
ToXString(GetPeriod()) +
|
|
"]"
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Functions ...
|
|
|
|
/**
|
|
* Validate Handler Exists ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = IsXValid(mSymbol) &&
|
|
IsXValid(mPeriod) &&
|
|
mHandler != INVALID_HANDLE;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Validated Zones ...
|
|
*
|
|
* @param zones: XBoxZone, collection reference to holds results ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFZones: int, required Number of Zones ...
|
|
* @param breakValidLength: int, Breake Validation Length of Zones ...
|
|
* @param validateFakeBreakes: bool, Validation Fake Breaked Zones ...
|
|
* @param shadowMultiplier: double a Shadow Multiplier for Validation ...
|
|
* @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ...
|
|
* @param validationLength: int, Validation Length of Zones ...
|
|
* @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractBarZones(
|
|
XBoxZone &zones[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFZones = 50,
|
|
int breakValidLength = 3,
|
|
bool validateFakeBreakes = true,
|
|
double shadowMultiplier = 3,
|
|
double validationStrength = 1,
|
|
int validationLength = 21,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
SpecifiedClean(zones);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
validationLength = NormalizeInt(validationLength, 7);
|
|
shadowMultiplier = NormalizeDouble(shadowMultiplier, 1);
|
|
validationStrength = NormalizeDouble(validationStrength, 1);
|
|
requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5);
|
|
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100);
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
double minAllowedStrength = (validationStrength * GetPoints(symbol));
|
|
|
|
//
|
|
XOHCL bar;
|
|
bool has = false;
|
|
|
|
//
|
|
// Initialized Start Bar ...
|
|
has = bar.Init(
|
|
symbol,
|
|
period,
|
|
barIndex //
|
|
);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
XBoxZone zone;
|
|
int start = barIndex;
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
bool lowShadowPassed = false;
|
|
bool highShadowPassed = false;
|
|
ENUM_X_DIRECTION dir = X_DIRECTION_NONE;
|
|
int end = start + maxAllowedLoopbackLength;
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
zone.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Reading HK Buffesr ...
|
|
has = bar.BarAt(i, iBar);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check Direction ...
|
|
isBullish = iBar.open < iBar.close;
|
|
isBearish = iBar.open > iBar.close;
|
|
dir =
|
|
(isBullish && !isBearish)
|
|
? X_DIRECTION_BULLISH
|
|
: (isBearish && !isBullish)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(dir);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Low Shadow ...
|
|
lowShadowPassed = iBar.GetLowShadow() >= (shadowMultiplier * iBar.GetHighShadow());
|
|
|
|
//
|
|
// High Shadow ...
|
|
highShadowPassed = iBar.GetHighShadow() >= (shadowMultiplier * iBar.GetLowShadow());
|
|
|
|
//
|
|
has = (lowShadowPassed && !highShadowPassed) ||
|
|
(highShadowPassed && !lowShadowPassed);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Filling Zone ...
|
|
|
|
//
|
|
zone.symbol = symbol;
|
|
zone.period = period;
|
|
zone.from = GetBarTime(
|
|
zone.symbol,
|
|
zone.period,
|
|
i //
|
|
);
|
|
zone.dir = lowShadowPassed
|
|
? X_DIRECTION_BULLISH
|
|
: highShadowPassed
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
|
|
//
|
|
zone.upper =
|
|
IsXBullish(zone.dir)
|
|
? iBar.GetDown()
|
|
: IsXBearish(zone.dir)
|
|
? iBar.high
|
|
: EMPTY_VALUE;
|
|
|
|
//
|
|
zone.lower =
|
|
IsXBullish(zone.dir)
|
|
? iBar.low
|
|
: IsXBearish(zone.dir)
|
|
? iBar.GetUp()
|
|
: EMPTY_VALUE;
|
|
|
|
//
|
|
zone.to = bar.time;
|
|
zone.type = "XBar_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance"
|
|
: "") +
|
|
"_" + ToXString(TimeToSeconds(zone.from));
|
|
|
|
//
|
|
// Validate ...
|
|
has =
|
|
zone.IsValid() &&
|
|
HasDirection(zone.dir) &&
|
|
NotEmptyZero(zone.upper) &&
|
|
NotEmptyZero(zone.lower) &&
|
|
(zone.IsBullish()
|
|
? bar.low > zone.upper
|
|
: bar.high < zone.lower) &&
|
|
(zone.upper - zone.lower) >= minAllowedStrength &&
|
|
ValidateBarZone(zone, validationLength, breakValidLength, validateFakeBreakes);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
zone,
|
|
zones //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
zone.Clean();
|
|
|
|
//
|
|
// Validating ...
|
|
result = ArraySize(zones);
|
|
has = IsValidSize(result) &&
|
|
result >= requiredNumberOFZones;
|
|
if (has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
bar.Clean();
|
|
iBar.Clean();
|
|
zone.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Validate Bar Zone ...
|
|
*
|
|
* @param zone: XBoxZone, reference to Specified Zone ...
|
|
* @param validationLength: int, Validation Length of Zones ...
|
|
* @param breakValidLength: int, Break Validation Length of Zones ...
|
|
* @param validateFakeBreakes: bool, Validation Fake Breaked Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateBarZone(
|
|
XBoxZone &zone,
|
|
int validationLength = 1,
|
|
int breakValidLength = 3,
|
|
bool validateFakeBreakes = true //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
validationLength = NormalizeInt(validationLength, 1);
|
|
breakValidLength = NormalizeInt(breakValidLength, 2);
|
|
|
|
//
|
|
// Validate ...
|
|
result = zone.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Requirements ...
|
|
XOHCL iBar;
|
|
int count = 0;
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
int start = zone.FromIndex() + 1;
|
|
int end = start + validationLength;
|
|
|
|
//
|
|
// Validate Before ...
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Initialize Indexed Bar ...
|
|
iBar.Clean();
|
|
result = iBar.Init(
|
|
symbol,
|
|
period,
|
|
i //
|
|
);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = zone.IsBullish()
|
|
? iBar.low > zone.lower
|
|
: iBar.high < zone.upper;
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validating After ...
|
|
if (result)
|
|
{
|
|
//
|
|
start = zone.ToIndex() + 1;
|
|
count = zone.FromIndex() - start;
|
|
end = start + count;
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Initialized Indexed Bar ...
|
|
iBar.Clean();
|
|
result = iBar.Init(
|
|
symbol,
|
|
period,
|
|
i //
|
|
);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = zone.IsBullish()
|
|
? iBar.low > zone.lower
|
|
: iBar.high < zone.upper;
|
|
if (!result)
|
|
{
|
|
//
|
|
// Check For Fake Breake ...
|
|
if (validateFakeBreakes && breakValidLength > 0)
|
|
{
|
|
//
|
|
result = i - 1 >= 0;
|
|
if (result)
|
|
{
|
|
//
|
|
for (int j = i - 1; j >= zone.ToIndex(); j--)
|
|
{
|
|
//
|
|
// Initialized Indexed Bar ...
|
|
iBar.Clean();
|
|
result = iBar.Init(
|
|
symbol,
|
|
period,
|
|
j //
|
|
);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = zone.IsBullish()
|
|
? iBar.close > zone.upper
|
|
: iBar.close < zone.lower;
|
|
if (result)
|
|
{
|
|
//
|
|
result = MathAbs(j - i) <= breakValidLength;
|
|
if (result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resource ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Normalizing Bar Index ...
|
|
*
|
|
* @param barIndex: int, Provided Bar Index ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int NormalizeBarIndex(int barIndex)
|
|
{
|
|
//
|
|
int result = barIndex;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = CountBars() - 1;
|
|
result = NormalizeInt(result, 0, count - 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Symbol ...
|
|
string mSymbol;
|
|
|
|
//
|
|
// Period ...
|
|
ENUM_TIMEFRAMES mPeriod;
|
|
|
|
//
|
|
// Indicator Handler ...
|
|
int mHandler;
|
|
|
|
/**
|
|
* Read Value of Specified Buffer ...
|
|
*
|
|
* @param bufferIndex: int, which handler buffer to read value ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double ReadValue(
|
|
int bufferIndex,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
double result = EMPTY_VALUE;
|
|
|
|
//
|
|
// Normalize ...
|
|
int barsTotal = CountBars();
|
|
barIndex = NormalizeInt(barIndex, 0, barsTotal - 1);
|
|
bufferIndex = NormalizeInt(bufferIndex, 0);
|
|
|
|
//
|
|
// Validate ...
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double tmp[];
|
|
int count = CopyBuffer(
|
|
mHandler,
|
|
bufferIndex,
|
|
barIndex,
|
|
1,
|
|
tmp //
|
|
);
|
|
result = tmp[0];
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Read Values of Specified Buffer ...
|
|
*
|
|
* @param buffer: double, reference collection to holds result ...
|
|
* @param bufferIndex: int, which handler buffer to read value ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param count: int, number of items to read, 0 for WHOLE_ARRAY ...
|
|
* @param asSeries: bool, set As Series Buffer or not ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ReadValues(
|
|
double &buffer[],
|
|
int bufferIndex,
|
|
int barIndex = 0,
|
|
int count = 0,
|
|
bool asSeries = true //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
XClean(buffer);
|
|
|
|
//
|
|
// Normalize ...
|
|
int barsTotal = CountBars();
|
|
count = NormalizeInt(count, 0);
|
|
bufferIndex = NormalizeInt(bufferIndex, 0);
|
|
barIndex = NormalizeInt(barIndex, 0, barsTotal - 1);
|
|
|
|
//
|
|
// Validate ...
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = CopyBuffer(
|
|
mHandler,
|
|
bufferIndex,
|
|
barIndex,
|
|
count,
|
|
buffer //
|
|
);
|
|
|
|
//
|
|
// Set As Series Flag ...
|
|
ArraySetAsSeries(buffer, asSeries);
|
|
|
|
//
|
|
result = ArraySize(buffer);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
};
|
|
|
|
//
|
|
// Tools ....
|