1727 lines
31 KiB
Plaintext
1727 lines
31 KiB
Plaintext
|
|
// #region XDetectors ...
|
|
bool IsKIPOI(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
bool isBullish = IsKIBullishPOI(barIndex);
|
|
bool isBearish = IsKIBearishPOI(barIndex);
|
|
|
|
//
|
|
dir = isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
|
|
//
|
|
result = HasDirection(dir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIBullishPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result =
|
|
kiParser.IsValid() &&
|
|
kiParser.IsKISlowBullish(barIndex) &&
|
|
kiParser.IsKIFastBearish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIBearishPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result =
|
|
kiParser.IsValid() &&
|
|
kiParser.IsKISlowBearish(barIndex) &&
|
|
kiParser.IsKIFastBullish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISignal(
|
|
ENUM_X_DIRECTION &dir, //
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Retrieve KI State ...
|
|
bool isBullish = kiParser.IsKIFastSwitchedToBullish(barIndex + 1) &&
|
|
kiParser.IsKIFastBullish(barIndex) &&
|
|
kiParser.IsKISlowBullish(barIndex);
|
|
bool isBearish = kiParser.IsKIFastSwitchedToBearish(barIndex + 1) &&
|
|
kiParser.IsKIFastBearish(barIndex) &&
|
|
kiParser.IsKISlowBearish(barIndex);
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
dir = isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
result = HasDirection(dir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(symbol, period, barIndex + 1);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bar Direction Same as Dir ...
|
|
|
|
//
|
|
// Price Place Check ...
|
|
double kiFast = kiHelper.GetKIFast(barIndex + 1);
|
|
double kiSlow = kiHelper.GetKISlow(barIndex + 1);
|
|
isBullish =
|
|
isBullish &&
|
|
bar.close > kiFast &&
|
|
kiFast > kiSlow &&
|
|
(kiParser.IsKIFastOverLast(barIndex + 1) ||
|
|
kiParser.IsKISlowOverLast(barIndex + 1));
|
|
isBearish =
|
|
isBearish &&
|
|
bar.close < kiFast &&
|
|
kiFast < kiSlow &&
|
|
(kiParser.IsKIFastUnderLast(barIndex + 1) ||
|
|
kiParser.IsKISlowUnderLast(barIndex + 1));
|
|
|
|
//
|
|
result =
|
|
result &&
|
|
(isBullish ||
|
|
isBearish);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region Detectors ...
|
|
bool IsPOI(
|
|
ENUM_X_DIRECTION &forDir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
forDir = X_DIRECTION_NONE;
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = IsBullishPOI(barIndex);
|
|
bool isBearish = IsBearishPOI(barIndex);
|
|
result = isBullish || isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
forDir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
result = HasDirection(forDir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsTrendBullish(barIndex) &&
|
|
kiParser.IsRSIBullish(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsTrendBearish(barIndex) &&
|
|
kiParser.IsRSIBearish(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBreakoutPOI(
|
|
ENUM_X_DIRECTION &forDir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
forDir = X_DIRECTION_NONE;
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = IsBullishBreakoutPOI(barIndex);
|
|
bool isBearish = IsBearishBreakoutPOI(barIndex);
|
|
result = isBullish || isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
forDir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
result = HasDirection(forDir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishBreakoutPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsBullishBreakout(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishBreakoutPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsBearishBreakout(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsReversalPOI(
|
|
ENUM_X_DIRECTION &forDir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
forDir = X_DIRECTION_NONE;
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = IsBullishReversalPOI(barIndex);
|
|
bool isBearish = IsBearishReversalPOI(barIndex);
|
|
result = isBullish || isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
forDir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
result = HasDirection(forDir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishReversalPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsBullishReversal(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishReversalPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsBearishReversal(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsContinuationPOI(
|
|
ENUM_X_DIRECTION &forDir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
forDir = X_DIRECTION_NONE;
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = IsBullishContinuationPOI(barIndex);
|
|
bool isBearish = IsBearishContinuationPOI(barIndex);
|
|
result = isBullish || isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
forDir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
result = HasDirection(forDir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishContinuationPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsTrendStrongBullish(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL swingBar;
|
|
result = result &&
|
|
IsFlagPattern(bar, dir, swingBar) &&
|
|
IsXBullish(dir);
|
|
|
|
//
|
|
bar.Clean();
|
|
swingBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishContinuationPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = kiParser.IsTrendStrongBearish(barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
ENUM_X_DIRECTION dir;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL swingBar;
|
|
result = result &&
|
|
IsFlagPattern(bar, dir, swingBar) &&
|
|
IsXBearish(dir);
|
|
|
|
//
|
|
bar.Clean();
|
|
swingBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsExhaustionPOI(
|
|
ENUM_X_DIRECTION &forDir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
forDir = X_DIRECTION_NONE;
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = IsBullishExhaustionPOI(barIndex);
|
|
bool isBearish = IsBearishExhaustionPOI(barIndex);
|
|
result = isBullish || isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
forDir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
result = HasDirection(forDir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishExhaustionPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isTrendOk = kiParser.IsTrendStrongBullish(barIndex);
|
|
bool isRSIOk = kiParser.IsRSIOverbought(barIndex);
|
|
result = isTrendOk && isRSIOk;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishExhaustionPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isTrendOk = kiParser.IsTrendStrongBearish(barIndex);
|
|
bool isRSIOk = kiParser.IsRSIOversold(barIndex);
|
|
result = isTrendOk && isRSIOk;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsTrendExhaustedPOI(
|
|
ENUM_X_DIRECTION &forDir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
forDir = X_DIRECTION_NONE;
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isBullish = IsBullishTrendExhaustedPOI(barIndex);
|
|
bool isBearish = IsBearishTrendExhaustedPOI(barIndex);
|
|
result = isBullish || isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
forDir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
result = HasDirection(forDir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishTrendExhaustedPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Trend was strong in last 3 bars ...
|
|
bool isTrendOk = kiParser.IsTrendStrongBullish(barIndex + 1);
|
|
for (int i = 1; i <= 3; i++)
|
|
{
|
|
//
|
|
if (kiParser.IsTrendStrongBullish(barIndex + i))
|
|
{
|
|
isTrendOk = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// RSI rolling over from overbought ...
|
|
double rsiNow = kiHelper.GetRSI(barIndex);
|
|
double rsiPrev = kiHelper.GetRSI(barIndex + 1);
|
|
bool rsiFlip = (rsiPrev > 70 && rsiNow < rsiPrev);
|
|
bool isRSIOk = rsiFlip || kiParser.IsRSIOverbought(barIndex);
|
|
|
|
//
|
|
bool volCooling = kiHelper.GetATR(barIndex) <= kiHelper.GetATRSmoothed(barIndex) * 1.05;
|
|
bool isVolatilityOk = volCooling || kiParser.IsVolatilityLow(barIndex);
|
|
|
|
//
|
|
result = isRSIOk &&
|
|
isTrendOk &&
|
|
isVolatilityOk;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BEARISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishTrendExhaustedPOI(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
bool isTrendOk = kiParser.IsTrendStrongBearish(barIndex + 1);
|
|
for (int i = 1; i <= 3; i++)
|
|
{
|
|
//
|
|
if (kiParser.IsTrendStrongBearish(barIndex + i))
|
|
{
|
|
isTrendOk = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// RSI rolling over from overbought ...
|
|
double rsiNow = kiHelper.GetRSI(barIndex);
|
|
double rsiPrev = kiHelper.GetRSI(barIndex + 1);
|
|
bool rsiFlip = (rsiPrev < 30 && rsiNow > rsiPrev);
|
|
bool isRSIOk = rsiFlip || kiParser.IsRSIOversold(barIndex);
|
|
|
|
//
|
|
bool volCooling = kiHelper.GetATR(barIndex) <= kiHelper.GetATRSmoothed(barIndex) * 1.05;
|
|
bool isVolatilityOk = volCooling || kiParser.IsVolatilityLow(barIndex);
|
|
|
|
//
|
|
result = isRSIOk &&
|
|
isTrendOk &&
|
|
isVolatilityOk;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Add candlestick confirmation ...
|
|
XOHCL bar;
|
|
result = result &&
|
|
bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = result &&
|
|
HasCandlestickDirection(
|
|
bar,
|
|
X_DIRECTION_BULLISH //
|
|
);
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region POI Detectors ...
|
|
bool NearestKIFastBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKIFastBullish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool NearestKIFastBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKIFastBearish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool NearestKIFastSwitchedToBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKIFastSwitchedToBullish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool NearestKIFastSwitchedToBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKIFastSwitchedToBearish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool NearestKISlowBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKISlowBullish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool NearestKISlowBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKISlowBearish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool NearestKISlowSwitchedToBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKISlowSwitchedToBullish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool NearestKISlowSwitchedToBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = kiParser.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Loop Back ...
|
|
bool isPassed = false;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
isPassed = kiParser.IsKISlowSwitchedToBearish(i);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region Composite ...
|
|
bool IsTrendBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKIFastBullish(barIndex) &&
|
|
IsKISlowBullish(barIndex) &&
|
|
IsMACrossoverBullish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsTrendBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKIFastBearish(barIndex) &&
|
|
IsKISlowBearish(barIndex) &&
|
|
IsMACrossoverBearish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishMomentumTrend(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsTrendBullish(barIndex) &&
|
|
IsRSIBullish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishMomentumTrend(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsTrendBearish(barIndex) &&
|
|
IsRSIBearish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishBreakout(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
IsPriceAboveKIUpper(barIndex) &&
|
|
IsATRBreakoutUp(barIndex) &&
|
|
IsVolatilityHigh(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishBreakout(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
IsPriceBelowKILower(barIndex) &&
|
|
IsATRBreakoutDown(barIndex) &&
|
|
IsVolatilityHigh(barIndex);
|
|
return result;
|
|
}
|
|
|
|
bool IsBullishReversal(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// RSI oversold and turning upward ...
|
|
double rsiNow = helper.GetRSI(barIndex);
|
|
double rsiPrev = helper.GetRSI(barIndex + 1);
|
|
bool rsiFlip = (rsiNow > rsiPrev) && (rsiPrev < 30);
|
|
|
|
//
|
|
// ATR check (volatility supportive) ...
|
|
double atrNow = helper.GetATR(barIndex);
|
|
double atrPrev = helper.GetATR(barIndex + 1);
|
|
double atrMaNow = helper.GetATRSmoothed(barIndex);
|
|
double atrMaPrev = helper.GetATRSmoothed(barIndex + 1);
|
|
bool atrOk = atrNow > atrMaNow || atrNow > atrPrev || atrMaNow > atrMaPrev;
|
|
|
|
//
|
|
// MA crossover bullish ...
|
|
double maFastNow = helper.GetMAFast(barIndex);
|
|
double maSlowNow = helper.GetMASlow(barIndex);
|
|
bool maOk = maFastNow > maSlowNow;
|
|
|
|
//
|
|
result = rsiFlip && (atrOk || maOk);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsBearishReversal(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// RSI overbought and turning downward ...
|
|
double rsiNow = helper.GetRSI(barIndex);
|
|
double rsiPrev = helper.GetRSI(barIndex + 1);
|
|
bool rsiFlip = (rsiNow < rsiPrev) && (rsiPrev > 70);
|
|
|
|
//
|
|
// ATR check (volatility supportive) ...
|
|
double atrNow = helper.GetATR(barIndex);
|
|
double atrPrev = helper.GetATR(barIndex + 1);
|
|
double atrMaNow = helper.GetATRSmoothed(barIndex);
|
|
double atrMaPrev = helper.GetATRSmoothed(barIndex + 1);
|
|
bool atrOk = atrNow > atrMaNow || atrNow > atrPrev || atrMaNow > atrMaPrev;
|
|
|
|
//
|
|
// MA crossover bearish ...
|
|
double maFastNow = helper.GetMAFast(barIndex);
|
|
double maSlowNow = helper.GetMASlow(barIndex);
|
|
bool maOk = maFastNow < maSlowNow;
|
|
|
|
//
|
|
result = rsiFlip && (atrOk || maOk);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsSafeBullishEntry(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsBullishMomentumTrend(barIndex) && !IsRSIOverbought(barIndex);
|
|
return result;
|
|
}
|
|
|
|
bool IsSafeBearishEntry(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsBearishMomentumTrend(barIndex) && !IsRSIOversold(barIndex);
|
|
return result;
|
|
}
|
|
|
|
bool IsTrendStrongBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Strong bullish trend requires:
|
|
// - KI Fast bullish
|
|
// - KI Slow bullish
|
|
// - MA crossover bullish
|
|
// - RSI > 60
|
|
// - Volatility high
|
|
result = IsKIFastBullish(barIndex) &&
|
|
IsKISlowBullish(barIndex) &&
|
|
IsMACrossoverBullish(barIndex) &&
|
|
(helper.GetRSI(barIndex) > 60) &&
|
|
IsVolatilityHigh(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsTrendStrongBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Strong bearish trend requires:
|
|
// - KI Fast bearish
|
|
// - KI Slow bearish
|
|
// - MA crossover bearish
|
|
// - RSI < 40
|
|
// - Volatility high
|
|
result = IsKIFastBearish(barIndex) &&
|
|
IsKISlowBearish(barIndex) &&
|
|
IsMACrossoverBearish(barIndex) &&
|
|
(helper.GetRSI(barIndex) < 40) &&
|
|
IsVolatilityHigh(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Counting Touches ...
|
|
*
|
|
* @param bullish: int reference to holds bullih touches ...
|
|
* @param bearish: int reference to holds bearish touches ...
|
|
* @param barIndex: int, start Bar Index ...
|
|
* @param loopback: int, loopback length for counting ...
|
|
* @param countKIFast: boolean, Count KI Fast ...
|
|
* @param countKISlow: boolean, Count KI Slow ...
|
|
* @param countKIUpper: boolean, Count KI Upper ...
|
|
* @param countKILower: boolean, Count KI Lower ...
|
|
* @param countMAFast: boolean, Count MA Fast ...
|
|
* @param countMASlow: boolean, Count MA Slow ...
|
|
* @param forceClean: boolean, Force Clean results before Start Counting ...
|
|
* @param priceType: ENUM_X_BOUNDARY_PRICE, Specified Price Type for Boundary Countinf ...
|
|
*/
|
|
void CountTouches(
|
|
int &bullish,
|
|
int &bearish,
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
bool countKIFast = true,
|
|
bool countKISlow = true,
|
|
bool countKIUpper = true,
|
|
bool countKILower = true,
|
|
bool countMAFast = true,
|
|
bool countMASlow = true,
|
|
bool forceClean = true,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
if (forceClean)
|
|
{
|
|
bullish = 0;
|
|
bearish = 0;
|
|
}
|
|
|
|
//
|
|
// KI Fast ...
|
|
if (countKIFast)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bullish += CountKIFastTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BULLISH,
|
|
priceType //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
bearish += CountKIFastTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BEARISH,
|
|
priceType //
|
|
);
|
|
}
|
|
|
|
//
|
|
// KI Slow ...
|
|
if (countKISlow)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bullish += CountKISlowTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BULLISH,
|
|
priceType //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
bearish += CountKISlowTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BEARISH,
|
|
priceType //
|
|
);
|
|
}
|
|
|
|
//
|
|
// KI Upper ...
|
|
if (countKIUpper)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bullish += CountKIUpperTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BULLISH,
|
|
priceType //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
bearish += CountKIUpperTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BEARISH,
|
|
priceType //
|
|
);
|
|
}
|
|
|
|
//
|
|
// KI Lower ...
|
|
if (countKILower)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bullish += CountKILowerTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BULLISH,
|
|
priceType //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
bearish += CountKILowerTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BEARISH,
|
|
priceType //
|
|
);
|
|
}
|
|
|
|
//
|
|
// KI MA Fast ...
|
|
if (countMAFast)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bullish += CountMAFastTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BULLISH,
|
|
priceType //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
bearish += CountMAFastTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BEARISH,
|
|
priceType //
|
|
);
|
|
}
|
|
|
|
//
|
|
// KI MA Slow ...
|
|
if (countMASlow)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bullish += CountMASlowTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BULLISH,
|
|
priceType //
|
|
);
|
|
|
|
//
|
|
// Bearish ...
|
|
bearish += CountMASlowTouches(
|
|
barIndex,
|
|
loopback,
|
|
X_DIRECTION_BEARISH,
|
|
priceType //
|
|
);
|
|
}
|
|
}
|
|
// #endregion
|