ass support for PV and KISuperSlow and MASuper Slow in KI Indicator and also Helper and implement them in BackTester ...
3133 lines
71 KiB
Plaintext
3133 lines
71 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Helper Parser Class Library
|
|
// ----------------------------------------------------
|
|
// Name: XCX121XKIHelperParser
|
|
// Description: provides all Indicator
|
|
// Helper Parse 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
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../../Helpers/x-saherelm.x121.xki.helper.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Implementation ...
|
|
|
|
class XCX121XKIHelperParser : XCBase
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
// Constructor ...
|
|
XCX121XKIHelperParser(XCX121XKIHelper *_helper)
|
|
{
|
|
//
|
|
helper = _helper;
|
|
symbol = _helper.GetSymbol();
|
|
period = _helper.GetPeriod();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCX121XKIHelperParser()
|
|
{
|
|
ZeroMemory(helper);
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Validate ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = helper != NULL &&
|
|
helper.IsValid() &&
|
|
IsXValid(symbol) &&
|
|
IsXValid(period);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Normalize Bar Index ...
|
|
*
|
|
* @param barIndex: int, Provided Bar Index ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int NormalizeBarIndex(int barIndex = 0)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Parsers ...
|
|
// Indicators Base Conditions ...
|
|
|
|
// #region KI Fast ...
|
|
bool IsKIFastBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetKIFastState(barIndex);
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIFastBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetKIFastState(barIndex);
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIFastSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKIFastBullish(barIndex) &&
|
|
!IsKIFastBullish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIFastSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKIFastBearish(barIndex) &&
|
|
!IsKIFastBearish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIFastOverLast(
|
|
int barIndex = 0,
|
|
double distancePoint = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value = helper.GetKIFast(barIndex);
|
|
double pValue = helper.GetKIFast(barIndex + 1);
|
|
double point = GetPoints(symbol);
|
|
double distance = point * distancePoint;
|
|
|
|
//
|
|
result = value >= pValue + distance;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIFastUnderLast(
|
|
int barIndex = 0,
|
|
double distancePoint = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value = helper.GetKIFast(barIndex);
|
|
double pValue = helper.GetKIFast(barIndex + 1);
|
|
double point = GetPoints(symbol);
|
|
double distance = point * distancePoint;
|
|
|
|
//
|
|
result = value <= pValue - distance;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountKIFastTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetKIFast(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region KI Slow ...
|
|
bool IsKISlowBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetKISlowState(barIndex);
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISlowBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetKISlowState(barIndex);
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISlowSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKISlowBullish(barIndex) &&
|
|
!IsKISlowBullish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISlowSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKISlowBearish(barIndex) &&
|
|
!IsKISlowBearish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISlowOverLast(
|
|
int barIndex = 0,
|
|
double distancePoint = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value = helper.GetKISlow(barIndex);
|
|
double pValue = helper.GetKISlow(barIndex + 1);
|
|
double point = GetPoints(symbol);
|
|
double distance = point * distancePoint;
|
|
|
|
//
|
|
result = value >= pValue + distance;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISlowUnderLast(
|
|
int barIndex = 0,
|
|
double distancePoint = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value = helper.GetKISlow(barIndex);
|
|
double pValue = helper.GetKISlow(barIndex + 1);
|
|
double point = GetPoints(symbol);
|
|
double distance = point * distancePoint;
|
|
|
|
//
|
|
result = value <= pValue - distance;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountKISlowTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetKISlow(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region KI Super Slow ...
|
|
bool IsKISuperSlowBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetKISuperSlowState(barIndex);
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISuperSlowBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetKISuperSlowState(barIndex);
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISuperSlowSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKISuperSlowBullish(barIndex) &&
|
|
!IsKISuperSlowBullish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISuperSlowSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKISuperSlowBearish(barIndex) &&
|
|
!IsKISuperSlowBearish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISuperSlowOverLast(
|
|
int barIndex = 0,
|
|
double distancePoint = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value = helper.GetKISuperSlow(barIndex);
|
|
double pValue = helper.GetKISuperSlow(barIndex + 1);
|
|
double point = GetPoints(symbol);
|
|
double distance = point * distancePoint;
|
|
|
|
//
|
|
result = value >= pValue + distance;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKISuperSlowUnderLast(
|
|
int barIndex = 0,
|
|
double distancePoint = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double value = helper.GetKISuperSlow(barIndex);
|
|
double pValue = helper.GetKISuperSlow(barIndex + 1);
|
|
double point = GetPoints(symbol);
|
|
double distance = point * distancePoint;
|
|
|
|
//
|
|
result = value <= pValue - distance;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountKISuperSlowTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetKISuperSlow(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region KI Wave ...
|
|
bool IsKIWaveBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetKIWaveState(barIndex) >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIWaveBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetKIWaveState(barIndex) <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIWaveSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKIWaveBullish(barIndex) &&
|
|
!IsKIWaveBullish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsKIWaveSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsKIWaveBearish(barIndex) &&
|
|
!IsKIWaveBearish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region KI Band ...
|
|
bool IsPriceAboveKIUpper(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
result = price > helper.GetKIUpper(barIndex);
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsPriceBelowKILower(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
result = price < helper.GetKILower(barIndex);
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsPriceInsideKIBands(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
result = price < helper.GetKIUpper(barIndex) &&
|
|
price > helper.GetKILower(barIndex);
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountKIUpperTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetKIUpper(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountKILowerTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetKILower(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region MA Fast/Slow/SuperSlow ...
|
|
|
|
// #region MA Fast ...
|
|
bool IsMAFastBullish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL iBar;
|
|
result = IsValid() &&
|
|
iBar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBar.GetPrice(priceType) > helper.GetMAFast(barIndex);
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMAFastBearish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL iBar;
|
|
result = IsValid() &&
|
|
iBar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBar.GetPrice(priceType) < helper.GetMAFast(barIndex);
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMAFastSwitchedToBullish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsMAFastBullish(barIndex) &&
|
|
!IsMAFastBullish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMAFastSwitchedToBearish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsMAFastBearish(barIndex) &&
|
|
!IsMAFastBearish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountMAFastTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetMAFast(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region MA Slow ...
|
|
bool IsMASlowBullish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL iBar;
|
|
result = IsValid() &&
|
|
iBar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBar.GetPrice(priceType) > helper.GetMASlow(barIndex);
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMASlowBearish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL iBar;
|
|
result = IsValid() &&
|
|
iBar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBar.GetPrice(priceType) < helper.GetMASlow(barIndex);
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMASlowSwitchedToBullish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsMASlowBullish(barIndex) &&
|
|
!IsMASlowBullish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMASlowSwitchedToBearish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsMASlowBearish(barIndex) &&
|
|
!IsMASlowBearish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountMASlowTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetMASlow(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region MA Super Slow ...
|
|
bool IsMASuperSlowBullish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL iBar;
|
|
result = IsValid() &&
|
|
iBar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBar.GetPrice(priceType) > helper.GetMASuperSlow(barIndex);
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMASuperSlowBearish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL iBar;
|
|
result = IsValid() &&
|
|
iBar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = iBar.GetPrice(priceType) < helper.GetMASuperSlow(barIndex);
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMASuperSlowSwitchedToBullish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsMASuperSlowBullish(barIndex) &&
|
|
!IsMASuperSlowBullish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsMASuperSlowSwitchedToBearish(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsMASuperSlowBearish(barIndex) &&
|
|
!IsMASuperSlowBearish(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountMASuperSlowTouches(
|
|
int barIndex = 0,
|
|
int loopback = 5,
|
|
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
|
|
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool has = false;
|
|
double iValue = 0;
|
|
double affectedValue = 0;
|
|
double iConfirnValue = 0;
|
|
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
|
|
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
|
|
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_HIGH
|
|
: X_PRICE_UP;
|
|
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
|
|
? X_PRICE_LOW
|
|
: X_PRICE_DOWN;
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
has = iBar.Init(symbol, period, i);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
affectedValue = helper.GetMASuperSlow(i);
|
|
|
|
//
|
|
// Bullish Touches ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
|
|
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue <= affectedValue &&
|
|
iConfirnValue >= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish Touches ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
|
|
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
|
|
has =
|
|
NotEmptyZero(iValue) &&
|
|
NotEmptyZero(affectedValue) &&
|
|
NotEmptyZero(iConfirnValue) &&
|
|
iValue >= affectedValue &&
|
|
iConfirnValue <= affectedValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
bool IsMACrossoverBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetMAFast(barIndex) > helper.GetMASlow(barIndex);
|
|
return result;
|
|
}
|
|
|
|
bool IsMACrossoverBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetMAFast(barIndex) < helper.GetMASlow(barIndex);
|
|
return result;
|
|
}
|
|
|
|
bool IsMACrossoverSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsMACrossoverBullish(barIndex) &&
|
|
!IsMACrossoverBullish(barIndex + 1);
|
|
return result;
|
|
}
|
|
|
|
bool IsMACrossoverSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsMACrossoverBearish(barIndex) &&
|
|
!IsMACrossoverBearish(barIndex + 1);
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region PV ...
|
|
bool IsPeakSameAsLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetPeak(barIndex) == helper.GetPeak(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsPeakOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetPeak(barIndex) > helper.GetPeak(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsPeakUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetPeak(barIndex) < helper.GetPeak(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountSamePeaks(
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
if (IsPeakSameAsLast(i))
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsValeSameAsLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetVale(barIndex) == helper.GetVale(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsValeOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetVale(barIndex) > helper.GetVale(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsValeUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetVale(barIndex) < helper.GetVale(barIndex + 1);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
int CountSameVales(
|
|
int barIndex = 0,
|
|
int loopback = 10 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
loopback = NormalizeInt(loopback, 2);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
for (int i = barIndex; i < barIndex + loopback; i++)
|
|
{
|
|
//
|
|
if (IsValeSameAsLast(i))
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region ATR ...
|
|
bool IsATRBreakoutUp(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
result = price > helper.GetATRRawUpper(barIndex);
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsATRBreakoutDown(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
result = price < helper.GetATRRawLower(barIndex);
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsVolatilityHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double atr = helper.GetATR(barIndex);
|
|
double atrMa = helper.GetATRSmoothed(barIndex);
|
|
result = atr > atrMa;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsVolatilityLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double atr = helper.GetATR(barIndex);
|
|
double atrMa = helper.GetATRSmoothed(barIndex);
|
|
result = atr < atrMa;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsVolatilitySwitchdToHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double atr = helper.GetATR(barIndex);
|
|
double atrPrev = helper.GetATR(barIndex + 1);
|
|
double atrMa = helper.GetATRSmoothed(barIndex);
|
|
double atrMaPrev = helper.GetATRSmoothed(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
atr > atrMa &&
|
|
atrPrev <= atrMaPrev;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
bool IsVolatilitySwitchdToLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double atr = helper.GetATR(barIndex);
|
|
double atrPrev = helper.GetATR(barIndex + 1);
|
|
double atrMa = helper.GetATRSmoothed(barIndex);
|
|
double atrMaPrev = helper.GetATRSmoothed(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
atr < atrMa &&
|
|
atrPrev >= atrMaPrev;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
// #endregion
|
|
|
|
// #region RSI ...
|
|
bool IsRSIBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetRSI(barIndex) > 50;
|
|
return result;
|
|
}
|
|
|
|
bool IsRSIBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetRSI(barIndex) < 50;
|
|
return result;
|
|
}
|
|
|
|
bool IsRSIOverbought(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetRSI(barIndex) > 70;
|
|
return result;
|
|
}
|
|
|
|
bool IsRSIOversold(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = helper.GetRSI(barIndex) < 30;
|
|
return result;
|
|
}
|
|
|
|
bool IsRSISwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsRSIBullish(barIndex) && !IsRSIBullish(barIndex + 1);
|
|
return result;
|
|
}
|
|
|
|
bool IsRSISwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = IsRSIBearish(barIndex) && !IsRSIBearish(barIndex + 1);
|
|
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
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
XCX121XKIHelper *helper;
|
|
|
|
//
|
|
};
|
|
|
|
//
|