9887 lines
198 KiB
Plaintext
9887 lines
198 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Helper Parser Class Library
|
|
// ----------------------------------------------------
|
|
// Name: XCXFIMAHelperParser
|
|
// 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.xfima.helper.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Implementation ...
|
|
|
|
class XCXFIMAHelperParser : XCBase
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
|
|
//
|
|
// Constructor ...
|
|
XCXFIMAHelperParser(XCXFIMAHelper *_helper)
|
|
{
|
|
//
|
|
helper = _helper;
|
|
symbol = _helper.GetSymbol();
|
|
period = _helper.GetPeriod();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXFIMAHelperParser()
|
|
{
|
|
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 ...
|
|
|
|
//
|
|
// XSAR ...
|
|
|
|
/**
|
|
* Check SAR is Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSARBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetSARState(barIndex);
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check SAR is Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSARBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetSARState(barIndex);
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check SAR is Switched to Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSARSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
int pBarIndex = barIndex + 1;
|
|
|
|
//
|
|
bool isBullish = IsSARBullish(barIndex);
|
|
bool isPBullish = IsSARBullish(pBarIndex);
|
|
|
|
//
|
|
result = isBullish &&
|
|
!isPBullish;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check SAR is Switched to Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSARSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
int pBarIndex = barIndex + 1;
|
|
|
|
//
|
|
bool isBearish = IsSARBearish(barIndex);
|
|
bool isPBearish = IsSARBearish(pBarIndex);
|
|
|
|
//
|
|
result = isBearish &&
|
|
!isPBearish;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bullish SAR(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBullishSARs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsSARBullish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bearish SAR(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBearishSARs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsSARBearish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XMA ...
|
|
|
|
/**
|
|
* Check Fast Ma is Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetMAFastState(barIndex);
|
|
|
|
//
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Slow Ma is Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetMASlowState(barIndex);
|
|
|
|
//
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fast Ma is Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetMAFastState(barIndex);
|
|
|
|
//
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Slow Ma is Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetMASlowState(barIndex);
|
|
|
|
//
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fast Ma is Switched to Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMAFastBullish(barIndex);
|
|
bool isP = IsMAFastBullish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Slow Ma is Switched to Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMASlowBullish(barIndex);
|
|
bool isP = IsMASlowBullish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fast Ma is Switched to Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMAFastBearish(barIndex);
|
|
bool isP = IsMAFastBearish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Slow Ma is Switched to Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMASlowBearish(barIndex);
|
|
bool isP = IsMASlowBearish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fast Ma Over Slow or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastOverSlow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iFast = helper.GetMAFast(barIndex);
|
|
double iSlow = helper.GetMASlow(barIndex);
|
|
|
|
//
|
|
result = iFast > iSlow;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fast Ma Under Slow or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastUnderSlow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iFast = helper.GetMAFast(barIndex);
|
|
double iSlow = helper.GetMASlow(barIndex);
|
|
|
|
//
|
|
result = iFast < iSlow;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fast Ma Over Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iFast = helper.GetMAFast(barIndex);
|
|
double pFast = helper.GetMAFast(barIndex + 1);
|
|
|
|
//
|
|
result = iFast > pFast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Slow Ma Over Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iSlow = helper.GetMASlow(barIndex);
|
|
double pSlow = helper.GetMASlow(barIndex + 1);
|
|
|
|
//
|
|
result = iSlow > pSlow;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fast Ma Under Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iFast = helper.GetMAFast(barIndex);
|
|
double pFast = helper.GetMAFast(barIndex + 1);
|
|
|
|
//
|
|
result = iFast < pFast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Slow Ma Under Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iSlow = helper.GetMASlow(barIndex);
|
|
double pSlow = helper.GetMASlow(barIndex + 1);
|
|
|
|
//
|
|
result = iSlow < pSlow;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Fast is Crossed Over Slow or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastCrossedOverSlow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isFastOverSlow = IsMAFastOverSlow(barIndex);
|
|
bool isPFastOverSlow = IsMAFastOverSlow(barIndex + 1);
|
|
|
|
//
|
|
result = isFastOverSlow &&
|
|
!isPFastOverSlow;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Fast is Crossed Under Slow or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastCrossedUnderSlow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isFastUnderSlow = IsMAFastUnderSlow(barIndex);
|
|
bool isPFastUnderSlow = IsMAFastUnderSlow(barIndex + 1);
|
|
|
|
//
|
|
result = isFastUnderSlow &&
|
|
!isPFastUnderSlow;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Fast is Crossed Over Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastCrossedOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isFastOverLast = IsMAFastOverLast(barIndex);
|
|
bool isPFastOverLast = IsMAFastOverLast(barIndex + 1);
|
|
|
|
//
|
|
result = isFastOverLast &&
|
|
!isPFastOverLast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Fast is Crossed Under Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMAFastCrossedUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isFastUnderLast = IsMAFastUnderLast(barIndex);
|
|
bool isPFastUnderLast = IsMAFastUnderLast(barIndex + 1);
|
|
|
|
//
|
|
result = isFastUnderLast &&
|
|
!isPFastUnderLast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Slow is Crossed Over Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowCrossedOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isSlowOverLast = IsMASlowOverLast(barIndex);
|
|
bool isPSlowOverLast = IsMASlowOverLast(barIndex + 1);
|
|
|
|
//
|
|
result = isSlowOverLast &&
|
|
!isPSlowOverLast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Slow is Crossed Under Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMASlowCrossedUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isSlowUnderLast = IsMASlowUnderLast(barIndex);
|
|
bool isPSlowUnderLast = IsMASlowUnderLast(barIndex + 1);
|
|
|
|
//
|
|
result = isSlowUnderLast &&
|
|
!isPSlowUnderLast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Fast and Slow Crossed Over Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMACrossedOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isFastCrossedOverLast = IsMAFastCrossedOverLast(barIndex);
|
|
bool isSlowCrossedOverLast = IsMASlowCrossedOverLast(barIndex);
|
|
|
|
//
|
|
result = isFastCrossedOverLast &&
|
|
isSlowCrossedOverLast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check MA Fast and Slow Crossed Under Last or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMACrossedUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool isFastCrossedUnderLast = IsMAFastCrossedUnderLast(barIndex);
|
|
bool isSlowCrossedUnderLast = IsMASlowCrossedUnderLast(barIndex);
|
|
|
|
//
|
|
result = isFastCrossedUnderLast &&
|
|
isSlowCrossedUnderLast;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count MA Fast Over Slows ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMAFastOverSlows(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMAFastOverSlow(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count MA Fast Under Slows ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMAFastUnderSlows(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMAFastUnderSlow(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count MA Fast Over Lasts ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMAFastOverLasts(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMAFastOverLast(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count MA Fast Under Lasts ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMAFastUnderLasts(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMAFastUnderLast(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count MA Slow Over Lasts ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMASlowOverLasts(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMASlowOverLast(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count MA Slow Under Lasts ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMASlowUnderLasts(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMASlowUnderLast(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Over MA Fast Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountOverMAFastBars(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetMAFast(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice > iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Under MA Fast Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountUnderMAFastBars(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetMAFast(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice < iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Over MA Slow Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountOverMASlowBars(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetMASlow(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice > iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Under MA Slow Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountUnderMASlowBars(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetMASlow(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice < iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XHK ...
|
|
|
|
/**
|
|
* Check HK is Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified BarIndex ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHKBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iO = helper.GetHKOpen(barIndex);
|
|
double iC = helper.GetHKClose(barIndex);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(iO) &&
|
|
NotEmptyZero(iC) &&
|
|
iC > iO;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check HK is Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified BarIndex ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHKBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
double iO = helper.GetHKOpen(barIndex);
|
|
double iC = helper.GetHKClose(barIndex);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(iO) &&
|
|
NotEmptyZero(iC) &&
|
|
iC < iO;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check HK is Switched to Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified BarIndex ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHKSwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool is = IsHKBullish(barIndex);
|
|
bool isP = IsHKBullish(barIndex + 1);
|
|
|
|
//
|
|
result = is &&
|
|
!isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check HK is Switched to Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified BarIndex ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHKSwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
bool is = IsHKBearish(barIndex);
|
|
bool isP = IsHKBearish(barIndex + 1);
|
|
|
|
//
|
|
result = is &&
|
|
!isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Over HK Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsOverHKBandLower(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetHKBandLower(barIndex);
|
|
result =
|
|
result &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Over HK Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsOverHKBandUpper(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetHKBandUpper(barIndex);
|
|
result =
|
|
result &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Under HK Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsUnderHKBandLower(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetHKBandLower(barIndex);
|
|
result =
|
|
result &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Under HK Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsUnderHKBandUpper(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetHKBandUpper(barIndex);
|
|
result =
|
|
result &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Crossed Over HK Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedOverHKBandLower(
|
|
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;
|
|
}
|
|
|
|
//
|
|
bool isC = IsOverHKBandLower(barIndex, priceType);
|
|
bool isP = IsOverHKBandLower(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Crossed Under HK Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedUnderHKBandLower(
|
|
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;
|
|
}
|
|
|
|
//
|
|
bool isC = IsUnderHKBandLower(barIndex, priceType);
|
|
bool isP = IsUnderHKBandLower(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Crossed Over HK Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedOverHKBandUpper(
|
|
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;
|
|
}
|
|
|
|
//
|
|
bool isC = IsOverHKBandUpper(barIndex, priceType);
|
|
bool isP = IsOverHKBandUpper(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Crossed Under HK Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedUnderHKBandUpper(
|
|
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;
|
|
}
|
|
|
|
//
|
|
bool isC = IsUnderHKBandUpper(barIndex, priceType);
|
|
bool isP = IsUnderHKBandUpper(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bullish HK(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBullishHKs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsHKBullish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bearish HK(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBearishHKs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// DO ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsHKBearish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Over HK Band Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountOverHKBandLower(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetHKBandLower(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice > iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Under HK Band Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountUnderHKBandLower(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetHKBandLower(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice < iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Over HK Band Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountOverHKBandUpper(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetHKBandUpper(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice > iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Under HK Band Bars ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountUnderHKBandUpper(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
int idx = barIndex;
|
|
double iValue = EMPTY_VALUE;
|
|
double iPrice = EMPTY_VALUE;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iBar.Clean();
|
|
has = iBar.Init(symbol, period, idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
iValue = helper.GetHKBandUpper(idx);
|
|
iPrice = iBar.GetPrice(priceType);
|
|
|
|
//
|
|
has = iPrice < iValue;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XPV ...
|
|
|
|
/**
|
|
* Check Peak Same as Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsPeakSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double iC = helper.GetPeak(barIndex);
|
|
double iP = helper.GetPeak(barIndex + 1);
|
|
|
|
//
|
|
result = iC == iP &&
|
|
NotEmptyZero(iC);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Vale Same as Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValeSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double iC = helper.GetVale(barIndex);
|
|
double iP = helper.GetVale(barIndex + 1);
|
|
|
|
//
|
|
result = iC == iP &&
|
|
NotEmptyZero(iC);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Same Peaks ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountSamePeaks(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double iPeak = EMPTY_VALUE;
|
|
double peak = helper.GetPeak(barIndex);
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iPeak = helper.GetPeak(idx);
|
|
has = peak == iPeak;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Same Vales ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountSameVales(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double iVale = EMPTY_VALUE;
|
|
double vale = helper.GetVale(barIndex);
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iVale = helper.GetVale(idx);
|
|
has = vale == iVale;
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Peak Happens over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsPeakOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
double iPeak = helper.GetPeak(barIndex);
|
|
double pPeak = helper.GetPeak(barIndex + 1);
|
|
|
|
//
|
|
result = NotEmptyZero(iPeak) &&
|
|
iPeak > pPeak;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Vale Happens over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValeOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
double iVale = helper.GetVale(barIndex);
|
|
double pVale = helper.GetVale(barIndex + 1);
|
|
|
|
//
|
|
result = NotEmptyZero(iVale) &&
|
|
iVale > pVale;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Peak Happens under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsPeakUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
double iPeak = helper.GetPeak(barIndex);
|
|
double pPeak = helper.GetPeak(barIndex + 1);
|
|
|
|
//
|
|
result = NotEmptyZero(iPeak) &&
|
|
iPeak < pPeak;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Vale Happens under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValeUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
double iVale = helper.GetVale(barIndex);
|
|
double pVale = helper.GetVale(barIndex + 1);
|
|
|
|
//
|
|
result = NotEmptyZero(iVale) &&
|
|
iVale < pVale;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Peak Change ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastPeakOverLast(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsPeakOverLast(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Peak Change ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastPeakUnderLast(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsPeakUnderLast(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Vale Change ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastValeOverLast(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsValeOverLast(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Vale Change ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastValeUnderLast(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsValeUnderLast(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XZG ...
|
|
|
|
/**
|
|
* Check ZigZag has Value and Read it ...
|
|
*
|
|
* @param value: double, reference to holds value ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasZG(
|
|
double &value,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
value = EMPTY_VALUE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
value = helper.GetZigZag(barIndex);
|
|
|
|
//
|
|
result = NotEmptyZero(value);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check ZG is Low or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsZGLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
// Reading Value ...
|
|
double iValue;
|
|
result = HasZG(iValue, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Value ...
|
|
XOHCL iBar;
|
|
result = iBar.Init(symbol, period, barIndex);
|
|
result = result &&
|
|
iBar.low == iValue;
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check ZG is High or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsZGHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
// Reading Value ...
|
|
double iValue;
|
|
result = HasZG(iValue, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Reading Value ...
|
|
XOHCL iBar;
|
|
result = iBar.Init(symbol, period, barIndex);
|
|
result = result &&
|
|
iBar.high == iValue;
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// XATR ...
|
|
|
|
bool GetATRBox(
|
|
XBoxZone &zone,
|
|
int barIndex = 0,
|
|
int loopback = 3 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
zone.Clean();
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 1);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double lowers[];
|
|
double uppers[];
|
|
double iUpper = EMPTY_VALUE;
|
|
double iLower = EMPTY_VALUE;
|
|
double upper = helper.GetATRRawBandUpper(barIndex);
|
|
double lower = helper.GetATRRawBandLower(barIndex);
|
|
int idx = barIndex;
|
|
while (idx <= barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
iUpper = helper.GetATRRawBandUpper(idx);
|
|
iLower = helper.GetATRRawBandLower(idx);
|
|
Add(iUpper, uppers);
|
|
Add(iLower, lowers);
|
|
}
|
|
|
|
//
|
|
zone.symbol = symbol;
|
|
zone.period = period;
|
|
zone.upper = GetMax(uppers);
|
|
zone.lower = GetMin(lowers);
|
|
zone.dir =
|
|
(upper > zone.upper ||
|
|
lower > zone.lower)
|
|
? X_DIRECTION_BULLISH
|
|
: (upper < zone.upper ||
|
|
lower < zone.lower)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
zone.type = ToXString(XFIMA_PIVOT_ATR);
|
|
zone.to = GetBarTime(symbol, period, barIndex);
|
|
zone.at = zone.to;
|
|
zone.from = GetBarTime(symbol, period, barIndex + loopback);
|
|
|
|
//
|
|
result = zone.IsValid();
|
|
|
|
//
|
|
// Cleanup ...
|
|
if (!result)
|
|
{
|
|
zone.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Over ATR Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsOverATRBandLower(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetATRBandLower(barIndex);
|
|
result =
|
|
result &&
|
|
NotEmptyZero(value) &&
|
|
NotEmptyZero(price) &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Over ATR Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsOverATRBandUpper(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetATRBandUpper(barIndex);
|
|
result =
|
|
result &&
|
|
NotEmptyZero(value) &&
|
|
NotEmptyZero(price) &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Under ATR Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsUnderATRBandLower(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetATRBandLower(barIndex);
|
|
result =
|
|
result &&
|
|
NotEmptyZero(value) &&
|
|
NotEmptyZero(price) &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Under ATR Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsUnderATRBandUpper(
|
|
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);
|
|
double price = bar.GetPrice(priceType);
|
|
double value = helper.GetATRBandUpper(barIndex);
|
|
result =
|
|
result &&
|
|
NotEmptyZero(value) &&
|
|
NotEmptyZero(price) &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Crossed Over ATR Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedOverATRBandLower(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsOverATRBandLower(barIndex, priceType);
|
|
bool isP = IsOverATRBandLower(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Crossed Under ATR Band Lower ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedUnderATRBandLower(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsUnderATRBandLower(barIndex, priceType);
|
|
bool isP = IsUnderATRBandLower(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Crossed Over ATR Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedOverATRBandUpper(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsOverATRBandUpper(barIndex, priceType);
|
|
bool isP = IsOverATRBandUpper(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price is Crossed Under ATR Band Upper ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedUnderATRBandUpper(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsUnderATRBandUpper(barIndex, priceType);
|
|
bool isP = IsUnderATRBandUpper(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Cycles Tools ...
|
|
|
|
//
|
|
// SC ...
|
|
|
|
/**
|
|
* Check Short Cycle is Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMABullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetSCMAState(barIndex);
|
|
|
|
//
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMABearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetSCMAState(barIndex);
|
|
|
|
//
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMASwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsSCMABullish(barIndex);
|
|
bool isP = IsSCMABullish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMASwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsSCMABearish(barIndex);
|
|
bool isP = IsSCMABearish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bullish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBullishSCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsSCMABullish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bearish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBearishSCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsSCMABearish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bullish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSCMASwitchedToBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSCMASwitchedToBullish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bearish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSCMASwitchedToBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSCMASwitchedToBearish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMAOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSCMA(barIndex);
|
|
double pValue = helper.GetSCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue > pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMAUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSCMA(barIndex);
|
|
double pValue = helper.GetSCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue < pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMACrossedOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsSCMAOverLast(barIndex);
|
|
bool isP = IsSCMAOverLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCMACrossedUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsSCMAUnderLast(barIndex);
|
|
bool isP = IsSCMAUnderLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCLLSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSLL(barIndex);
|
|
double pValue = helper.GetSLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Lower Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCLowerLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSLL(barIndex);
|
|
double pValue = helper.GetSLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Higher Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCHigherLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSLL(barIndex);
|
|
double pValue = helper.GetSLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCHHSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSHH(barIndex);
|
|
double pValue = helper.GetSHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Lower High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCLowerHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSHH(barIndex);
|
|
double pValue = helper.GetSHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Higher High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSCHigherHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetSHH(barIndex);
|
|
double pValue = helper.GetSHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same LL(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountSCSameLLs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsSCLLSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same HH(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountSCSameHHs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsSCHHSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSCLowerLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSCLowerLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSCHigherLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSCHigherLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSCLowerHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSCLowerHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSCHigherHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSCHigherHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Has Trend or not ...
|
|
*
|
|
* @param trend: XTrend, reference to holds Detected Trend ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasSCTrend(
|
|
XTrend &trend,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
trend.Clean();
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detecte Lower Lows ...
|
|
int cLowerLowIDX = -1;
|
|
int pLowerLowIDX = -1;
|
|
bool hasCLowerLow = FindLastSCLowerLow(cLowerLowIDX, barIndex, loopback);
|
|
bool hasPLowerLow =
|
|
hasCLowerLow &&
|
|
FindLastSCLowerLow(pLowerLowIDX, cLowerLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Lower Highs ...
|
|
int cLowerHighIDX = -1;
|
|
int pLowerHighIDX = -1;
|
|
bool hasCLowerHigh = FindLastSCLowerHigh(cLowerHighIDX, barIndex, loopback);
|
|
bool hasPLowerHigh =
|
|
hasCLowerHigh &&
|
|
FindLastSCLowerHigh(pLowerHighIDX, cLowerHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Lows ...
|
|
int cHigherLowIDX = -1;
|
|
int pHigherLowIDX = -1;
|
|
bool hasCHigherLow = FindLastSCHigherLow(cHigherLowIDX, barIndex, loopback);
|
|
bool hasPHigherLow =
|
|
hasCHigherLow &&
|
|
FindLastSCHigherLow(pHigherLowIDX, cHigherLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Highs ...
|
|
int cHigherHighIDX = -1;
|
|
int pHigherHighIDX = -1;
|
|
bool hasCHigherHigh = FindLastSCHigherHigh(cHigherHighIDX, barIndex, loopback);
|
|
bool hasPHigherHigh =
|
|
hasCHigherHigh &&
|
|
FindLastSCHigherHigh(pHigherHighIDX, cHigherHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Direction ...
|
|
|
|
//
|
|
// Bullish ...
|
|
bool isBullish =
|
|
hasCHigherLow &&
|
|
hasPHigherLow &&
|
|
hasCHigherHigh &&
|
|
hasPHigherHigh;
|
|
|
|
//
|
|
// Bearish ...
|
|
bool isBearish =
|
|
hasCLowerLow &&
|
|
hasPLowerLow &&
|
|
hasCLowerHigh &&
|
|
hasPLowerHigh;
|
|
|
|
//
|
|
// Summarize Result ...
|
|
result = isBullish || isBearish;
|
|
|
|
//
|
|
// Preparing XTrend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
|
|
//
|
|
double toValue = EMPTY_VALUE;
|
|
double fromValue = EMPTY_VALUE;
|
|
|
|
//
|
|
// Validating Directions ...
|
|
|
|
//
|
|
// Bullish Validation ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
datetime cHL = GetBarTime(symbol, period, cHigherLowIDX);
|
|
datetime pHL = GetBarTime(symbol, period, pHigherLowIDX);
|
|
|
|
//
|
|
toTime = cHL;
|
|
fromTime = pHL;
|
|
|
|
//
|
|
toValue = helper.GetSLL(cHigherLowIDX);
|
|
fromValue = helper.GetSLL(pHigherLowIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBullish =
|
|
isBullish &&
|
|
fromValue < toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Bearish Validation ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
datetime cLH = GetBarTime(symbol, period, cLowerHighIDX);
|
|
datetime pLH = GetBarTime(symbol, period, pLowerHighIDX);
|
|
|
|
//
|
|
toTime = cLH;
|
|
fromTime = pLH;
|
|
|
|
//
|
|
toValue = helper.GetSHH(cLowerHighIDX);
|
|
fromValue = helper.GetSHH(pLowerHighIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBearish =
|
|
isBearish &&
|
|
fromValue > toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Validate Values ...
|
|
result =
|
|
IsXValid(toTime) &&
|
|
IsXValid(fromTime) &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
|
|
//
|
|
// Try to Initialized Trend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Initialize Trend ...
|
|
result = trend.Init(
|
|
symbol,
|
|
period,
|
|
TimeCurrent(),
|
|
fromValue,
|
|
fromTime,
|
|
toValue,
|
|
toTime //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Validate Trend ...
|
|
result = trend.IsValid();
|
|
}
|
|
|
|
//
|
|
// Validate Result ...
|
|
result = trend.IsValid() &&
|
|
trend.HasTrend();
|
|
|
|
//
|
|
// Cleanup ...
|
|
if (!result)
|
|
{
|
|
trend.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// MC ...
|
|
|
|
/**
|
|
* Check Short Cycle is Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMABullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetMCMAState(barIndex);
|
|
|
|
//
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMABearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetMCMAState(barIndex);
|
|
|
|
//
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMASwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMCMABullish(barIndex);
|
|
bool isP = IsMCMABullish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMASwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMCMABearish(barIndex);
|
|
bool isP = IsMCMABearish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bullish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBullishMCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMCMABullish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bearish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBearishMCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMCMABearish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bullish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastMCMASwitchedToBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsMCMASwitchedToBullish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bearish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastMCMASwitchedToBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsMCMASwitchedToBearish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMAOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMCMA(barIndex);
|
|
double pValue = helper.GetMCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue > pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMAUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMCMA(barIndex);
|
|
double pValue = helper.GetMCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue < pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMACrossedOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMCMAOverLast(barIndex);
|
|
bool isP = IsMCMAOverLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCMACrossedUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsMCMAUnderLast(barIndex);
|
|
bool isP = IsMCMAUnderLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCLLSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMLL(barIndex);
|
|
double pValue = helper.GetMLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Lower Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCLowerLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMLL(barIndex);
|
|
double pValue = helper.GetMLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Higher Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCHigherLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMLL(barIndex);
|
|
double pValue = helper.GetMLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCHHSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMHH(barIndex);
|
|
double pValue = helper.GetMHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Lower High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCLowerHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMHH(barIndex);
|
|
double pValue = helper.GetMHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Higher High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsMCHigherHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetMHH(barIndex);
|
|
double pValue = helper.GetMHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same LL(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMCSameLLs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMCLLSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same HH(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountMCSameHHs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsMCHHSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastMCLowerLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsMCLowerLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastMCHigherLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsMCHigherLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastMCLowerHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsMCLowerHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastMCHigherHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsMCHigherHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Has Trend or not ...
|
|
*
|
|
* @param trend: XTrend, reference to holds Detected Trend ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasMCTrend(
|
|
XTrend &trend,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
trend.Clean();
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detecte Lower Lows ...
|
|
int cLowerLowIDX = -1;
|
|
int pLowerLowIDX = -1;
|
|
bool hasCLowerLow = FindLastMCLowerLow(cLowerLowIDX, barIndex, loopback);
|
|
bool hasPLowerLow =
|
|
hasCLowerLow &&
|
|
FindLastMCLowerLow(pLowerLowIDX, cLowerLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Lower Highs ...
|
|
int cLowerHighIDX = -1;
|
|
int pLowerHighIDX = -1;
|
|
bool hasCLowerHigh = FindLastMCLowerHigh(cLowerHighIDX, barIndex, loopback);
|
|
bool hasPLowerHigh =
|
|
hasCLowerHigh &&
|
|
FindLastMCLowerHigh(pLowerHighIDX, cLowerHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Lows ...
|
|
int cHigherLowIDX = -1;
|
|
int pHigherLowIDX = -1;
|
|
bool hasCHigherLow = FindLastMCHigherLow(cHigherLowIDX, barIndex, loopback);
|
|
bool hasPHigherLow =
|
|
hasCHigherLow &&
|
|
FindLastMCHigherLow(pHigherLowIDX, cHigherLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Highs ...
|
|
int cHigherHighIDX = -1;
|
|
int pHigherHighIDX = -1;
|
|
bool hasCHigherHigh = FindLastMCHigherHigh(cHigherHighIDX, barIndex, loopback);
|
|
bool hasPHigherHigh =
|
|
hasCHigherHigh &&
|
|
FindLastMCHigherHigh(pHigherHighIDX, cHigherHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Direction ...
|
|
|
|
//
|
|
// Bullish ...
|
|
bool isBullish =
|
|
hasCHigherLow &&
|
|
hasPHigherLow &&
|
|
hasCHigherHigh &&
|
|
hasPHigherHigh;
|
|
|
|
//
|
|
// Bearish ...
|
|
bool isBearish =
|
|
hasCLowerLow &&
|
|
hasPLowerLow &&
|
|
hasCLowerHigh &&
|
|
hasPLowerHigh;
|
|
|
|
//
|
|
// Summarize Result ...
|
|
result = isBullish || isBearish;
|
|
|
|
//
|
|
// Preparing XTrend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
|
|
//
|
|
double toValue = EMPTY_VALUE;
|
|
double fromValue = EMPTY_VALUE;
|
|
|
|
//
|
|
// Validating Directions ...
|
|
|
|
//
|
|
// Bullish Validation ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
datetime cHL = GetBarTime(symbol, period, cHigherLowIDX);
|
|
datetime pHL = GetBarTime(symbol, period, pHigherLowIDX);
|
|
|
|
//
|
|
toTime = cHL;
|
|
fromTime = pHL;
|
|
|
|
//
|
|
toValue = helper.GetMLL(cHigherLowIDX);
|
|
fromValue = helper.GetMLL(pHigherLowIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBullish =
|
|
isBullish &&
|
|
fromValue < toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Bearish Validation ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
datetime cLH = GetBarTime(symbol, period, cLowerHighIDX);
|
|
datetime pLH = GetBarTime(symbol, period, pLowerHighIDX);
|
|
|
|
//
|
|
toTime = cLH;
|
|
fromTime = pLH;
|
|
|
|
//
|
|
toValue = helper.GetMHH(cLowerHighIDX);
|
|
fromValue = helper.GetMHH(pLowerHighIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBearish =
|
|
isBearish &&
|
|
fromValue > toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Validate Values ...
|
|
result =
|
|
IsXValid(toTime) &&
|
|
IsXValid(fromTime) &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
|
|
//
|
|
// Try to Initialized Trend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Initialize Trend ...
|
|
result = trend.Init(
|
|
symbol,
|
|
period,
|
|
TimeCurrent(),
|
|
fromValue,
|
|
fromTime,
|
|
toValue,
|
|
toTime //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Validate Trend ...
|
|
result = trend.IsValid();
|
|
}
|
|
|
|
//
|
|
// Validate Result ...
|
|
result = trend.IsValid() &&
|
|
trend.HasTrend();
|
|
|
|
//
|
|
// Cleanup ...
|
|
if (!result)
|
|
{
|
|
trend.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// LC ...
|
|
|
|
/**
|
|
* Check Short Cycle is Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMABullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetLCMAState(barIndex);
|
|
|
|
//
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMABearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetLCMAState(barIndex);
|
|
|
|
//
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMASwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsLCMABullish(barIndex);
|
|
bool isP = IsLCMABullish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMASwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsLCMABearish(barIndex);
|
|
bool isP = IsLCMABearish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bullish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBullishLCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsLCMABullish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bearish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBearishLCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsLCMABearish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bullish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastLCMASwitchedToBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsLCMASwitchedToBullish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bearish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastLCMASwitchedToBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsLCMASwitchedToBearish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMAOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLCMA(barIndex);
|
|
double pValue = helper.GetLCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue > pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMAUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLCMA(barIndex);
|
|
double pValue = helper.GetLCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue < pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMACrossedOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsLCMAOverLast(barIndex);
|
|
bool isP = IsLCMAOverLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCMACrossedUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsLCMAUnderLast(barIndex);
|
|
bool isP = IsLCMAUnderLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCLLSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLLL(barIndex);
|
|
double pValue = helper.GetLLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Lower Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCLowerLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLLL(barIndex);
|
|
double pValue = helper.GetLLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Higher Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCHigherLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLLL(barIndex);
|
|
double pValue = helper.GetLLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCHHSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLHH(barIndex);
|
|
double pValue = helper.GetLHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Lower High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCLowerHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLHH(barIndex);
|
|
double pValue = helper.GetLHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Higher High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsLCHigherHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetLHH(barIndex);
|
|
double pValue = helper.GetLHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same LL(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountLCSameLLs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsLCLLSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same HH(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountLCSameHHs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsLCHHSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastLCLowerLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsLCLowerLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastLCHigherLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsLCHigherLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastLCLowerHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsLCLowerHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastLCHigherHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsLCHigherHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Has Trend or not ...
|
|
*
|
|
* @param trend: XTrend, reference to holds Detected Trend ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasLCTrend(
|
|
XTrend &trend,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
trend.Clean();
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detecte Lower Lows ...
|
|
int cLowerLowIDX = -1;
|
|
int pLowerLowIDX = -1;
|
|
bool hasCLowerLow = FindLastLCLowerLow(cLowerLowIDX, barIndex, loopback);
|
|
bool hasPLowerLow =
|
|
hasCLowerLow &&
|
|
FindLastLCLowerLow(pLowerLowIDX, cLowerLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Lower Highs ...
|
|
int cLowerHighIDX = -1;
|
|
int pLowerHighIDX = -1;
|
|
bool hasCLowerHigh = FindLastLCLowerHigh(cLowerHighIDX, barIndex, loopback);
|
|
bool hasPLowerHigh =
|
|
hasCLowerHigh &&
|
|
FindLastLCLowerHigh(pLowerHighIDX, cLowerHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Lows ...
|
|
int cHigherLowIDX = -1;
|
|
int pHigherLowIDX = -1;
|
|
bool hasCHigherLow = FindLastLCHigherLow(cHigherLowIDX, barIndex, loopback);
|
|
bool hasPHigherLow =
|
|
hasCHigherLow &&
|
|
FindLastLCHigherLow(pHigherLowIDX, cHigherLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Highs ...
|
|
int cHigherHighIDX = -1;
|
|
int pHigherHighIDX = -1;
|
|
bool hasCHigherHigh = FindLastLCHigherHigh(cHigherHighIDX, barIndex, loopback);
|
|
bool hasPHigherHigh =
|
|
hasCHigherHigh &&
|
|
FindLastLCHigherHigh(pHigherHighIDX, cHigherHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Direction ...
|
|
|
|
//
|
|
// Bullish ...
|
|
bool isBullish =
|
|
hasCHigherLow &&
|
|
hasPHigherLow &&
|
|
hasCHigherHigh &&
|
|
hasPHigherHigh;
|
|
|
|
//
|
|
// Bearish ...
|
|
bool isBearish =
|
|
hasCLowerLow &&
|
|
hasPLowerLow &&
|
|
hasCLowerHigh &&
|
|
hasPLowerHigh;
|
|
|
|
//
|
|
// Summarize Result ...
|
|
result = isBullish || isBearish;
|
|
|
|
//
|
|
// Preparing XTrend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
|
|
//
|
|
double toValue = EMPTY_VALUE;
|
|
double fromValue = EMPTY_VALUE;
|
|
|
|
//
|
|
// Validating Directions ...
|
|
|
|
//
|
|
// Bullish Validation ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
datetime cHL = GetBarTime(symbol, period, cHigherLowIDX);
|
|
datetime pHL = GetBarTime(symbol, period, pHigherLowIDX);
|
|
|
|
//
|
|
toTime = cHL;
|
|
fromTime = pHL;
|
|
|
|
//
|
|
toValue = helper.GetLLL(cHigherLowIDX);
|
|
fromValue = helper.GetLLL(pHigherLowIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBullish =
|
|
isBullish &&
|
|
fromValue < toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Bearish Validation ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
datetime cLH = GetBarTime(symbol, period, cLowerHighIDX);
|
|
datetime pLH = GetBarTime(symbol, period, pLowerHighIDX);
|
|
|
|
//
|
|
toTime = cLH;
|
|
fromTime = pLH;
|
|
|
|
//
|
|
toValue = helper.GetLHH(cLowerHighIDX);
|
|
fromValue = helper.GetLHH(pLowerHighIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBearish =
|
|
isBearish &&
|
|
fromValue > toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Validate Values ...
|
|
result =
|
|
IsXValid(toTime) &&
|
|
IsXValid(fromTime) &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
|
|
//
|
|
// Try to Initialized Trend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Initialize Trend ...
|
|
result = trend.Init(
|
|
symbol,
|
|
period,
|
|
TimeCurrent(),
|
|
fromValue,
|
|
fromTime,
|
|
toValue,
|
|
toTime //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Validate Trend ...
|
|
result = trend.IsValid();
|
|
}
|
|
|
|
//
|
|
// Validate Result ...
|
|
result = trend.IsValid() &&
|
|
trend.HasTrend();
|
|
|
|
//
|
|
// Cleanup ...
|
|
if (!result)
|
|
{
|
|
trend.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// HC ...
|
|
|
|
/**
|
|
* Check Short Cycle is Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMABullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetHCMAState(barIndex);
|
|
|
|
//
|
|
result = state >= 1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMABearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double state = helper.GetHCMAState(barIndex);
|
|
|
|
//
|
|
result = state <= -1;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bullish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMASwitchedToBullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsHCMABullish(barIndex);
|
|
bool isP = IsHCMABullish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Short Cycle is Switched to Bearish ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMASwitchedToBearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsHCMABearish(barIndex);
|
|
bool isP = IsHCMABearish(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bullish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBullishHCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsHCMABullish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Bearish MA(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBearishHCMAs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsHCMABearish(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bullish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastHCMASwitchedToBullish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsHCMASwitchedToBullish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last MA Bearish Switches ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastHCMASwitchedToBearish(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsHCMASwitchedToBearish(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMAOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHCMA(barIndex);
|
|
double pValue = helper.GetHCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue > pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Happens Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMAUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHCMA(barIndex);
|
|
double pValue = helper.GetHCMA(barIndex + 1);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue) &&
|
|
cValue < pValue;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Over Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMACrossedOverLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsHCMAOverLast(barIndex);
|
|
bool isP = IsHCMAOverLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle MA Crossed Under Last ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCMACrossedUnderLast(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsHCMAUnderLast(barIndex);
|
|
bool isP = IsHCMAUnderLast(barIndex + 1);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCLLSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHLL(barIndex);
|
|
double pValue = helper.GetHLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Lower Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCLowerLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHLL(barIndex);
|
|
double pValue = helper.GetHLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Lows is Higher Low ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCHigherLow(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHLL(barIndex);
|
|
double pValue = helper.GetHLL(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Same ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCHHSame(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHHH(barIndex);
|
|
double pValue = helper.GetHHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue == pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Lower High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCLowerHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHHH(barIndex);
|
|
double pValue = helper.GetHHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue < pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Highss is Higher High ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHCHigherHigh(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double cValue = helper.GetHHH(barIndex);
|
|
double pValue = helper.GetHHH(barIndex + 1);
|
|
|
|
//
|
|
result = cValue > pValue &&
|
|
NotEmptyZero(cValue) &&
|
|
NotEmptyZero(pValue);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same LL(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountHCSameLLs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsHCLLSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Cycle Same HH(s) ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountHCSameHHs(
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsHCHHSame(idx);
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastHCLowerLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsHCLowerLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher Low ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastHCHigherLow(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsHCHigherLow(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Lower High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastHCLowerHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsHCLowerHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Last Cycle Higher High ...
|
|
*
|
|
* @param index: int, reference to hold change index ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastHCHigherHigh(
|
|
int &index,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsHCHigherHigh(idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Has Trend or not ...
|
|
*
|
|
* @param trend: XTrend, reference to holds Detected Trend ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasHCTrend(
|
|
XTrend &trend,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
trend.Clean();
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Detecte Lower Lows ...
|
|
int cLowerLowIDX = -1;
|
|
int pLowerLowIDX = -1;
|
|
bool hasCLowerLow = FindLastHCLowerLow(cLowerLowIDX, barIndex, loopback);
|
|
bool hasPLowerLow =
|
|
hasCLowerLow &&
|
|
FindLastHCLowerLow(pLowerLowIDX, cLowerLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Lower Highs ...
|
|
int cLowerHighIDX = -1;
|
|
int pLowerHighIDX = -1;
|
|
bool hasCLowerHigh = FindLastHCLowerHigh(cLowerHighIDX, barIndex, loopback);
|
|
bool hasPLowerHigh =
|
|
hasCLowerHigh &&
|
|
FindLastHCLowerHigh(pLowerHighIDX, cLowerHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Lows ...
|
|
int cHigherLowIDX = -1;
|
|
int pHigherLowIDX = -1;
|
|
bool hasCHigherLow = FindLastHCHigherLow(cHigherLowIDX, barIndex, loopback);
|
|
bool hasPHigherLow =
|
|
hasCHigherLow &&
|
|
FindLastHCHigherLow(pHigherLowIDX, cHigherLowIDX, loopback);
|
|
|
|
//
|
|
// Detect Higher Highs ...
|
|
int cHigherHighIDX = -1;
|
|
int pHigherHighIDX = -1;
|
|
bool hasCHigherHigh = FindLastHCHigherHigh(cHigherHighIDX, barIndex, loopback);
|
|
bool hasPHigherHigh =
|
|
hasCHigherHigh &&
|
|
FindLastHCHigherHigh(pHigherHighIDX, cHigherHighIDX, loopback);
|
|
|
|
//
|
|
// Detect Direction ...
|
|
|
|
//
|
|
// Bullish ...
|
|
bool isBullish =
|
|
hasCHigherLow &&
|
|
hasPHigherLow &&
|
|
hasCHigherHigh &&
|
|
hasPHigherHigh;
|
|
|
|
//
|
|
// Bearish ...
|
|
bool isBearish =
|
|
hasCLowerLow &&
|
|
hasPLowerLow &&
|
|
hasCLowerHigh &&
|
|
hasPLowerHigh;
|
|
|
|
//
|
|
// Summarize Result ...
|
|
result = isBullish || isBearish;
|
|
|
|
//
|
|
// Preparing XTrend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
datetime toTime = NULL;
|
|
datetime fromTime = NULL;
|
|
|
|
//
|
|
double toValue = EMPTY_VALUE;
|
|
double fromValue = EMPTY_VALUE;
|
|
|
|
//
|
|
// Validating Directions ...
|
|
|
|
//
|
|
// Bullish Validation ...
|
|
if (isBullish)
|
|
{
|
|
//
|
|
datetime cHL = GetBarTime(symbol, period, cHigherLowIDX);
|
|
datetime pHL = GetBarTime(symbol, period, pHigherLowIDX);
|
|
|
|
//
|
|
toTime = cHL;
|
|
fromTime = pHL;
|
|
|
|
//
|
|
toValue = helper.GetHLL(cHigherLowIDX);
|
|
fromValue = helper.GetHLL(pHigherLowIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBullish =
|
|
isBullish &&
|
|
fromValue < toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Bearish Validation ...
|
|
if (isBearish)
|
|
{
|
|
//
|
|
datetime cLH = GetBarTime(symbol, period, cLowerHighIDX);
|
|
datetime pLH = GetBarTime(symbol, period, pLowerHighIDX);
|
|
|
|
//
|
|
toTime = cLH;
|
|
fromTime = pLH;
|
|
|
|
//
|
|
toValue = helper.GetHHH(cLowerHighIDX);
|
|
fromValue = helper.GetHHH(pLowerHighIDX);
|
|
|
|
//
|
|
// Validate Conditions ...
|
|
isBearish =
|
|
isBearish &&
|
|
fromValue > toValue &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
}
|
|
|
|
//
|
|
// Validate Values ...
|
|
result =
|
|
IsXValid(toTime) &&
|
|
IsXValid(fromTime) &&
|
|
NotEmptyZero(toValue) &&
|
|
NotEmptyZero(fromValue);
|
|
|
|
//
|
|
// Try to Initialized Trend ...
|
|
if (result)
|
|
{
|
|
//
|
|
// Initialize Trend ...
|
|
result = trend.Init(
|
|
symbol,
|
|
period,
|
|
TimeCurrent(),
|
|
fromValue,
|
|
fromTime,
|
|
toValue,
|
|
toTime //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Validate Trend ...
|
|
result = trend.IsValid();
|
|
}
|
|
|
|
//
|
|
// Validate Result ...
|
|
result = trend.IsValid() &&
|
|
trend.HasTrend();
|
|
|
|
//
|
|
// Cleanup ...
|
|
if (!result)
|
|
{
|
|
trend.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Cycles MA(s) ...
|
|
*
|
|
* @param scMA: double, reference to holds cycle value ...
|
|
* @param mcMA: double, reference to holds cycle value ...
|
|
* @param lcMA: double, reference to holds cycle value ...
|
|
* @param hcMA: double, reference to holds cycle value ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
void GetCycleMAs(
|
|
double &scMA,
|
|
double &mcMA,
|
|
double &lcMA,
|
|
double &hcMA,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
// Prepare ...
|
|
scMA = EMPTY_VALUE;
|
|
mcMA = EMPTY_VALUE;
|
|
lcMA = EMPTY_VALUE;
|
|
hcMA = EMPTY_VALUE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
scMA = helper.GetSCMA(barIndex);
|
|
mcMA = helper.GetMCMA(barIndex);
|
|
lcMA = helper.GetLCMA(barIndex);
|
|
hcMA = helper.GetHCMA(barIndex);
|
|
}
|
|
|
|
/**
|
|
* Retrieve Cycles MA State(s) ...
|
|
*
|
|
* @param scMAState: double, reference to holds cycle value ...
|
|
* @param mcMAState: double, reference to holds cycle value ...
|
|
* @param lcMAState: double, reference to holds cycle value ...
|
|
* @param hcMAState: double, reference to holds cycle value ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
void GetCycleMAStates(
|
|
double &scMAState,
|
|
double &mcMAState,
|
|
double &lcMAState,
|
|
double &hcMAState,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
// Prepare ...
|
|
scMAState = EMPTY_VALUE;
|
|
mcMAState = EMPTY_VALUE;
|
|
lcMAState = EMPTY_VALUE;
|
|
hcMAState = EMPTY_VALUE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
scMAState = helper.GetSCMAState(barIndex);
|
|
mcMAState = helper.GetMCMAState(barIndex);
|
|
lcMAState = helper.GetLCMAState(barIndex);
|
|
hcMAState = helper.GetHCMAState(barIndex);
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Hind and Long is Bullish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCycleMABullish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
IsLCMABullish(barIndex) &&
|
|
IsHCMABullish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Cycle Hind and Long is Bearish or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCycleMABearish(int barIndex = 0)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result =
|
|
IsLCMABearish(barIndex) &&
|
|
IsHCMABearish(barIndex);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Boundary Tools ...
|
|
// =============================
|
|
// Boundary Includes:
|
|
// MA Band ...
|
|
// PB Band ...
|
|
// HK Band ...
|
|
// ATR Band ...
|
|
|
|
/**
|
|
* Reading Boundary Values ...
|
|
*
|
|
* @param maBandUpper: double, reference to holds MA Band Upper value ...
|
|
* @param maBandLower: double, reference to holds MA Band Lower value ...
|
|
* @param pbBandUpper: double, reference to holds PB Band Upper value ...
|
|
* @param pbBandLower: double, reference to holds PB Band Lower value ...
|
|
* @param hkBandUpper: double, reference to holds HK Band Upper value ...
|
|
* @param hkBandLower: double, reference to holds HK Band Lower value ...
|
|
* @param atrBandUpper: double, reference to holds ATR Band Upper value ...
|
|
* @param atrBandLower: double, reference to holds ATR Band Lower value ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
void GetBoundaryValues(
|
|
double &maBandUpper,
|
|
double &maBandLower,
|
|
double &pbBandUpper,
|
|
double &pbBandLower,
|
|
double &hkBandUpper,
|
|
double &hkBandLower,
|
|
double &atrBandUpper,
|
|
double &atrBandLower,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Prepare ...
|
|
maBandUpper = EMPTY_VALUE;
|
|
maBandLower = EMPTY_VALUE;
|
|
pbBandUpper = EMPTY_VALUE;
|
|
pbBandLower = EMPTY_VALUE;
|
|
hkBandUpper = EMPTY_VALUE;
|
|
hkBandLower = EMPTY_VALUE;
|
|
atrBandUpper = EMPTY_VALUE;
|
|
atrBandLower = EMPTY_VALUE;
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
maBandUpper = helper.GetMABandUpper(barIndex);
|
|
maBandLower = helper.GetMABandLower(barIndex);
|
|
pbBandUpper = helper.GetPBBandUpper(barIndex);
|
|
pbBandLower = helper.GetPBBandLower(barIndex);
|
|
hkBandUpper = helper.GetHKBandUpper(barIndex);
|
|
hkBandLower = helper.GetHKBandLower(barIndex);
|
|
atrBandUpper = helper.GetATRBandUpper(barIndex);
|
|
atrBandLower = helper.GetATRBandLower(barIndex);
|
|
}
|
|
|
|
/**
|
|
* Read Boundary Values and Fill as an Array ...
|
|
*
|
|
* @param values: double, collection reference to fill results ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*/
|
|
void GetBoundaryValuesArray(
|
|
double &values[],
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
// Prepare ...
|
|
XClean(values);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Reading Boundary Values ...
|
|
|
|
//
|
|
double maBandUpper = EMPTY_VALUE;
|
|
double maBandLower = EMPTY_VALUE;
|
|
double pbBandUpper = EMPTY_VALUE;
|
|
double pbBandLower = EMPTY_VALUE;
|
|
double hkBandUpper = EMPTY_VALUE;
|
|
double hkBandLower = EMPTY_VALUE;
|
|
double atrBandUpper = EMPTY_VALUE;
|
|
double atrBandLower = EMPTY_VALUE;
|
|
|
|
//
|
|
GetBoundaryValues(
|
|
maBandUpper,
|
|
maBandLower,
|
|
pbBandUpper,
|
|
pbBandLower,
|
|
hkBandUpper,
|
|
hkBandLower,
|
|
atrBandUpper,
|
|
atrBandLower,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
// Validate ...
|
|
has =
|
|
NotEmptyZero(maBandUpper) &&
|
|
NotEmptyZero(maBandLower) &&
|
|
NotEmptyZero(pbBandUpper) &&
|
|
NotEmptyZero(pbBandLower) &&
|
|
NotEmptyZero(hkBandUpper) &&
|
|
NotEmptyZero(hkBandLower) &&
|
|
NotEmptyZero(atrBandUpper) &&
|
|
NotEmptyZero(atrBandLower);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
Add(maBandUpper, values);
|
|
Add(maBandLower, values);
|
|
Add(pbBandUpper, values);
|
|
Add(pbBandLower, values);
|
|
Add(hkBandUpper, values);
|
|
Add(hkBandLower, values);
|
|
Add(atrBandUpper, values);
|
|
Add(atrBandLower, values);
|
|
}
|
|
|
|
/**
|
|
* Read Boundary Min Value ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double GetBoundaryMin(int barIndex = 0)
|
|
{
|
|
//
|
|
double result = EMPTY_VALUE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double values[];
|
|
GetBoundaryValuesArray(values, barIndex);
|
|
result = GetMin(values);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Read Boundary Max Value ...
|
|
*
|
|
* @param barIndex: int, Specified BAr Index ...
|
|
*
|
|
* @return ( double )
|
|
*/
|
|
double GetBoundaryMax(int barIndex = 0)
|
|
{
|
|
//
|
|
double result = EMPTY_VALUE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double values[];
|
|
GetBoundaryValuesArray(values, barIndex);
|
|
result = GetMax(values);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bars and Boundary ...
|
|
|
|
/**
|
|
* Check Bar's Price is Over Boundary Max or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarOverBoundaryMax(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
double price = EMPTY_VALUE;
|
|
double value = GetBoundaryMax(barIndex);
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (result)
|
|
{
|
|
price = bar.GetPrice(priceType);
|
|
}
|
|
result = bar.IsValid() &&
|
|
NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar's Price is Over Boundary Min or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarOverBoundaryMin(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
double price = EMPTY_VALUE;
|
|
double value = GetBoundaryMin(barIndex);
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (result)
|
|
{
|
|
price = bar.GetPrice(priceType);
|
|
}
|
|
result = bar.IsValid() &&
|
|
NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar's Price is Under Boundary Max or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarUnderBoundaryMax(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
double price = EMPTY_VALUE;
|
|
double value = GetBoundaryMax(barIndex);
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (result)
|
|
{
|
|
price = bar.GetPrice(priceType);
|
|
}
|
|
result = bar.IsValid() &&
|
|
NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar's Price is Under Boundary Min or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarUnderBoundaryMin(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL bar;
|
|
double price = EMPTY_VALUE;
|
|
double value = GetBoundaryMin(barIndex);
|
|
result = bar.Init(symbol, period, barIndex);
|
|
if (result)
|
|
{
|
|
price = bar.GetPrice(priceType);
|
|
}
|
|
result = bar.IsValid() &&
|
|
NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar's Price is Crossed Over Boundary Max or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarCrossedOverBoundaryMax(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsBarOverBoundaryMax(barIndex, priceType);
|
|
bool isP = IsBarOverBoundaryMax(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar's Price is Crossed Over Boundary Min or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarCrossedOverBoundaryMin(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsBarOverBoundaryMin(barIndex, priceType);
|
|
bool isP = IsBarOverBoundaryMin(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar's Price is Crossed Under Boundary Max or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarCrossedUnderBoundaryMax(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsBarUnderBoundaryMax(barIndex, priceType);
|
|
bool isP = IsBarUnderBoundaryMax(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Bar's Price is Crossed Under Boundary Min or not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBarCrossedUnderBoundaryMin(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isC = IsBarUnderBoundaryMin(barIndex, priceType);
|
|
bool isP = IsBarUnderBoundaryMin(barIndex + 1, priceType);
|
|
|
|
//
|
|
result = isC && !isP;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Over Boundary Max Bar's Prices ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBarsOverBoundaryMax(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsBarOverBoundaryMax(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
result++;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Over Boundary Min Bar's Prices ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBarsOverBoundaryMin(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsBarOverBoundaryMin(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
result++;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Under Boundary Max Bar's Prices ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBarsUnderBoundaryMax(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsBarUnderBoundaryMax(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
result++;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Under Boundary Min Bar's Prices ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountBarsUnderBoundaryMin(
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
has = IsBarUnderBoundaryMin(idx);
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
result++;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Has Boundary Trend or not ...
|
|
*
|
|
* @param trend: XTrend, refrence to holds Detected trend ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasBoundaryTrend(
|
|
XTrend &trend,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
trend.Clean();
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int pIDX = barIndex + 1;
|
|
|
|
//
|
|
// Select Times ...
|
|
datetime toTime = GetBarTime(symbol, period, barIndex);
|
|
datetime fromTime = GetBarTime(symbol, period, pIDX);
|
|
|
|
//
|
|
// Reading Min and Max ...
|
|
|
|
//
|
|
double bMax = GetBoundaryMax(barIndex);
|
|
double pBMax = GetBoundaryMax(pIDX);
|
|
|
|
//
|
|
double bMin = GetBoundaryMin(barIndex);
|
|
double pBMin = GetBoundaryMin(pIDX);
|
|
|
|
//
|
|
bool isBullish =
|
|
pBMax < bMax &&
|
|
pBMin < bMin;
|
|
|
|
//
|
|
bool isBearish =
|
|
pBMax > bMax &&
|
|
pBMin > bMin;
|
|
|
|
//
|
|
// Initialize Trend ...
|
|
result = isBullish || isBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
result = trend.Init(
|
|
symbol,
|
|
period,
|
|
toTime,
|
|
isBullish
|
|
? pBMin
|
|
: pBMax,
|
|
fromTime,
|
|
isBullish
|
|
? bMin
|
|
: bMax,
|
|
toTime //
|
|
);
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
trend.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
result = trend.IsValid() &&
|
|
trend.HasTrend();
|
|
|
|
//
|
|
// Cleanup ...
|
|
if (!result)
|
|
{
|
|
trend.Clean();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Other Tools ...
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
XCXFIMAHelper *helper;
|
|
|
|
//
|
|
};
|
|
|
|
//
|