last works on implementing Candlestick Patterns on Bar Analyser Class ...
This commit is contained in:
@@ -26,9 +26,6 @@
|
|||||||
//
|
//
|
||||||
// Definitions ...
|
// Definitions ...
|
||||||
|
|
||||||
//
|
|
||||||
#define X_PERCENTAGE_GOLDEN_MULTIPLIER 100000
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Implementations ...
|
// Implementations ...
|
||||||
class XCBarAnalyser : public XCBase
|
class XCBarAnalyser : public XCBase
|
||||||
@@ -423,7 +420,7 @@ class XCBarAnalyser : public XCBase
|
|||||||
for (int i = 0; i < uppersCount; i++)
|
for (int i = 0; i < uppersCount; i++)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
double iValue = uppers[i] - lowers[i];
|
double iValue = lowers[i] + (uppers[i] - lowers[i]);
|
||||||
|
|
||||||
//
|
//
|
||||||
Add(
|
Add(
|
||||||
@@ -707,45 +704,48 @@ class XCBarAnalyser : public XCBase
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/**
|
||||||
// Actions ...
|
* Detect Big Price Change Happens or not ...
|
||||||
|
*
|
||||||
bool IsSpike(
|
* @param bar: XOHCL instance reference, Start Bar ...
|
||||||
|
* @param dir: ENUM_X_DIRECTION member, Event Direction ...
|
||||||
|
* @param type: ENUM_X_PRICE member, Price Type ...
|
||||||
|
* @param forcBodyInRange: bool, Use Body in Range Detection ...
|
||||||
|
* @param rangeExtendMultiplier: double, a Multiplier for Checking Price Range ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsBigChange(
|
||||||
XOHCL &bar,
|
XOHCL &bar,
|
||||||
XOHCL &fromBar,
|
|
||||||
XOHCL &toBar,
|
|
||||||
ENUM_X_DIRECTION &dir,
|
ENUM_X_DIRECTION &dir,
|
||||||
double minPriceChangePercent = 1.5,
|
|
||||||
ENUM_X_PRICE type = X_PRICE_CLOSE,
|
ENUM_X_PRICE type = X_PRICE_CLOSE,
|
||||||
bool forcBodyInRange = true,
|
bool forcBodyInRange = true,
|
||||||
double rangeExtendMultiplier = 2,
|
double rangeExtendMultiplier = 1.0 //
|
||||||
int loopback = 14 //
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
toBar.Clean();
|
|
||||||
fromBar.Clean();
|
|
||||||
dir = X_DIRECTION_NONE;
|
dir = X_DIRECTION_NONE;
|
||||||
loopback = NormalizeInt(loopback, 1);
|
|
||||||
rangeExtendMultiplier = NormalizeDouble(rangeExtendMultiplier, 1);
|
rangeExtendMultiplier = NormalizeDouble(rangeExtendMultiplier, 1);
|
||||||
minPriceChangePercent = NormalizeDouble(minPriceChangePercent, 1.5);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
int periodSeconds = PeriodSeconds(bar.period);
|
result =
|
||||||
double divider = X_PERCENTAGE_GOLDEN_MULTIPLIER;
|
bar.IsValid() &&
|
||||||
double periodMult = (periodSeconds / PeriodSeconds(PERIOD_M5)) * 0.2;
|
IsValid(type);
|
||||||
minPriceChangePercent /= (divider / periodMult);
|
|
||||||
|
|
||||||
//
|
|
||||||
result = bar.IsValid();
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double minPriceChangePercent = 0;
|
||||||
|
int loopback = GetPeriodSharpData(
|
||||||
|
minPriceChangePercent,
|
||||||
|
bar.period //
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
double ranges[];
|
double ranges[];
|
||||||
int rangesCount = GetPriceRange(
|
int rangesCount = GetPriceRange(
|
||||||
@@ -765,6 +765,7 @@ class XCBarAnalyser : public XCBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Calculate Ranges ...
|
||||||
double rangeMax = GetMax(ranges);
|
double rangeMax = GetMax(ranges);
|
||||||
double rangeMin = GetMin(ranges);
|
double rangeMin = GetMin(ranges);
|
||||||
double rangeAverage = GetAverage(ranges);
|
double rangeAverage = GetAverage(ranges);
|
||||||
@@ -775,29 +776,54 @@ class XCBarAnalyser : public XCBase
|
|||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
static double maxPriceChange = 0;
|
// Calculate HH and LL ...
|
||||||
static double minPriceChange = 0;
|
double hh = 0;
|
||||||
if (maxPriceChange == 0 || maxPriceChange < priceChangePercent)
|
double ll = 0;
|
||||||
|
int hhIDX = -1;
|
||||||
|
int llIDX = -1;
|
||||||
|
result = CalculateLoopbackHLData(
|
||||||
|
hhIDX,
|
||||||
|
hh,
|
||||||
|
llIDX,
|
||||||
|
ll,
|
||||||
|
bar,
|
||||||
|
loopback //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
ll > 0 &&
|
||||||
|
hh > ll &&
|
||||||
|
IsValidIndex(llIDX) &&
|
||||||
|
IsValidIndex(hhIDX);
|
||||||
|
if (!result)
|
||||||
{
|
{
|
||||||
maxPriceChange = priceChangePercent;
|
return result;
|
||||||
}
|
|
||||||
if (minPriceChange == 0 || minPriceChange > priceChangePercent)
|
|
||||||
{
|
|
||||||
minPriceChange = priceChangePercent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int hhDiff = (hhIDX - bar.Index());
|
||||||
|
int llDiff = (llIDX - bar.Index());
|
||||||
|
|
||||||
//
|
//
|
||||||
bool isBullish =
|
bool isBullish =
|
||||||
//
|
//
|
||||||
|
hhDiff <= 1 &&
|
||||||
|
llIDX > hhIDX &&
|
||||||
|
bar.close >= hh &&
|
||||||
priceChangePercent > 0 &&
|
priceChangePercent > 0 &&
|
||||||
priceChangePercent >= minPriceChangePercent
|
priceChangePercent >= minPriceChangePercent &&
|
||||||
|
bar.high > (rangeAverage * rangeExtendMultiplier)
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
|
|
||||||
//
|
//
|
||||||
bool isBearish =
|
bool isBearish =
|
||||||
//
|
//
|
||||||
|
llDiff <= 1 &&
|
||||||
|
hhIDX > llIDX &&
|
||||||
|
bar.close <= ll &&
|
||||||
priceChangePercent < 0 &&
|
priceChangePercent < 0 &&
|
||||||
|
bar.low < (rangeAverage * rangeExtendMultiplier) &&
|
||||||
MathAbs(priceChangePercent) >= minPriceChangePercent
|
MathAbs(priceChangePercent) >= minPriceChangePercent
|
||||||
//
|
//
|
||||||
;
|
;
|
||||||
@@ -823,6 +849,504 @@ class XCBarAnalyser : public XCBase
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Spike ...
|
||||||
|
*
|
||||||
|
* @param bar: XOHCL instance reference, Start Bar ...
|
||||||
|
* @param dir: ENUM_X_DIRECTION member, Event Direction ...
|
||||||
|
* @param type: ENUM_X_PRICE member, Price Type ...
|
||||||
|
* @param forcBodyInRange: bool, Use Body in Range Detection ...
|
||||||
|
* @param rangeExtendMultiplier: double, a Multiplier for Checking Price Range ...
|
||||||
|
* @param sameBars: int, Specified How Many Same Bars Required for an Spike ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsSpike(
|
||||||
|
XOHCL &bar,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
ENUM_X_PRICE type = X_PRICE_CLOSE,
|
||||||
|
bool forcBodyInRange = true,
|
||||||
|
double rangeExtendMultiplier = 1.0,
|
||||||
|
int sameBars = 3 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
sameBars = NormalizeInt(sameBars, 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid(type) &&
|
||||||
|
bar.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// First We Have to Has a Big Change ...
|
||||||
|
result = IsBigChange(
|
||||||
|
bar,
|
||||||
|
dir,
|
||||||
|
type,
|
||||||
|
forcBodyInRange,
|
||||||
|
rangeExtendMultiplier //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Has Same Bars ...
|
||||||
|
int sameBarsIndex = -1;
|
||||||
|
ENUM_X_DIRECTION sameBarsDir;
|
||||||
|
result = HasSameBars(
|
||||||
|
bar,
|
||||||
|
sameBarsDir,
|
||||||
|
sameBarsIndex,
|
||||||
|
sameBars //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Same Bars Direction sames To Price Change ...
|
||||||
|
result = sameBarsDir == dir;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Candlestick ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Specified Bar is Doji Pattern or not ...
|
||||||
|
*
|
||||||
|
* @param bar: XOHCL instance reference, Specified Bar to Check ...
|
||||||
|
* @param dir: ENUM_X_DIRECTION member, Specified Doji Direction ...
|
||||||
|
* @param shadowMultiplier: double, Specified Shadow Multiplier ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsDoji(
|
||||||
|
XOHCL &bar,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
double shadowMultiplier = 1.5 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
shadowMultiplier = NormalizeDouble(shadowMultiplier, 1.5, 3);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = bar.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double body = bar.GetBody();
|
||||||
|
double range = bar.GetRange();
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
body > 0 &&
|
||||||
|
range > 0
|
||||||
|
? (body / range < 0.1)
|
||||||
|
: false;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
bar.GetLowShadow() >= (bar.GetHighShadow() * shadowMultiplier)
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: bar.GetHighShadow() >= (bar.GetLowShadow() * shadowMultiplier)
|
||||||
|
? X_DIRECTION_BEARISH
|
||||||
|
: X_DIRECTION_NONE;
|
||||||
|
//
|
||||||
|
result = HasDirection(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Specified Bar is Hammer Pattern or not ...
|
||||||
|
*
|
||||||
|
* @param bar: XOHCL instance reference, Specified Bar to Check ...
|
||||||
|
* @param dir: ENUM_X_DIRECTION member, Specified Doji Direction ...
|
||||||
|
* @param bodyMultiplier: double, Specified Body Multiplier ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsHammer(
|
||||||
|
XOHCL &bar,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
double bodyMultiplier = 2.0 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
bodyMultiplier = NormalizeDouble(bodyMultiplier, 1.5, 3);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = bar.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double body = bar.GetBody();
|
||||||
|
double lShadow = bar.GetLowShadow();
|
||||||
|
double hShadow = bar.GetHighShadow();
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish =
|
||||||
|
hShadow < body &&
|
||||||
|
lShadow > (bodyMultiplier * body);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBearish =
|
||||||
|
lShadow < body &&
|
||||||
|
hShadow > (bodyMultiplier * body);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Specified Bar is Engulfed Prev Bar or not ...
|
||||||
|
*
|
||||||
|
* @param bar: XOHCL instance reference, Specified Bar to Check ...
|
||||||
|
* @param dir: ENUM_X_DIRECTION member, Specified Doji Direction ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsEngulfed(
|
||||||
|
XOHCL &bar,
|
||||||
|
ENUM_X_DIRECTION &dir //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = bar.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL pBar;
|
||||||
|
result = bar.GetPreviousBar(pBar);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
pBar.Clean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = bar.GetBody() > pBar.GetBody();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
pBar.Clean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish =
|
||||||
|
bar.IsBullish() &&
|
||||||
|
pBar.IsBearish() &&
|
||||||
|
bar.GetDown() <= pBar.GetDown() &&
|
||||||
|
bar.GetUp() > pBar.GetUp();
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBearish =
|
||||||
|
bar.IsBearish() &&
|
||||||
|
pBar.IsBullish() &&
|
||||||
|
bar.GetUp() >= pBar.GetUp() &&
|
||||||
|
bar.GetDown() < pBar.GetDown();
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
|
||||||
|
//
|
||||||
|
pBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Specified Bar is Momentum Bar or not ...
|
||||||
|
*
|
||||||
|
* @param bar: XOHCL instance reference, Specified Bar to Check ...
|
||||||
|
* @param dir: ENUM_X_DIRECTION member, Specified Doji Direction ...
|
||||||
|
* @param loopback: int, Specified Loopback ...
|
||||||
|
* @param rangeExtendMultiplier: double, a Multiplier for Checking Price Range ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsMomentum(
|
||||||
|
XOHCL &bar,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
int loopback = 2,
|
||||||
|
double rangeExtendMultiplier = 1.5 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
loopback = NormalizeInt(loopback, 1);
|
||||||
|
rangeExtendMultiplier = NormalizeDouble(rangeExtendMultiplier, 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = bar.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bar Must Engulfed ...
|
||||||
|
result = IsEngulfed(
|
||||||
|
bar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate HH and LL ...
|
||||||
|
double hh = 0;
|
||||||
|
double ll = 0;
|
||||||
|
int hhIDX = -1;
|
||||||
|
int llIDX = -1;
|
||||||
|
result = CalculateLoopbackHLData(
|
||||||
|
hhIDX,
|
||||||
|
hh,
|
||||||
|
llIDX,
|
||||||
|
ll,
|
||||||
|
bar,
|
||||||
|
loopback //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
ll > 0 &&
|
||||||
|
hh > ll &&
|
||||||
|
IsValidIndex(llIDX) &&
|
||||||
|
IsValidIndex(hhIDX);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish =
|
||||||
|
bar.low > ll &&
|
||||||
|
IsBullish(dir) &&
|
||||||
|
bar.close >= hh;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBearish =
|
||||||
|
bar.high < hh &&
|
||||||
|
IsBearish(dir) &&
|
||||||
|
bar.close <= ll;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Specified Bar is Pullback or not ...
|
||||||
|
*
|
||||||
|
* @param bar: XOHCL instance reference, Specified Bar to Check ...
|
||||||
|
* @param dir: ENUM_X_DIRECTION member, Specified Doji Direction ...
|
||||||
|
* @param loopback: int, Specified Loopback ...
|
||||||
|
* @param forceBody: bool, Force Using Body ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsPullback(
|
||||||
|
XOHCL &bar,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
int loopback = 3,
|
||||||
|
bool forceBody = false //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
loopback = NormalizeInt(loopback, 3);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = bar.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bar Must Engulfed ...
|
||||||
|
result = IsEngulfed(
|
||||||
|
bar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate HH and LL ...
|
||||||
|
double hh = 0;
|
||||||
|
double ll = 0;
|
||||||
|
int hhIDX = -1;
|
||||||
|
int llIDX = -1;
|
||||||
|
result = CalculateLoopbackHLData(
|
||||||
|
hhIDX,
|
||||||
|
hh,
|
||||||
|
llIDX,
|
||||||
|
ll,
|
||||||
|
bar,
|
||||||
|
loopback //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
ll > 0 &&
|
||||||
|
hh > ll &&
|
||||||
|
IsValidIndex(llIDX) &&
|
||||||
|
IsValidIndex(hhIDX);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish =
|
||||||
|
bar.high > hh &&
|
||||||
|
bar.low > ll;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBearish =
|
||||||
|
bar.high < hh &&
|
||||||
|
bar.low < ll;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (forceBody)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
isBullish =
|
||||||
|
isBullish &&
|
||||||
|
bar.GetUp() > hh &&
|
||||||
|
bar.GetDown() > ll &&
|
||||||
|
llIDX == bar.Index() + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
isBearish =
|
||||||
|
isBearish &&
|
||||||
|
bar.GetUp() < hh &&
|
||||||
|
bar.GetDown() < ll &&
|
||||||
|
hhIDX == bar.Index() + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
protected:
|
protected:
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -2988,52 +2988,6 @@
|
|||||||
//
|
//
|
||||||
// Decisions ...
|
// Decisions ...
|
||||||
|
|
||||||
//
|
|
||||||
bool IsBullishDecision(
|
|
||||||
XOHCL &bar,
|
|
||||||
double percent = 70 // Percent of Body
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
result =
|
|
||||||
//
|
|
||||||
bar.IsValid() &&
|
|
||||||
bar.Index() > 0 &&
|
|
||||||
bar.IsBullish() &&
|
|
||||||
(bar.GetRange() * percent) / 100 <= bar.GetBody()
|
|
||||||
//
|
|
||||||
;
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
bool IsBearishDecision(
|
|
||||||
XOHCL &bar,
|
|
||||||
double percent = 70 // Percent of Body
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
//
|
|
||||||
result =
|
|
||||||
//
|
|
||||||
bar.IsValid() &&
|
|
||||||
bar.Index() > 0 &&
|
|
||||||
bar.IsBearish() &&
|
|
||||||
(bar.GetRange() * percent) / 100 <= bar.GetBody()
|
|
||||||
//
|
|
||||||
;
|
|
||||||
|
|
||||||
//
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Candlestic Patterns ...
|
// Candlestic Patterns ...
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
//
|
//
|
||||||
// XCPOIDetector *mPOIDetector;
|
// XCPOIDetector *mPOIDetector;
|
||||||
|
XBarTracker mBarTracker;
|
||||||
XCBarAnalyser *mBarAnalyser;
|
XCBarAnalyser *mBarAnalyser;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -47,6 +48,12 @@ int OnInit()
|
|||||||
//
|
//
|
||||||
mBarAnalyser = new XCBarAnalyser();
|
mBarAnalyser = new XCBarAnalyser();
|
||||||
|
|
||||||
|
//
|
||||||
|
mBarTracker.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period //
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
return (INIT_SUCCEEDED);
|
return (INIT_SUCCEEDED);
|
||||||
}
|
}
|
||||||
@@ -89,6 +96,12 @@ void DetectBarAnalyser()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!mBarTracker.IsNewBar())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
XOHCL zBar;
|
XOHCL zBar;
|
||||||
bool isInited = zBar.Init(
|
bool isInited = zBar.Init(
|
||||||
@@ -96,21 +109,115 @@ void DetectBarAnalyser()
|
|||||||
_Period,
|
_Period,
|
||||||
0 //
|
0 //
|
||||||
);
|
);
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
XOHCL toBar;
|
XOHCL cBar;
|
||||||
XOHCL fromBar;
|
isInited = zBar.GetPreviousBar(cBar);
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Big Change in Price ...
|
||||||
ENUM_X_DIRECTION dir;
|
ENUM_X_DIRECTION dir;
|
||||||
|
bool isBigChange = mBarAnalyser.IsBigChange(
|
||||||
|
zBar, // Bar ...
|
||||||
|
dir, // Change Direction ...
|
||||||
|
X_PRICE_CLOSE, // Price Change Type ...
|
||||||
|
true, // Force Use Body for Range Calculation ...
|
||||||
|
1.0 // Range Extend Multiplier ...
|
||||||
|
);
|
||||||
|
if (isBigChange)
|
||||||
|
{
|
||||||
|
// Print("Big Price Change Detected: ", ToString(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Big Change in Price ...
|
||||||
bool isSpike = mBarAnalyser.IsSpike(
|
bool isSpike = mBarAnalyser.IsSpike(
|
||||||
zBar,
|
zBar, // Bar ...
|
||||||
fromBar,
|
dir, // Change Direction ...
|
||||||
toBar,
|
X_PRICE_CLOSE, // Price Change Type ...
|
||||||
dir //
|
true, // Force Use Body for Range Calculation ...
|
||||||
|
1.0, // Range Extend Multiplier ...
|
||||||
|
3 // Same Bars ...
|
||||||
);
|
);
|
||||||
if (isSpike)
|
if (isSpike)
|
||||||
{
|
{
|
||||||
Print("Spike Detected ...");
|
// Print("Spike Detected: ", ToString(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Doji Pattern ...
|
||||||
|
bool isDoji = mBarAnalyser.IsDoji(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isDoji)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Doji Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Hammer Pattern ...
|
||||||
|
bool isHammer = mBarAnalyser.IsHammer(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isHammer)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Hammer Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Engulf Pattern ...
|
||||||
|
bool isEngulfed = mBarAnalyser.IsEngulfed(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isEngulfed)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Engulfed Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Momentum Pattern ...
|
||||||
|
bool isMomentum = mBarAnalyser.IsMomentum(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isMomentum)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Momentum Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Pullback Pattern ...
|
||||||
|
bool isPullback = mBarAnalyser.IsPullback(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isMomentum)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Pullback Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3425,6 +3425,183 @@ int GetCycleLengthOn(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve Sharp Change Info for Specified Period ...
|
||||||
|
*
|
||||||
|
* @param priceChange: double, required Price Change ...
|
||||||
|
* @param mPeriod: ENUM_TIMEFRAMES member, Specified Period ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int GetPeriodSharpData(
|
||||||
|
double &priceChange,
|
||||||
|
ENUM_TIMEFRAMES mPeriod = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
priceChange = 0.0;
|
||||||
|
|
||||||
|
//
|
||||||
|
mPeriod = NormalizePeriod(mPeriod);
|
||||||
|
|
||||||
|
//
|
||||||
|
switch (mPeriod)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
case PERIOD_M1:
|
||||||
|
//
|
||||||
|
priceChange = 0.000008;
|
||||||
|
result = 14;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M2:
|
||||||
|
//
|
||||||
|
priceChange = 0.000008;
|
||||||
|
result = 14;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M3:
|
||||||
|
//
|
||||||
|
priceChange = 0.00001;
|
||||||
|
result = 14;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M4:
|
||||||
|
//
|
||||||
|
priceChange = 0.000011;
|
||||||
|
result = 14;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M5:
|
||||||
|
//
|
||||||
|
priceChange = 0.000015;
|
||||||
|
result = 14;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M6:
|
||||||
|
//
|
||||||
|
priceChange = 0.000015;
|
||||||
|
result = 14;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M10:
|
||||||
|
//
|
||||||
|
priceChange = 0.000015;
|
||||||
|
result = 12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M12:
|
||||||
|
//
|
||||||
|
priceChange = 0.000015;
|
||||||
|
result = 11;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M15:
|
||||||
|
//
|
||||||
|
priceChange = 0.000015;
|
||||||
|
result = 9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M20:
|
||||||
|
//
|
||||||
|
priceChange = 0.000015;
|
||||||
|
result = 9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_M30:
|
||||||
|
//
|
||||||
|
priceChange = 0.000017;
|
||||||
|
result = 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_H1:
|
||||||
|
//
|
||||||
|
priceChange = 0.000019;
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_H2:
|
||||||
|
//
|
||||||
|
priceChange = 0.000019;
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_H3:
|
||||||
|
//
|
||||||
|
priceChange = 0.000019;
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_H4:
|
||||||
|
//
|
||||||
|
priceChange = 0.000022;
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_H6:
|
||||||
|
//
|
||||||
|
priceChange = 0.000022;
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_H8:
|
||||||
|
//
|
||||||
|
priceChange = 0.000025;
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_H12:
|
||||||
|
//
|
||||||
|
priceChange = 0.000027;
|
||||||
|
result = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_D1:
|
||||||
|
//
|
||||||
|
priceChange = 0.000027;
|
||||||
|
result = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_W1:
|
||||||
|
//
|
||||||
|
priceChange = 0.00003;
|
||||||
|
result = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case PERIOD_MN1:
|
||||||
|
//
|
||||||
|
priceChange = 0.00003;
|
||||||
|
result = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// END Cycles ...
|
// END Cycles ...
|
||||||
//
|
//
|
||||||
@@ -5873,6 +6050,137 @@ double GetAppliedPrice(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Applied Price ...
|
||||||
|
*
|
||||||
|
* @param mSymbol: string, Specified Symbol ...
|
||||||
|
* @param mPeriod: ENUM_TIMEFRAMES member, Specified PEriod ...
|
||||||
|
* @param barIndex: int, Specified Bar Index ...
|
||||||
|
* @param mType: ENUM_X_PRICE member, Specified Price Type ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double GetAppliedPrice(
|
||||||
|
string mSymbol = NULL, // Symbol
|
||||||
|
ENUM_TIMEFRAMES mPeriod = NULL, // Period
|
||||||
|
int barIndex = 0, // Bar Index
|
||||||
|
ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
mSymbol = NormalizeSymbol(mSymbol);
|
||||||
|
mPeriod = NormalizePeriod(mPeriod);
|
||||||
|
barIndex = NormalizeInt(barIndex, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool has = IsValid(mType);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double open = iOpen(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double high = iHigh(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double low = iLow(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double close = iClose(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Applied Price ...
|
||||||
|
result = GetAppliedPrice(
|
||||||
|
mType,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Applied Price ...
|
||||||
|
*
|
||||||
|
* @param mSymbol: string, Specified Symbol ...
|
||||||
|
* @param mPeriod: ENUM_TIMEFRAMES member, Specified PEriod ...
|
||||||
|
* @param time: int, Specified Bar Time ...
|
||||||
|
* @param mType: ENUM_X_PRICE member, Specified Price Type ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double GetAppliedPrice(
|
||||||
|
string mSymbol = NULL, // Symbol
|
||||||
|
ENUM_TIMEFRAMES mPeriod = NULL, // Period
|
||||||
|
datetime mTime = NULL, // Bar Time
|
||||||
|
ENUM_X_PRICE mType = X_PRICE_CLOSE // Type of Price Selection,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
mTime = NormalizeTime(mTime);
|
||||||
|
mSymbol = NormalizeSymbol(mSymbol);
|
||||||
|
mPeriod = NormalizePeriod(mPeriod);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool has = IsValid(mType);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int barIndex = GetBarIndex(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
mTime //
|
||||||
|
);
|
||||||
|
has = IsValidIndex(barIndex);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Applied Price ...
|
||||||
|
result = GetAppliedPrice(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
barIndex,
|
||||||
|
mType //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// END Price ...
|
// END Price ...
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user