7308 lines
167 KiB
Plaintext
7308 lines
167 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Helper Class Library
|
|
// ----------------------------------------------
|
|
// Name: XCXFIMAHelper
|
|
// Description: provides all Indicator
|
|
// Helper requirements ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Classes/x-saherelm.x-helper.class.mq5"
|
|
#include "../Classes/x-saherelm.x-market.pattern.class.mq5"
|
|
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
|
|
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
enum ENUM_XFIMA_PIVOTS
|
|
{
|
|
XFIMA_PIVOT_NONE = 0,
|
|
XFIMA_PIVOT_PV = 1,
|
|
XFIMA_PIVOT_HK = 2,
|
|
XFIMA_PIVOT_ZIGZAG = 3,
|
|
XFIMA_PIVOT_MA_CROSS = 4,
|
|
XFIMA_PIVOT_HK_SWITCH = 5,
|
|
XFIMA_PIVOT_SAR_SWITCH = 6,
|
|
XFIMA_PIVOT_BOUNDARY_SWITCH = 7,
|
|
};
|
|
|
|
bool IsXValid(ENUM_XFIMA_PIVOTS value)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result = value != XFIMA_PIVOT_NONE;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
string ToXString(ENUM_XFIMA_PIVOTS value)
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
if (!IsXValid(value))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
switch (value)
|
|
{
|
|
//
|
|
case XFIMA_PIVOT_NONE:
|
|
result = "NONE";
|
|
break;
|
|
|
|
//
|
|
case XFIMA_PIVOT_PV:
|
|
result = "XPV";
|
|
break;
|
|
|
|
//
|
|
case XFIMA_PIVOT_HK:
|
|
result = "XHK";
|
|
break;
|
|
|
|
//
|
|
case XFIMA_PIVOT_ZIGZAG:
|
|
result = "XZGP";
|
|
break;
|
|
|
|
//
|
|
case XFIMA_PIVOT_MA_CROSS:
|
|
result = "XMACRS";
|
|
break;
|
|
|
|
//
|
|
case XFIMA_PIVOT_HK_SWITCH:
|
|
result = "XHKSWCH";
|
|
break;
|
|
|
|
//
|
|
case XFIMA_PIVOT_SAR_SWITCH:
|
|
result = "XSARSWCH";
|
|
break;
|
|
|
|
//
|
|
case XFIMA_PIVOT_BOUNDARY_SWITCH:
|
|
result = "XBNDSWCH";
|
|
break;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
ENUM_XFIMA_PIVOTS ToXFIMAPivots(string value)
|
|
{
|
|
//
|
|
ENUM_XFIMA_PIVOTS result = XFIMA_PIVOT_NONE;
|
|
|
|
//
|
|
if (!IsXValid(value))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (value == ToXString(XFIMA_PIVOT_NONE))
|
|
{
|
|
result = XFIMA_PIVOT_NONE;
|
|
}
|
|
else if (value == ToXString(XFIMA_PIVOT_PV))
|
|
{
|
|
result = XFIMA_PIVOT_PV;
|
|
}
|
|
else if (value == ToXString(XFIMA_PIVOT_HK))
|
|
{
|
|
result = XFIMA_PIVOT_HK;
|
|
}
|
|
else if (value == ToXString(XFIMA_PIVOT_ZIGZAG))
|
|
{
|
|
result = XFIMA_PIVOT_ZIGZAG;
|
|
}
|
|
else if (value == ToXString(XFIMA_PIVOT_MA_CROSS))
|
|
{
|
|
result = XFIMA_PIVOT_MA_CROSS;
|
|
}
|
|
else if (value == ToXString(XFIMA_PIVOT_HK_SWITCH))
|
|
{
|
|
result = XFIMA_PIVOT_HK_SWITCH;
|
|
}
|
|
else if (value == ToXString(XFIMA_PIVOT_SAR_SWITCH))
|
|
{
|
|
result = XFIMA_PIVOT_SAR_SWITCH;
|
|
}
|
|
else if (value == ToXString(XFIMA_PIVOT_BOUNDARY_SWITCH))
|
|
{
|
|
result = XFIMA_PIVOT_BOUNDARY_SWITCH;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Buffers ...
|
|
enum ENUM_XFIMA_BUFFERS
|
|
{
|
|
//
|
|
// Plot Buffers ...
|
|
XFIMA_MA_FAST_LINE = 0,
|
|
XFIMA_MA_FAST_COLOR_LINE = 1,
|
|
XFIMA_MA_SLOW_LINE = 2,
|
|
XFIMA_MA_SLOW_COLOR_LINE = 3,
|
|
XFIMA_SAR_LINE = 4,
|
|
XFIMA_SAR_COLOR_LINE = 5,
|
|
XFIMA_PEAK_LINE = 6,
|
|
XFIMA_VALE_LINE = 7,
|
|
XFIMA_FIBO_UPPER_LINE = 8,
|
|
XFIMA_FIBO_MIDDLE_LINE = 9,
|
|
XFIMA_FIBO_LOWER_LINE = 10,
|
|
XFIMA_ZIGZAG_LINE = 11,
|
|
XFIMA_MA_BOND_UPPER_LINE = 12,
|
|
XFIMA_MA_BOND_LOWER_LINE = 13,
|
|
XFIMA_HK_OPEN_LINE = 14,
|
|
XFIMA_HK_HIGH_LINE = 15,
|
|
XFIMA_HK_LOW_LINE = 16,
|
|
XFIMA_HK_CLOSE_LINE = 17,
|
|
XFIMA_HK_COLOR_LINE = 18,
|
|
XFIMA_HK_BOND_UPPER_LINE = 19,
|
|
XFIMA_HK_BOND_LOWER_LINE = 20,
|
|
XFIMA_PB_BOND_UPPER_LINE = 21,
|
|
XFIMA_PB_BOND_LOWER_LINE = 22,
|
|
//
|
|
// Data Buffers ...
|
|
XFIMA_MA_FAST_STATE_LINE = 23,
|
|
XFIMA_MA_SLOW_STATE_LINE = 24,
|
|
XFIMA_SAR_STATE_LINE = 25,
|
|
XFIMA_SC_HH_LINE = 26,
|
|
XFIMA_SC_LL_LINE = 27,
|
|
XFIMA_MC_HH_LINE = 28,
|
|
XFIMA_MC_LL_LINE = 29,
|
|
XFIMA_LC_HH_LINE = 30,
|
|
XFIMA_LC_LL_LINE = 31,
|
|
XFIMA_HC_HH_LINE = 32,
|
|
XFIMA_HC_LL_LINE = 33,
|
|
XFIMA_ZIGZAG_HIGHS_LINE = 34,
|
|
XFIMA_ZIGZAG_HIGHS_TIME_LINE = 35,
|
|
XFIMA_ZIGZAG_LOWS_LINE = 36,
|
|
XFIMA_ZIGZAG_LOWS_TIME_LINE = 37,
|
|
XFIMA_HK_RAW_OPEN_LINE = 38,
|
|
XFIMA_HK_RAW_HIGH_LINE = 39,
|
|
XFIMA_HK_RAW_LOW_LINE = 40,
|
|
XFIMA_HK_RAW_CLOSE_LINE = 41,
|
|
XFIMA_PB_BOND_RAW_UPPER_LINE = 42,
|
|
XFIMA_PB_BOND_RAW_LOWER_LINE = 43,
|
|
};
|
|
|
|
//
|
|
// Input Models ...
|
|
struct XFIMAInputs
|
|
{
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Calculation ...
|
|
ENUM_X_PERIOD_METHOD scMethod; // How to Find Short Period
|
|
ENUM_TIMEFRAMES scPeriod; // Short Period
|
|
ENUM_X_PERIOD_METHOD mcMethod; // How to Find Medium Period
|
|
ENUM_TIMEFRAMES mcPeriod; // Medium Period
|
|
ENUM_X_PERIOD_METHOD lcMethod; // How to Find Long Period
|
|
ENUM_TIMEFRAMES lcPeriod; // Long Period
|
|
ENUM_X_PERIOD_METHOD hcMethod; // How to Find Hind Period
|
|
ENUM_TIMEFRAMES hcPeriod; // Hind Period
|
|
ENUM_SERIESMODE upperMode; // Peak Method
|
|
ENUM_SERIESMODE lowerMode; // Vale Method
|
|
ENUM_X_FIBO_LEVELS fiboUpperZoneLevel; // Upper Zone Level
|
|
ENUM_X_FIBO_LEVELS fiboMiddleZoneLevel; // Upper Zone Level
|
|
ENUM_X_FIBO_LEVELS fiboLowerZoneLevel; // Lower Zone Level
|
|
double sarStep; // SAR Step
|
|
double sarMax; // SAR Maximum
|
|
ENUM_MA_METHOD maMethod; // MA Method
|
|
ENUM_APPLIED_PRICE maAppliedTo; // MA Applied To
|
|
int maFastLength; // Fast MA Length
|
|
int maSlowLength; // Slow MA Length
|
|
int maBondLength; // MA Bond Length
|
|
int zigzagDepth; // ZigZag Depth
|
|
int zigzagDeviation; // ZigZag Deviation
|
|
int zigzagBackStep; // ZigZag Back Step
|
|
ENUM_X_PRICE zigzagUppersMode; // ZigZag High Detect Mode
|
|
ENUM_X_PRICE zigzagLowersMode; // ZigZag Low Detect Mode
|
|
bool hkIgnoreShadows; // HK Remove noises
|
|
int hkSmoothingLength; // HK Smoothing Length
|
|
ENUM_X_MA_METHOD hkSmoothingMode; // HK Smoothing Method
|
|
|
|
//
|
|
// Presentation ...
|
|
bool showPV; // Show PV
|
|
bool showHK; // Show HK
|
|
bool showSAR; // Show Sar
|
|
bool showMAFast; // Show MA Fast
|
|
bool showMASlow; // Show MA Slow
|
|
bool showMABond; // Show MA Bond
|
|
bool showHKBond; // Show HK Bond
|
|
bool showZigZag; // Show ZigZag
|
|
bool showFiboZone; // Show Fibo Zone
|
|
int startCalculationForLastBars; // Calculate Last n Bars
|
|
int sarArrowCode; // Parabolic Sar Arrow Code
|
|
int peakArrowCode; // Peaks Arrow Code
|
|
int valeArrowCode; // Vales Arrow Code
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XFIMAInputs()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Clean ...
|
|
void Clean()
|
|
{
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
//
|
|
// Default ...
|
|
void Default()
|
|
{
|
|
//
|
|
// Calculations ...
|
|
scMethod = X_PERIOD_AUTO; // How to Find Short Period
|
|
scPeriod = NULL; // Short Period
|
|
mcMethod = X_PERIOD_AUTO; // How to Find Medium Period
|
|
mcPeriod = NULL; // Medium Period
|
|
lcMethod = X_PERIOD_AUTO; // How to Find Long Period
|
|
lcPeriod = NULL; // Long Period
|
|
hcMethod = X_PERIOD_AUTO; // How to Find Hind Period
|
|
hcPeriod = NULL; // Hind Period
|
|
upperMode = MODE_HIGH; // Peak Method
|
|
lowerMode = MODE_LOW; // Vale Method
|
|
fiboUpperZoneLevel = X_FIBO_LEVEL_382; // Upper Zone Level
|
|
fiboMiddleZoneLevel = X_FIBO_LEVEL_500; // Upper Zone Level
|
|
fiboLowerZoneLevel = X_FIBO_LEVEL_618; // Lower Zone Level
|
|
sarStep = 0.02; // SAR Step
|
|
sarMax = 0.2; // SAR Maximum
|
|
maMethod = MODE_EMA; // MA Method
|
|
maAppliedTo = PRICE_CLOSE; // MA Applied To
|
|
maFastLength = 7; // Fast MA Length
|
|
maSlowLength = 20; // Slow MA Length
|
|
maBondLength = 7; // MA Bond Length
|
|
zigzagDepth = 12; // ZigZag Depth
|
|
zigzagDeviation = 5; // ZigZag Deviation
|
|
zigzagBackStep = 3; // ZigZag Back Step
|
|
zigzagUppersMode = X_PRICE_HIGH; // ZigZag High Detect Mode
|
|
zigzagLowersMode = X_PRICE_LOW; // ZigZag Low Detect Mode
|
|
hkIgnoreShadows = true; // HK Remove noises
|
|
hkSmoothingLength = 21; // HK Smoothing Length
|
|
hkSmoothingMode = X_MA_MODE_EMA; // HK Smoothing Method
|
|
|
|
//
|
|
// Presentation ...
|
|
showPV = true; // Show PV
|
|
showHK = true; // Show HK
|
|
showSAR = true; // Show Sar
|
|
showMAFast = true; // Show MA Fast
|
|
showMASlow = true; // Show MA Slow
|
|
showMABond = true; // Show MA Bond
|
|
showHKBond = true; // Show HK Bond
|
|
showZigZag = true; // Show ZigZag
|
|
showFiboZone = true; // Show Fibo Zone
|
|
startCalculationForLastBars = 1500; // Calculate Last n Bars
|
|
sarArrowCode = 159; // Parabolic Sar Arrow Code
|
|
peakArrowCode = 159; // Peaks Arrow Code
|
|
valeArrowCode = 159; // Vales Arrow Code
|
|
}
|
|
|
|
//
|
|
// Hide all Visible Buffers ...
|
|
void Hide()
|
|
{
|
|
//
|
|
showPV = false;
|
|
showHK = false;
|
|
showSAR = false;
|
|
showMAFast = false;
|
|
showMASlow = false;
|
|
showMABond = false;
|
|
showHKBond = false;
|
|
showZigZag = false;
|
|
showFiboZone = false;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
// MA ...
|
|
maFastLength >= 2 &&
|
|
maSlowLength >= 2 &&
|
|
maBondLength >= 2 &&
|
|
maSlowLength > maFastLength &&
|
|
//
|
|
// SAR ...
|
|
sarMax > 0 &&
|
|
sarStep > 0 &&
|
|
sarMax > sarStep &&
|
|
//
|
|
// CYCLES ...
|
|
(IsSpecifiedValid(scMethod, scPeriod) &&
|
|
IsSpecifiedValid(mcMethod, mcPeriod) &&
|
|
IsSpecifiedValid(lcMethod, lcPeriod) &&
|
|
IsSpecifiedValid(hcMethod, hcPeriod)) &&
|
|
//
|
|
// ZIGZAG ...
|
|
zigzagDepth > 0 &&
|
|
zigzagDeviation > 0 &&
|
|
zigzagBackStep > 0 &&
|
|
//
|
|
// Validate Upper Mode Detection ...
|
|
IsXValid(zigzagUppersMode) &&
|
|
//
|
|
// Validate Lower Mode Detection ...
|
|
IsXValid(zigzagLowersMode)
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
// Conditions ...
|
|
struct XFIMAConditions
|
|
{
|
|
//
|
|
// Common ...
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
datetime time;
|
|
|
|
//
|
|
datetime to;
|
|
datetime from;
|
|
XOHCL bars[];
|
|
|
|
//
|
|
// Buffers ...
|
|
double maFastBuffer[];
|
|
double maFastColorBuffer[];
|
|
double maFastStateBuffer[];
|
|
double maSlowBuffer[];
|
|
double maSlowColorBuffer[];
|
|
double maSlowStateBuffer[];
|
|
double maBondUpperBuffer[];
|
|
double maBondLowerBuffer[];
|
|
double sarBuffer[];
|
|
double sarColorBuffer[];
|
|
double sarStateBuffer[];
|
|
double peakBuffer[];
|
|
double valeBuffer[];
|
|
double fiboUpperBuffer[];
|
|
double fiboMiddleBuffer[];
|
|
double fiboLowerBuffer[];
|
|
double zigzagBuffer[];
|
|
double sHHBuffer[];
|
|
double sLLBuffer[];
|
|
double mHHBuffer[];
|
|
double mLLBuffer[];
|
|
double lHHBuffer[];
|
|
double lLLBuffer[];
|
|
double hHHBuffer[];
|
|
double hLLBuffer[];
|
|
double highsBuffer[];
|
|
double highsTimeBuffer[];
|
|
double lowsBuffer[];
|
|
double lowsTimeBuffer[];
|
|
double hkOpenBuffer[];
|
|
double hkHighBuffer[];
|
|
double hkLowBuffer[];
|
|
double hkCloseBuffer[];
|
|
double hkColorBuffer[];
|
|
|
|
//
|
|
// Conditions ...
|
|
|
|
//
|
|
// Constructor ...
|
|
XFIMAConditions()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Cleaning Up ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
// Commons ...
|
|
to = NULL;
|
|
from = NULL;
|
|
time = NULL;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
|
|
//
|
|
// Buffers ...
|
|
|
|
//
|
|
SpecifiedClean(bars);
|
|
|
|
//
|
|
SpecifiedClean(maFastBuffer);
|
|
SpecifiedClean(maFastColorBuffer);
|
|
SpecifiedClean(maFastStateBuffer);
|
|
SpecifiedClean(maSlowBuffer);
|
|
SpecifiedClean(maSlowColorBuffer);
|
|
SpecifiedClean(maSlowStateBuffer);
|
|
SpecifiedClean(maBondUpperBuffer);
|
|
SpecifiedClean(maBondLowerBuffer);
|
|
SpecifiedClean(sarBuffer);
|
|
SpecifiedClean(sarColorBuffer);
|
|
SpecifiedClean(sarStateBuffer);
|
|
SpecifiedClean(peakBuffer);
|
|
SpecifiedClean(valeBuffer);
|
|
SpecifiedClean(fiboUpperBuffer);
|
|
SpecifiedClean(fiboMiddleBuffer);
|
|
SpecifiedClean(fiboLowerBuffer);
|
|
SpecifiedClean(zigzagBuffer);
|
|
SpecifiedClean(sHHBuffer);
|
|
SpecifiedClean(sLLBuffer);
|
|
SpecifiedClean(mHHBuffer);
|
|
SpecifiedClean(mLLBuffer);
|
|
SpecifiedClean(lHHBuffer);
|
|
SpecifiedClean(lLLBuffer);
|
|
SpecifiedClean(hHHBuffer);
|
|
SpecifiedClean(hLLBuffer);
|
|
SpecifiedClean(highsBuffer);
|
|
SpecifiedClean(highsTimeBuffer);
|
|
SpecifiedClean(lowsBuffer);
|
|
SpecifiedClean(lowsTimeBuffer);
|
|
SpecifiedClean(hkOpenBuffer);
|
|
SpecifiedClean(hkHighBuffer);
|
|
SpecifiedClean(hkLowBuffer);
|
|
SpecifiedClean(hkCloseBuffer);
|
|
SpecifiedClean(hkColorBuffer);
|
|
|
|
//
|
|
// Conditions ...
|
|
|
|
//
|
|
ArraySetAsSeries(bars, true);
|
|
|
|
//
|
|
ArraySetAsSeries(maFastBuffer, true);
|
|
ArraySetAsSeries(maFastColorBuffer, true);
|
|
ArraySetAsSeries(maFastStateBuffer, true);
|
|
ArraySetAsSeries(maSlowBuffer, true);
|
|
ArraySetAsSeries(maSlowColorBuffer, true);
|
|
ArraySetAsSeries(maSlowStateBuffer, true);
|
|
ArraySetAsSeries(maBondUpperBuffer, true);
|
|
ArraySetAsSeries(maBondLowerBuffer, true);
|
|
ArraySetAsSeries(sarBuffer, true);
|
|
ArraySetAsSeries(sarColorBuffer, true);
|
|
ArraySetAsSeries(sarStateBuffer, true);
|
|
ArraySetAsSeries(peakBuffer, true);
|
|
ArraySetAsSeries(valeBuffer, true);
|
|
ArraySetAsSeries(fiboUpperBuffer, true);
|
|
ArraySetAsSeries(fiboMiddleBuffer, true);
|
|
ArraySetAsSeries(fiboLowerBuffer, true);
|
|
ArraySetAsSeries(zigzagBuffer, false); // Fix this ...
|
|
ArraySetAsSeries(sHHBuffer, true);
|
|
ArraySetAsSeries(sLLBuffer, true);
|
|
ArraySetAsSeries(mHHBuffer, true);
|
|
ArraySetAsSeries(mLLBuffer, true);
|
|
ArraySetAsSeries(lHHBuffer, true);
|
|
ArraySetAsSeries(lLLBuffer, true);
|
|
ArraySetAsSeries(hHHBuffer, true);
|
|
ArraySetAsSeries(hLLBuffer, true);
|
|
ArraySetAsSeries(highsBuffer, true);
|
|
ArraySetAsSeries(highsTimeBuffer, true);
|
|
ArraySetAsSeries(lowsBuffer, true);
|
|
ArraySetAsSeries(lowsTimeBuffer, true);
|
|
ArraySetAsSeries(hkOpenBuffer, true);
|
|
ArraySetAsSeries(hkHighBuffer, true);
|
|
ArraySetAsSeries(hkLowBuffer, true);
|
|
ArraySetAsSeries(hkCloseBuffer, true);
|
|
ArraySetAsSeries(hkColorBuffer, true);
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Generate Conditions Scores ...
|
|
*
|
|
* @param bullishScore: Double, Directional Scores Reference ...
|
|
* @param bearishScore: Double, Directional Scores Reference ...
|
|
*/
|
|
void GenerateScore(
|
|
double &bullishScore,
|
|
double &bearishScore //
|
|
)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Generate Summary String for Represent Conditions State ...
|
|
*
|
|
* @param onlyCommons: Boolean, Just Generate Only Commons Conditions ...
|
|
* @param onlyConditions: Boolean, Just Generate Only Conditions ...
|
|
* @param includeScores: Boolean, Attach Scores Representations on Result ...
|
|
* @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ...
|
|
* @param separator: String, Separate Lines ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GenerateSummary(
|
|
bool onlyCommons = false,
|
|
bool onlyConditions = false,
|
|
bool includeScores = true,
|
|
bool ignoreFalseConditions = true,
|
|
string separator = "\n" //
|
|
)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* Retrieve Unique Tag Identifier ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetTag()
|
|
{
|
|
return GetToken(this);
|
|
}
|
|
};
|
|
|
|
//
|
|
// Class ...
|
|
class XCXFIMAHelper : public XCBaseHelper
|
|
{
|
|
//
|
|
// Public ...
|
|
public:
|
|
//
|
|
// Props ...
|
|
XCMarketPatternDetector *patternDetector;
|
|
|
|
//
|
|
// Constructors ...
|
|
XCXFIMAHelper()
|
|
: XCBaseHelper(_Symbol, _Period)
|
|
{
|
|
patternDetector = new XCMarketPatternDetector();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCXFIMAHelper()
|
|
{
|
|
//
|
|
delete patternDetector;
|
|
ZeroMemory(patternDetector);
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Initialize Helper Cleass ...
|
|
bool Init(
|
|
string symbol, // Trading Symbol
|
|
ENUM_TIMEFRAMES period, // Trading Period
|
|
XFIMAInputs &inputs // Inputs
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
mSymbol = symbol;
|
|
mPeriod = period;
|
|
|
|
//
|
|
result = inputs.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mInputs = inputs;
|
|
|
|
//
|
|
mHandler = iCustom(
|
|
mSymbol,
|
|
mPeriod,
|
|
"x-saherelm.xfima",
|
|
"", // Calculation ...
|
|
mInputs.scMethod,
|
|
mInputs.scPeriod,
|
|
mInputs.mcMethod,
|
|
mInputs.mcPeriod,
|
|
mInputs.lcMethod,
|
|
mInputs.lcPeriod,
|
|
mInputs.hcMethod,
|
|
mInputs.hcPeriod,
|
|
mInputs.upperMode,
|
|
mInputs.lowerMode,
|
|
mInputs.fiboUpperZoneLevel,
|
|
mInputs.fiboMiddleZoneLevel,
|
|
mInputs.fiboLowerZoneLevel,
|
|
mInputs.sarStep,
|
|
mInputs.sarMax,
|
|
mInputs.maMethod,
|
|
mInputs.maAppliedTo,
|
|
mInputs.maFastLength,
|
|
mInputs.maSlowLength,
|
|
mInputs.maBondLength,
|
|
mInputs.zigzagDepth,
|
|
mInputs.zigzagDeviation,
|
|
mInputs.zigzagBackStep,
|
|
mInputs.zigzagUppersMode,
|
|
mInputs.zigzagLowersMode,
|
|
mInputs.hkIgnoreShadows,
|
|
mInputs.hkSmoothingLength,
|
|
mInputs.hkSmoothingMode,
|
|
"", // Presentation ...
|
|
mInputs.showPV,
|
|
mInputs.showHK,
|
|
mInputs.showSAR,
|
|
mInputs.showMAFast,
|
|
mInputs.showMASlow,
|
|
mInputs.showMABond,
|
|
mInputs.showHKBond,
|
|
mInputs.showZigZag,
|
|
mInputs.showFiboZone,
|
|
mInputs.startCalculationForLastBars,
|
|
mInputs.sarArrowCode,
|
|
mInputs.peakArrowCode,
|
|
mInputs.valeArrowCode
|
|
//
|
|
);
|
|
result = mHandler != INVALID_HANDLE;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Inputs ...
|
|
|
|
//
|
|
XFIMAInputs GetInputs()
|
|
{
|
|
return mInputs;
|
|
}
|
|
|
|
//
|
|
bool SetInputs(
|
|
XFIMAInputs &inputs // Configs
|
|
)
|
|
{
|
|
//
|
|
return Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
inputs //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
bool GetConditions(
|
|
XFIMAConditions &conditions, //
|
|
int barIndex = 0, //
|
|
int loopback = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = true;
|
|
|
|
//
|
|
if (loopback < 5)
|
|
{
|
|
loopback = 5;
|
|
}
|
|
|
|
//
|
|
conditions.Clean();
|
|
|
|
//
|
|
conditions.symbol = mSymbol;
|
|
conditions.period = mPeriod;
|
|
conditions.time = TimeCurrent();
|
|
|
|
//
|
|
// Filling Bars ...
|
|
int barsCount = GetBars(
|
|
conditions.bars,
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
result = barsCount == loopback;
|
|
if (!result)
|
|
{
|
|
//
|
|
conditions.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int zIDX = 0;
|
|
int cIDX = 1;
|
|
int pIDX = cIDX + 1;
|
|
int p2IDX = pIDX + 1;
|
|
int p3IDX = p2IDX + 1;
|
|
int p4IDX = p3IDX + 1;
|
|
|
|
//
|
|
conditions.to = conditions.bars[0].time;
|
|
conditions.from = conditions.bars[ArraySize(conditions.bars) - 1].time;
|
|
|
|
//
|
|
int zIndex = barIndex;
|
|
|
|
//
|
|
// Buffers ...
|
|
|
|
//
|
|
CopyMAFast(
|
|
zIndex,
|
|
loopback,
|
|
conditions.maFastBuffer //
|
|
);
|
|
|
|
//
|
|
CopyMAFastState(
|
|
zIndex,
|
|
loopback,
|
|
conditions.maFastStateBuffer //
|
|
);
|
|
|
|
//
|
|
CopyMASlow(
|
|
zIndex,
|
|
loopback,
|
|
conditions.maSlowBuffer //
|
|
);
|
|
|
|
//
|
|
CopyMASlowState(
|
|
zIndex,
|
|
loopback,
|
|
conditions.maSlowStateBuffer //
|
|
);
|
|
|
|
//
|
|
CopyMABondUpper(
|
|
zIndex,
|
|
loopback,
|
|
conditions.maBondUpperBuffer //
|
|
);
|
|
|
|
//
|
|
CopyMABondLower(
|
|
zIndex,
|
|
loopback,
|
|
conditions.maBondLowerBuffer //
|
|
);
|
|
|
|
//
|
|
CopySar(
|
|
zIndex,
|
|
loopback,
|
|
conditions.sarBuffer //
|
|
);
|
|
|
|
//
|
|
CopySarState(
|
|
zIndex,
|
|
loopback,
|
|
conditions.sarStateBuffer //
|
|
);
|
|
|
|
//
|
|
CopyPeak(
|
|
zIndex,
|
|
loopback,
|
|
conditions.peakBuffer //
|
|
);
|
|
|
|
//
|
|
CopyVale(
|
|
zIndex,
|
|
loopback,
|
|
conditions.valeBuffer //
|
|
);
|
|
|
|
//
|
|
CopyFiboUpper(
|
|
zIndex,
|
|
loopback,
|
|
conditions.fiboUpperBuffer //
|
|
);
|
|
|
|
//
|
|
CopyFiboMiddle(
|
|
zIndex,
|
|
loopback,
|
|
conditions.fiboMiddleBuffer //
|
|
);
|
|
|
|
//
|
|
CopyFiboLower(
|
|
zIndex,
|
|
loopback,
|
|
conditions.fiboLowerBuffer //
|
|
);
|
|
|
|
//
|
|
CopyZigZag(
|
|
zIndex,
|
|
loopback,
|
|
conditions.zigzagBuffer //
|
|
);
|
|
|
|
//
|
|
CopySHH(
|
|
zIndex,
|
|
loopback,
|
|
conditions.sHHBuffer //
|
|
);
|
|
|
|
//
|
|
CopySLL(
|
|
zIndex,
|
|
loopback,
|
|
conditions.sLLBuffer //
|
|
);
|
|
|
|
//
|
|
CopyMHH(
|
|
zIndex,
|
|
loopback,
|
|
conditions.mHHBuffer //
|
|
);
|
|
|
|
//
|
|
CopyMLL(
|
|
zIndex,
|
|
loopback,
|
|
conditions.mLLBuffer //
|
|
);
|
|
|
|
//
|
|
CopyLHH(
|
|
zIndex,
|
|
loopback,
|
|
conditions.lHHBuffer //
|
|
);
|
|
|
|
//
|
|
CopyLLL(
|
|
zIndex,
|
|
loopback,
|
|
conditions.lLLBuffer //
|
|
);
|
|
|
|
//
|
|
CopyHHH(
|
|
zIndex,
|
|
loopback,
|
|
conditions.hHHBuffer //
|
|
);
|
|
|
|
//
|
|
CopyHLL(
|
|
zIndex,
|
|
loopback,
|
|
conditions.hLLBuffer //
|
|
);
|
|
|
|
//
|
|
CopyHKOpen(
|
|
zIndex,
|
|
loopback,
|
|
conditions.hkOpenBuffer //
|
|
);
|
|
|
|
//
|
|
CopyHKHigh(
|
|
zIndex,
|
|
loopback,
|
|
conditions.hkHighBuffer //
|
|
);
|
|
|
|
//
|
|
CopyHKLow(
|
|
zIndex,
|
|
loopback,
|
|
conditions.hkLowBuffer //
|
|
);
|
|
|
|
//
|
|
CopyHKClose(
|
|
zIndex,
|
|
loopback,
|
|
conditions.hkCloseBuffer //
|
|
);
|
|
|
|
//
|
|
CopyHKColor(
|
|
zIndex,
|
|
loopback,
|
|
conditions.hkColorBuffer //
|
|
);
|
|
|
|
//
|
|
// Conditions ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Pivot Actions ...
|
|
|
|
/**
|
|
* Check Specified Bar has MA Cross or not ...
|
|
*
|
|
* @param dir: reference for holds cross Direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasMACross(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
double validCrossDiffMultiplier = 1 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double fast[];
|
|
int fastCount = CopyMAFast(barIndex, 2, fast);
|
|
|
|
//
|
|
double slow[];
|
|
int slowCount = CopyMASlow(barIndex, 2, slow);
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
// Validate Readed Values ...
|
|
int count = MathMin(fastCount, slowCount);
|
|
result = IsValidSize(count) && count >= 2;
|
|
if (result)
|
|
{
|
|
//
|
|
// Detect Direction Change ...
|
|
|
|
//
|
|
bool notEmpty =
|
|
NotEmptyZero(fast[0]) &&
|
|
NotEmptyZero(fast[1]) &&
|
|
NotEmptyZero(slow[0]) &&
|
|
NotEmptyZero(slow[1]);
|
|
|
|
//
|
|
isBullish =
|
|
notEmpty &&
|
|
fast[0] > slow[0] &&
|
|
fast[1] < slow[1];
|
|
|
|
//
|
|
isBearish =
|
|
notEmpty &&
|
|
fast[0] < slow[0] &&
|
|
fast[1] > slow[1];
|
|
|
|
//
|
|
result =
|
|
isBullish ||
|
|
isBearish;
|
|
|
|
//
|
|
// Validate Direction Change ...
|
|
if (result &&
|
|
validCrossDiffMultiplier > 0)
|
|
{
|
|
//
|
|
double _points = GetPoints(GetSymbol());
|
|
double diff = MathAbs(fast[0] - slow[0]);
|
|
|
|
//
|
|
result = diff >= (validCrossDiffMultiplier * _points);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
// Setting Direction ...
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
XClean(fast);
|
|
XClean(slow);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar has SAR Switch or not ...
|
|
*
|
|
* @param dir: reference for holds cross Direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasSARSwitch(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double sars[];
|
|
int count = CopySarState(barIndex, 2, sars);
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
// Validate Readed Values ...
|
|
result = IsValidSize(count) && count >= 2;
|
|
if (result)
|
|
{
|
|
//
|
|
// Detect Direction Change ...
|
|
|
|
//
|
|
isBullish =
|
|
sars[0] >= 1 &&
|
|
sars[1] <= -1;
|
|
|
|
//
|
|
isBearish =
|
|
sars[0] <= -1 &&
|
|
sars[1] >= 1;
|
|
|
|
//
|
|
result =
|
|
isBullish ||
|
|
isBearish;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
// Setting Direction ...
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
XClean(sars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar Price is In Boundary or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsInBoundary(
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
if (!IsXValid(priceType))
|
|
{
|
|
priceType = X_PRICE_CLOSE;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Bar ...
|
|
XOHCL bar;
|
|
result = bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
double value = bar.GetPrice(priceType);
|
|
|
|
//
|
|
// Read Boundary Values ...
|
|
double min;
|
|
double max;
|
|
result = GetBoundaryValues(min, max, barIndex);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = value < max &&
|
|
value > min;
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar Price is Over Boundary Min ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsOverBoundaryMin(
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
if (!IsXValid(priceType))
|
|
{
|
|
priceType = X_PRICE_CLOSE;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Boundary ...
|
|
double min;
|
|
double max;
|
|
result = GetBoundaryValues(min, max, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Bar ....
|
|
XOHCL bar;
|
|
result = bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
double value = bar.GetPrice(priceType);
|
|
|
|
//
|
|
result = value > min;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar Price is Under Boundary Max ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsUnderBoundaryMax(
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
if (!IsXValid(priceType))
|
|
{
|
|
priceType = X_PRICE_CLOSE;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Boundary ...
|
|
double min;
|
|
double max;
|
|
result = GetBoundaryValues(min, max, barIndex);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Retrieve Bar ....
|
|
XOHCL bar;
|
|
result = bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
double value = bar.GetPrice(priceType);
|
|
|
|
//
|
|
result = value < max;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Boundary Fake Breaked or not ...
|
|
*
|
|
* @param dir: reference for holds cross Direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param overMaxPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
|
|
* @param underMinPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsBoundaryFakeBreaked(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE overMaxPriceType = X_PRICE_NONE,
|
|
ENUM_X_PRICE underMinPriceType = X_PRICE_NONE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
if (!IsXValid(overMaxPriceType))
|
|
{
|
|
overMaxPriceType = X_PRICE_CLOSE;
|
|
}
|
|
if (!IsXValid(underMinPriceType))
|
|
{
|
|
underMinPriceType = X_PRICE_CLOSE;
|
|
}
|
|
|
|
//
|
|
// Initial Bars ...
|
|
XOHCL bar;
|
|
XOHCL pBar;
|
|
double min;
|
|
double max;
|
|
double pMin;
|
|
double pMax;
|
|
double boundaryValues[];
|
|
result =
|
|
bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
) &&
|
|
bar.GetPreviousBar(pBar) &&
|
|
GetBoundaryValues(min, max, barIndex) &&
|
|
GetBoundaryValues(pMin, pMax, barIndex + 1) &&
|
|
FillBoundaryValues(boundaryValues, barIndex) > 0;
|
|
|
|
//
|
|
bool isBullish =
|
|
result &&
|
|
pBar.IsBearish() &&
|
|
bar.IsBullish() &&
|
|
pBar.GetPrice(underMinPriceType) < pMin &&
|
|
bar.GetPrice(underMinPriceType) > min &&
|
|
(bar.GetPrice(underMinPriceType) > FindLesserThan(max, boundaryValues) ||
|
|
bar.GetPrice(underMinPriceType) > FindBiggerThan(min + ((max - min) / 2), boundaryValues));
|
|
|
|
//
|
|
bool isBearish =
|
|
result &&
|
|
pBar.IsBullish() &&
|
|
bar.IsBearish() &&
|
|
pBar.GetPrice(overMaxPriceType) > pMax &&
|
|
bar.GetPrice(overMaxPriceType) < max &&
|
|
(bar.GetPrice(overMaxPriceType) < FindBiggerThan(min, boundaryValues) ||
|
|
bar.GetPrice(overMaxPriceType) < FindLesserThan(min + ((max - min) / 2), boundaryValues));
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
pBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar's Price in Hot Place or Not ...
|
|
*
|
|
* @param dir: reference for holds cross Direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param overMaxPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
|
|
* @param underMinPriceType: ENUM_X_PRICE, which price of Specified bar to Check ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsInHotPlace(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
ENUM_X_PRICE overMaxPriceType = X_PRICE_NONE,
|
|
ENUM_X_PRICE underMinPriceType = X_PRICE_NONE //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
if (!IsXValid(overMaxPriceType))
|
|
{
|
|
overMaxPriceType = X_PRICE_LOW;
|
|
}
|
|
if (!IsXValid(underMinPriceType))
|
|
{
|
|
underMinPriceType = X_PRICE_HIGH;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Initialize Bar ...
|
|
XOHCL bar;
|
|
result = bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double overMaxPrice = bar.GetPrice(overMaxPriceType);
|
|
double underMinPrice = bar.GetPrice(underMinPriceType);
|
|
|
|
//
|
|
// Reading Boundary Value ...
|
|
double min;
|
|
double max;
|
|
result = GetBoundaryValues(
|
|
min,
|
|
max,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = underMinPrice < min;
|
|
bool isBearish = overMaxPrice > max;
|
|
|
|
//
|
|
result = (isBullish && !isBearish) ||
|
|
(isBearish && !isBullish);
|
|
if (result)
|
|
{
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar price Crossed in Boundary or not ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION, reference to hold Crossed in Dir ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedInBoundary(
|
|
ENUM_X_DIRECTION &dir,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
int pBarIndex = barIndex + 1;
|
|
|
|
//
|
|
if (!IsXValid(priceType))
|
|
{
|
|
priceType = X_PRICE_CLOSE;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check PrevBar Is in Hot Place ...
|
|
result = IsInHotPlace(
|
|
dir,
|
|
pBarIndex,
|
|
X_PRICE_LOW,
|
|
X_PRICE_HIGH //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = IsXBullish(dir);
|
|
bool isBearish = IsXBearish(dir);
|
|
|
|
//
|
|
// Current Bar must Into Boundary ...
|
|
result = IsInBoundary(priceType, barIndex);
|
|
if (!result)
|
|
{
|
|
dir = X_DIRECTION_NONE;
|
|
}
|
|
|
|
//
|
|
result = HasDirection(dir);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar price Crossed out Boundary or not ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION, reference to hold Crossed in Dir ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type of Bar ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsCrossedOutBoundary(
|
|
ENUM_X_DIRECTION &dir,
|
|
ENUM_X_PRICE priceType = X_PRICE_CLOSE,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
int pBarIndex = barIndex + 1;
|
|
|
|
//
|
|
if (!IsXValid(priceType))
|
|
{
|
|
priceType = X_PRICE_CLOSE;
|
|
}
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Prev Bar Must in Boundary ...
|
|
bool isBullish = IsInBoundary(X_PRICE_LOW, pBarIndex);
|
|
bool isBearish = IsInBoundary(X_PRICE_HIGH, pBarIndex);
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Current Bar must Out of Boundary ...
|
|
|
|
XOHCL bar;
|
|
result = bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
isBullish =
|
|
result &&
|
|
isBullish &&
|
|
bar.IsBullish() &&
|
|
!IsInBoundary(priceType, barIndex);
|
|
|
|
//
|
|
isBearish =
|
|
result &&
|
|
isBearish &&
|
|
bar.IsBearish() &&
|
|
!IsInBoundary(priceType, barIndex);
|
|
|
|
//
|
|
result = isBullish ||
|
|
isBearish;
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
dir = isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
result = HasDirection(dir);
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar has Boundary Trend or not ...
|
|
*
|
|
* @param dir: reference for holds cross Direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasBoundaryTrend(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double fast = GetMAFast(barIndex);
|
|
double slow = GetMASlow(barIndex);
|
|
|
|
//
|
|
double maBondUpper = GetMABondUpper(barIndex);
|
|
double maBondLower = GetMABondLower(barIndex);
|
|
|
|
//
|
|
double pbBondUpper = GetPBBondUpper(barIndex);
|
|
double pbBondLower = GetPBBondLower(barIndex);
|
|
|
|
//
|
|
double hkBondUpper = GetHKBondUpper(barIndex);
|
|
double hkBondLower = GetHKBondLower(barIndex);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(fast) &&
|
|
NotEmptyZero(slow) &&
|
|
NotEmptyZero(maBondUpper) &&
|
|
NotEmptyZero(maBondLower) &&
|
|
NotEmptyZero(hkBondUpper) &&
|
|
NotEmptyZero(hkBondLower) &&
|
|
NotEmptyZero(pbBondUpper) &&
|
|
NotEmptyZero(pbBondLower);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish =
|
|
fast > hkBondLower &&
|
|
slow > hkBondLower &&
|
|
maBondUpper > hkBondLower &&
|
|
maBondLower > hkBondLower &&
|
|
pbBondUpper > hkBondLower &&
|
|
pbBondLower > hkBondLower;
|
|
bool isBearish =
|
|
fast < hkBondUpper &&
|
|
slow < hkBondUpper &&
|
|
maBondUpper < hkBondUpper &&
|
|
maBondLower < hkBondUpper &&
|
|
pbBondUpper < hkBondUpper &&
|
|
pbBondLower < hkBondUpper;
|
|
|
|
//
|
|
result = (isBullish && !isBearish) ||
|
|
(isBearish && !isBullish);
|
|
if (result)
|
|
{
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar has Boundary Trend Switched or not ...
|
|
*
|
|
* @param dir: reference for holds cross Direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasBoundarySwitch(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = HasBoundaryTrend(
|
|
dir,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
bool isBullish = IsXBullish(dir);
|
|
bool isBearish = IsXBearish(dir);
|
|
|
|
//
|
|
result = HasBoundaryTrend(
|
|
dir,
|
|
barIndex + 1 //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
bool isPBullish = IsXBullish(dir);
|
|
bool isPBearish = IsXBearish(dir);
|
|
|
|
//
|
|
bool isSwitchedToBullish =
|
|
isBullish && !isPBullish;
|
|
bool isSwitchedToBearish =
|
|
isBearish && !isPBearish;
|
|
result = isSwitchedToBullish ||
|
|
isSwitchedToBearish;
|
|
if (result)
|
|
{
|
|
//
|
|
dir = isSwitchedToBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
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 = GetPeak(barIndex);
|
|
double pPeak = 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 = GetVale(barIndex);
|
|
double pVale = 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 = GetPeak(barIndex);
|
|
double pPeak = 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 = GetVale(barIndex);
|
|
double pVale = GetVale(barIndex + 1);
|
|
|
|
//
|
|
result = NotEmptyZero(iVale) &&
|
|
iVale < pVale;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Fibo Section is Changed or not ...
|
|
*
|
|
* @param dir: reference to hold section change direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsFiboSectionChanged(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
double iFiboUpper = GetFiboUpper(barIndex);
|
|
double pFiboUpper = GetFiboUpper(barIndex + 1);
|
|
|
|
//
|
|
double iFiboMiddle = GetFiboMiddle(barIndex);
|
|
double pFiboMiddle = GetFiboMiddle(barIndex + 1);
|
|
|
|
//
|
|
double iFiboLower = GetFiboLower(barIndex);
|
|
double pFiboLower = GetFiboLower(barIndex + 1);
|
|
|
|
//
|
|
isBullish = iFiboLower >= pFiboMiddle &&
|
|
iFiboMiddle >= pFiboUpper;
|
|
isBearish = iFiboUpper <= pFiboMiddle &&
|
|
iFiboMiddle <= pFiboLower;
|
|
result = (isBullish && !isBearish) ||
|
|
(isBearish && !isBullish);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check for Fibo Push Exists or not ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION, reference to hold result ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param validationLength: int, Validation Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasFiboPush(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
int validationLength = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
validationLength = NormalizeInt(validationLength, 3);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Define Requirements ...
|
|
|
|
//
|
|
XOHCL iBar;
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
double iFiboUpper = EMPTY_VALUE;
|
|
double pFiboUpper = EMPTY_VALUE;
|
|
|
|
//
|
|
double iFiboMiddle = EMPTY_VALUE;
|
|
double pFiboMiddle = EMPTY_VALUE;
|
|
|
|
//
|
|
double iFiboLower = EMPTY_VALUE;
|
|
double pFiboLower = EMPTY_VALUE;
|
|
|
|
//
|
|
// Check Zone Validation ...
|
|
int start = barIndex;
|
|
int end = start + validationLength;
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
iFiboUpper = GetFiboUpper(i);
|
|
pFiboUpper = GetFiboUpper(i + 1);
|
|
|
|
//
|
|
iFiboMiddle = GetFiboMiddle(i);
|
|
pFiboMiddle = GetFiboMiddle(i + 1);
|
|
|
|
//
|
|
iFiboLower = GetFiboLower(i);
|
|
pFiboLower = GetFiboLower(i + 1);
|
|
|
|
//
|
|
result = iFiboUpper == pFiboUpper;
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
result = iBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
iFiboUpper = GetFiboUpper(barIndex);
|
|
iFiboMiddle = GetFiboMiddle(barIndex);
|
|
iFiboLower = GetFiboLower(barIndex);
|
|
|
|
//
|
|
isBullish = iBar.IsBullish() &&
|
|
iBar.close > iFiboLower &&
|
|
iBar.low < iFiboLower;
|
|
isBearish = iBar.IsBearish() &&
|
|
iBar.close < iFiboUpper &&
|
|
iBar.high > iFiboUpper;
|
|
result = (isBullish && !isBearish) ||
|
|
(isBearish && !isBullish);
|
|
if (result)
|
|
{
|
|
//
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Has Higher Low Based On ZigZag ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasZigZagHigherLow(
|
|
int barIndex = 0,
|
|
bool forceBarValidation = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL bar;
|
|
result = IsValid() &&
|
|
bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
10,
|
|
200 //
|
|
);
|
|
|
|
//
|
|
// Validate Pivots and Nearest Pivot is Low ...
|
|
result = IsValidSize(count) &&
|
|
pivots[0].IsVale();
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Directional Pivots ...
|
|
XPivot vales[];
|
|
count = ExtractPivots(
|
|
vales,
|
|
pivots,
|
|
X_PIVOT_TYPE_VALE //
|
|
);
|
|
result = IsValidSize(count) &&
|
|
count >= 2;
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(vales);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Result ...
|
|
result =
|
|
vales[0].value > vales[1].value;
|
|
if (forceBarValidation)
|
|
{
|
|
//
|
|
result =
|
|
result &&
|
|
bar.open > vales[0].value &&
|
|
bar.close > vales[0].value;
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
XClean(vales);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Has Lower Low Based On ZigZag ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasZigZagLowerLow(
|
|
int barIndex = 0,
|
|
bool forceBarValidation = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL bar;
|
|
result = IsValid() &&
|
|
bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
10,
|
|
200 //
|
|
);
|
|
|
|
//
|
|
// Validate Pivots and Nearest Pivot is Low ...
|
|
result = IsValidSize(count) &&
|
|
pivots[0].IsVale();
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Directional Pivots ...
|
|
XPivot vales[];
|
|
count = ExtractPivots(
|
|
vales,
|
|
pivots,
|
|
X_PIVOT_TYPE_VALE //
|
|
);
|
|
result = IsValidSize(count) &&
|
|
count >= 2;
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(vales);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Result ...
|
|
result =
|
|
vales[0].value < vales[1].value;
|
|
if (forceBarValidation)
|
|
{
|
|
//
|
|
result =
|
|
result &&
|
|
bar.open < vales[0].value &&
|
|
bar.close < vales[0].value;
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
XClean(vales);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Has Higher High Based On ZigZag ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasZigZagHigherHigh(
|
|
int barIndex = 0,
|
|
bool forceBarValidation = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL bar;
|
|
result = IsValid() &&
|
|
bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
10,
|
|
200 //
|
|
);
|
|
|
|
//
|
|
// Validate Pivots and Nearest Pivot is Low ...
|
|
result = IsValidSize(count) &&
|
|
pivots[0].IsPeak();
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Directional Pivots ...
|
|
XPivot peaks[];
|
|
count = ExtractPivots(
|
|
peaks,
|
|
pivots,
|
|
X_PIVOT_TYPE_PEAK //
|
|
);
|
|
result = IsValidSize(count) &&
|
|
count >= 2;
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(peaks);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Result ...
|
|
result =
|
|
peaks[0].value > peaks[1].value;
|
|
if (forceBarValidation)
|
|
{
|
|
//
|
|
result =
|
|
result &&
|
|
bar.open > peaks[0].value &&
|
|
bar.close > peaks[0].value;
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
XClean(peaks);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Has Lower High Based On ZigZag ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasZigZagLowerHigh(
|
|
int barIndex = 0,
|
|
bool forceBarValidation = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
XOHCL bar;
|
|
result = IsValid() &&
|
|
bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
10,
|
|
200 //
|
|
);
|
|
|
|
//
|
|
// Validate Pivots and Nearest Pivot is Low ...
|
|
result = IsValidSize(count) &&
|
|
pivots[0].IsPeak();
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Directional Pivots ...
|
|
XPivot peaks[];
|
|
count = ExtractPivots(
|
|
peaks,
|
|
pivots,
|
|
X_PIVOT_TYPE_PEAK //
|
|
);
|
|
result = IsValidSize(count) &&
|
|
count >= 2;
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(peaks);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Result ...
|
|
result =
|
|
peaks[0].value < peaks[1].value;
|
|
if (forceBarValidation)
|
|
{
|
|
//
|
|
result =
|
|
result &&
|
|
bar.open < peaks[0].value &&
|
|
bar.close < peaks[0].value;
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
XClean(peaks);
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// HK ...
|
|
|
|
/**
|
|
* Check Specified Bar has HK Switch or not ...
|
|
*
|
|
* @param dir: reference for holds cross Direction ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasHKSwitch(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
|
|
//
|
|
double open[];
|
|
int openCount = CopyHKOpen(barIndex, 2, open);
|
|
|
|
//
|
|
double close[];
|
|
int closeCount = CopyHKClose(barIndex, 2, close);
|
|
|
|
//
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
// Validate Readed Values ...
|
|
int count = MathMin(openCount, closeCount);
|
|
result = IsValidSize(count) && count >= 2;
|
|
if (result)
|
|
{
|
|
//
|
|
// Detect Direction Change ...
|
|
|
|
//
|
|
bool notEmpty =
|
|
NotEmptyZero(open[0]) &&
|
|
NotEmptyZero(open[1]) &&
|
|
NotEmptyZero(close[0]) &&
|
|
NotEmptyZero(close[1]);
|
|
|
|
//
|
|
isBullish =
|
|
notEmpty &&
|
|
open[0] < close[0] &&
|
|
open[1] > close[1];
|
|
|
|
//
|
|
isBearish =
|
|
notEmpty &&
|
|
open[0] > close[0] &&
|
|
open[1] < close[1];
|
|
|
|
//
|
|
result =
|
|
isBullish ||
|
|
isBearish;
|
|
}
|
|
|
|
//
|
|
if (result)
|
|
{
|
|
//
|
|
// Setting Direction ...
|
|
dir =
|
|
isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: isBearish
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
XClean(open);
|
|
XClean(close);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar has HK Bond Based Trend or not ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION, reference to holds trend direction, if exists ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param validationLength: int, validation of trend ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasHKBasedTrend(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
int validationLength = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
validationLength = NormalizeInt(validationLength, 1);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
// Define Requirements ...
|
|
XOHCL iBar;
|
|
double hkUpper;
|
|
double hkLower;
|
|
bool has = false;
|
|
int bullishCount = 0;
|
|
int bearishCount = 0;
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
|
|
//
|
|
// Count Bullish/Bearish Directions ...
|
|
int start = barIndex + 1;
|
|
int end = start + validationLength;
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Reading Requirements ...
|
|
|
|
//
|
|
// Read Indexed Bar ...
|
|
iBar.Clean();
|
|
result = iBar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
i //
|
|
);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Reading Values ...
|
|
hkUpper = GetHKBondUpper(i);
|
|
hkLower = GetHKBondLower(i);
|
|
result = NotEmptyZero(hkUpper) &&
|
|
NotEmptyZero(hkLower);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Check Trend ...
|
|
|
|
//
|
|
// Bullish ...
|
|
isBullish = iBar.low > hkLower;
|
|
if (isBullish)
|
|
{
|
|
bullishCount++;
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
isBearish = iBar.high < hkUpper;
|
|
if (isBearish)
|
|
{
|
|
bearishCount++;
|
|
}
|
|
|
|
//
|
|
iBar.Clean();
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
// Validate Results ...
|
|
isBullish =
|
|
bullishCount >= validationLength;
|
|
isBearish =
|
|
bearishCount >= validationLength;
|
|
|
|
//
|
|
result = (isBullish && !isBearish) ||
|
|
(isBearish && !isBullish);
|
|
|
|
//
|
|
// Setting Direction if Has Trend ...
|
|
if (result)
|
|
{
|
|
//
|
|
dir = isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
iBar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Specified Bar has HK Bond Based Trend Switch or not ...
|
|
*
|
|
* @param dir: ENUM_X_DIRECTION, reference to holds trend direction, if exists ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param validationLength: int, validation of trend ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsHKBasedTrendSwitch(
|
|
ENUM_X_DIRECTION &dir,
|
|
int barIndex = 0,
|
|
int validationLength = 5 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
validationLength = NormalizeInt(validationLength, 1);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
bool hasTrend = HasHKBasedTrend(
|
|
dir,
|
|
barIndex,
|
|
validationLength //
|
|
);
|
|
bool isBullish = hasTrend &&
|
|
IsXBullish(dir);
|
|
bool isBearish = hasTrend &&
|
|
IsXBearish(dir);
|
|
|
|
//
|
|
bool hasPTrend = HasHKBasedTrend(
|
|
dir,
|
|
barIndex + 1,
|
|
validationLength //
|
|
);
|
|
bool isPBullish = hasPTrend &&
|
|
IsXBullish(dir);
|
|
bool isPBearish = hasPTrend &&
|
|
IsXBearish(dir);
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Checking Result ...
|
|
isBullish = isBullish && !isPBullish;
|
|
isBearish = isBearish && !isPBearish;
|
|
|
|
//
|
|
result =
|
|
(isBullish && !isBearish) ||
|
|
(isBearish && !isBullish);
|
|
if (result)
|
|
{
|
|
//
|
|
dir = isBullish
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_BEARISH;
|
|
}
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if Price Over HK Bond Upper or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsOverHKBondUpper(
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(mSymbol, mPeriod, barIndex);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
double value = GetHKBondUpper(barIndex);
|
|
result = NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if Price Over HK Bond Lower or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsOverHKBondLower(
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(mSymbol, mPeriod, barIndex);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
double value = GetHKBondLower(barIndex);
|
|
result = NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price > value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if Price Under HK Bond Upper or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsUnderHKBondUpper(
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(mSymbol, mPeriod, barIndex);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
double value = GetHKBondUpper(barIndex);
|
|
result = NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if Price Under HK Bond Lower or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsUnderHKBondLower(
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
XOHCL bar;
|
|
result = bar.Init(mSymbol, mPeriod, barIndex);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double price = bar.GetPrice(priceType);
|
|
double value = GetHKBondLower(barIndex);
|
|
result = NotEmptyZero(price) &&
|
|
NotEmptyZero(value) &&
|
|
price < value;
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Switched Over HK Bond Upper or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSwitchedOverHKBondUpper(
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int pBarIndex = barIndex + 1;
|
|
bool isBarPassed = IsOverHKBondUpper(priceType, barIndex);
|
|
bool isPBarPassed = !IsOverHKBondUpper(priceType, pBarIndex);
|
|
|
|
//
|
|
result = isBarPassed && isPBarPassed;
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Switched Under HK Bond Upper or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSwitchedUnderHKBondUpper(
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int pBarIndex = barIndex + 1;
|
|
bool isBarPassed = IsUnderHKBondUpper(priceType, barIndex);
|
|
bool isPBarPassed = !IsUnderHKBondUpper(priceType, pBarIndex);
|
|
|
|
//
|
|
result = isBarPassed && isPBarPassed;
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Switched Over HK Bond Lower or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSwitchedOverHKBondLower(
|
|
ENUM_X_PRICE priceType = X_PRICE_LOW,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int pBarIndex = barIndex + 1;
|
|
bool isBarPassed = IsOverHKBondLower(priceType, barIndex);
|
|
bool isPBarPassed = !IsOverHKBondLower(priceType, pBarIndex);
|
|
|
|
//
|
|
result = isBarPassed && isPBarPassed;
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check Price Switched Under HK Bond Lower or not ...
|
|
*
|
|
* @param priceType: ENUM_X_PRICE, Specified Price type ...
|
|
* @param barIndex: int, Specified Bar index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsSwitchedUnderHKBondLower(
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int pBarIndex = barIndex + 1;
|
|
bool isBarPassed = IsUnderHKBondLower(priceType, barIndex);
|
|
bool isPBarPassed = !IsUnderHKBondLower(priceType, pBarIndex);
|
|
|
|
//
|
|
result = isBarPassed && isPBarPassed;
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond ...
|
|
*
|
|
* @param index: int, reference to holds index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastOverHKBondUpper(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsOverHKBondUpper(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond ...
|
|
*
|
|
* @param index: int, reference to holds index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastUnderHKBondUpper(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsUnderHKBondUpper(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond ...
|
|
*
|
|
* @param index: int, reference to holds index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastOverHKBondLower(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsOverHKBondLower(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond ...
|
|
*
|
|
* @param index: int, reference to holds index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastUnderHKBondLower(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsUnderHKBondLower(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond Switch ...
|
|
*
|
|
* @param index: int, reference to holds switched index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSwitchedOverHKBondUpper(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSwitchedOverHKBondUpper(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond Switch ...
|
|
*
|
|
* @param index: int, reference to holds switched index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSwitchedUnderHKBondUpper(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSwitchedUnderHKBondUpper(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond Switch ...
|
|
*
|
|
* @param index: int, reference to holds switched index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSwitchedOverHKBondLower(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSwitchedOverHKBondLower(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Previous HK Bond Switch ...
|
|
*
|
|
* @param index: int, reference to holds switched index ...
|
|
* @param priceType: ENUM_X_PRICE, Specified Price Type ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param loopback: int, Max Allowed Loopback Length ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool FindLastSwitchedUnderHKBondLower(
|
|
int &index,
|
|
ENUM_X_PRICE priceType = X_PRICE_HIGH,
|
|
int barIndex = 0,
|
|
int loopback = 500 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
index = -1;
|
|
|
|
//
|
|
// Normalize ...
|
|
loopback = NormalizeInt(loopback, 50);
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
IsXValid(priceType);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do ...
|
|
|
|
//
|
|
int idx = barIndex;
|
|
while (idx < barIndex + loopback)
|
|
{
|
|
//
|
|
idx++;
|
|
result = IsSwitchedUnderHKBondLower(priceType, idx);
|
|
if (result)
|
|
{
|
|
//
|
|
index = idx - 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
// Cleanup ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// ZigZag Pivots With Liquidity ...
|
|
|
|
/**
|
|
* Check ZigZag has Lower Low by Liquidity or Not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasZigZagLowerLowByLiquidity(
|
|
int barIndex = 0,
|
|
bool forceBarValidation = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
XOHCL bar;
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
10,
|
|
200 //
|
|
);
|
|
|
|
//
|
|
// Validate Pivots and Nearest Pivot is Low ...
|
|
result = IsValidSize(count) &&
|
|
pivots[0].IsVale();
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Directional Pivots ...
|
|
XPivot selected[];
|
|
count = ExtractPivots(
|
|
selected,
|
|
pivots,
|
|
X_PIVOT_TYPE_VALE //
|
|
);
|
|
result = IsValidSize(count) &&
|
|
count >= 3;
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
XClean(selected);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do Calculations ...
|
|
result =
|
|
//
|
|
// Check Pivot ...
|
|
selected[0].value < selected[1].value &&
|
|
//
|
|
// Check Liquidity ...
|
|
selected[1].value > selected[2].value &&
|
|
//
|
|
// Check Bar Place ...
|
|
(!forceBarValidation
|
|
? true
|
|
: bar.open > selected[0].value &&
|
|
bar.close > selected[0].value);
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
XClean(selected);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check ZigZag has Higher High by Liquidity or Not ...
|
|
*
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param forceBarValidation: bool, Force Bar Price based on Pivot ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasZigZagHigherHighByLiquidity(
|
|
int barIndex = 0,
|
|
bool forceBarValidation = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
XOHCL bar;
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid() &&
|
|
bar.Init(
|
|
mSymbol,
|
|
mPeriod,
|
|
barIndex //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Pivots ...
|
|
XPivot pivots[];
|
|
int count = ExtractZigZagPivots(
|
|
pivots,
|
|
barIndex,
|
|
10,
|
|
200 //
|
|
);
|
|
|
|
//
|
|
// Validate Pivots and Nearest Pivot is Low ...
|
|
result = IsValidSize(count) &&
|
|
pivots[0].IsPeak();
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract Directional Pivots ...
|
|
XPivot selected[];
|
|
count = ExtractPivots(
|
|
selected,
|
|
pivots,
|
|
X_PIVOT_TYPE_PEAK //
|
|
);
|
|
result = IsValidSize(count) &&
|
|
count >= 3;
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
XClean(selected);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Do Calculations ...
|
|
result =
|
|
//
|
|
// Check Pivot ...
|
|
selected[0].value > selected[1].value &&
|
|
//
|
|
// Check Liquidity ...
|
|
selected[1].value < selected[2].value &&
|
|
//
|
|
// Check Bar Place ...
|
|
(!forceBarValidation
|
|
? true
|
|
: bar.open < selected[0].value &&
|
|
bar.close < selected[0].value);
|
|
|
|
//
|
|
// Cleanup ...
|
|
bar.Clean();
|
|
XClean(pivots);
|
|
XClean(selected);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extractions ...
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractPVPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500,
|
|
int validationLength = 0 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
validationLength = NormalizeInt(validationLength, 0);
|
|
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
|
|
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
|
|
|
|
//
|
|
// Validate ...
|
|
if (mHandler == INVALID_HANDLE)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool lookupPeaks = true;
|
|
bool lookupVales = true;
|
|
|
|
//
|
|
XOHCL iBar;
|
|
XPivot iPivot;
|
|
bool has = false;
|
|
int idx = barIndex - 1;
|
|
int samePeaksCount = 0;
|
|
int sameValesCount = 0;
|
|
double tmpPeaksBuffer[];
|
|
double tmpValesBuffer[];
|
|
string symbol = GetSymbol();
|
|
double iPValue = EMPTY_VALUE;
|
|
double iVValue = EMPTY_VALUE;
|
|
double pPValue = EMPTY_VALUE;
|
|
double pVValue = EMPTY_VALUE;
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
|
|
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
|
|
while (idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots)
|
|
{
|
|
//
|
|
idx++;
|
|
|
|
//
|
|
// Prepare ...
|
|
iBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpPeaksBuffer);
|
|
SpecifiedClean(tmpValesBuffer);
|
|
|
|
//
|
|
// Ignore First Item ...
|
|
if (idx == barIndex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Initialize Bar ...
|
|
has = iBar.Init(
|
|
symbol,
|
|
period,
|
|
idx //
|
|
);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Detecting ...
|
|
|
|
//
|
|
// Peak ...
|
|
if (lookupPeaks)
|
|
{
|
|
//
|
|
// Reading Buffer ...
|
|
CopyBuffer(
|
|
mHandler, // Handler ...
|
|
XFIMA_PEAK_LINE, // Handler Buffer Number ...
|
|
idx, // Bar Index ...
|
|
2, // Number of Requirements ...
|
|
tmpPeaksBuffer // Buffer ...
|
|
);
|
|
ArraySetAsSeries(tmpPeaksBuffer, true);
|
|
|
|
//
|
|
// Reading Values ...
|
|
iPValue = tmpPeaksBuffer[0];
|
|
pPValue = tmpPeaksBuffer[1];
|
|
|
|
//
|
|
// Validate Value ...
|
|
if (NotEmptyZero(iPValue))
|
|
{
|
|
//
|
|
// Check New Peak ...
|
|
has =
|
|
!NotEmptyZero(pPValue)
|
|
? true
|
|
: iPValue != pPValue;
|
|
if (has)
|
|
{
|
|
//
|
|
// Calculate and Validate Type ...
|
|
// Peaks Only Valid when Confirmed by Bar High ...
|
|
iType =
|
|
iPValue == iBar.high
|
|
? X_PIVOT_TYPE_PEAK
|
|
: X_PIVOT_TYPE_NONE;
|
|
has = IsXValid(iType);
|
|
|
|
//
|
|
// Calculate and Validate Dir ...
|
|
iDir = IsXPeak(iType)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = has &&
|
|
HasDirection(iDir);
|
|
|
|
//
|
|
// Check Validation Length ...
|
|
has =
|
|
has &&
|
|
(validationLength <= 0
|
|
? true
|
|
: samePeaksCount >= validationLength);
|
|
if (has)
|
|
{
|
|
//
|
|
// Initialize and Validate Pivot ...
|
|
has = iPivot.Init(
|
|
iPValue,
|
|
iBar.time,
|
|
symbol,
|
|
iDir,
|
|
period,
|
|
iType //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iPivot.prefix = ToXString(XFIMA_PIVOT_PV);
|
|
|
|
//
|
|
// Add Pivot to Collection only if not Exists ...
|
|
AddIfNotExists(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iPivot.Clean();
|
|
samePeaksCount = 0;
|
|
}
|
|
else if (iPValue == pPValue)
|
|
{
|
|
samePeaksCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Vale ...
|
|
if (lookupVales)
|
|
{
|
|
//
|
|
// Reading Buffer ...
|
|
CopyBuffer(
|
|
mHandler, // Handler ...
|
|
XFIMA_VALE_LINE, // Handler Buffer Number ...
|
|
idx, // Bar Index ...
|
|
2, // Number of Requirements ...
|
|
tmpValesBuffer // Buffer ...
|
|
);
|
|
ArraySetAsSeries(tmpValesBuffer, true);
|
|
|
|
//
|
|
// Reading Values ...
|
|
iVValue = tmpValesBuffer[0];
|
|
pVValue = tmpValesBuffer[1];
|
|
|
|
//
|
|
// Validate Value ...
|
|
if (NotEmptyZero(iVValue))
|
|
{
|
|
//
|
|
// Check New Vale ...
|
|
has =
|
|
!NotEmptyZero(pVValue)
|
|
? true
|
|
: iVValue != pVValue;
|
|
if (has)
|
|
{
|
|
//
|
|
// Calculate and Validate Type ...
|
|
// Vales Only Valid when Confirmed by Bar Low ...
|
|
iType =
|
|
iVValue == iBar.low
|
|
? X_PIVOT_TYPE_VALE
|
|
: X_PIVOT_TYPE_NONE;
|
|
has = IsXValid(iType);
|
|
|
|
//
|
|
// Calculate and Validate Dir ...
|
|
iDir = IsXVale(iType)
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_NONE;
|
|
has = has &&
|
|
HasDirection(iDir);
|
|
|
|
//
|
|
// Check Validation Length ...
|
|
has =
|
|
has &&
|
|
(validationLength <= 0
|
|
? true
|
|
: sameValesCount >= validationLength);
|
|
if (has)
|
|
{
|
|
//
|
|
// Initialize and Validate Pivot ...
|
|
has = iPivot.Init(
|
|
iVValue,
|
|
iBar.time,
|
|
symbol,
|
|
iDir,
|
|
period,
|
|
iType //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iPivot.prefix = ToXString(XFIMA_PIVOT_PV);
|
|
|
|
//
|
|
// Add Pivot to Collection only if not Exists ...
|
|
AddIfNotExists(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iPivot.Clean();
|
|
sameValesCount = 0;
|
|
}
|
|
else if (iVValue == pVValue)
|
|
{
|
|
sameValesCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpPeaksBuffer);
|
|
SpecifiedClean(tmpValesBuffer);
|
|
|
|
//
|
|
// Check Moving Forward Condition ...
|
|
has =
|
|
idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots;
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpPeaksBuffer);
|
|
SpecifiedClean(tmpValesBuffer);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param validCrossDiffMultiplier: double, validate diff between MAs on Cross happens ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractMAPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
double validCrossDiffMultiplier = 1,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
|
|
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
|
|
validCrossDiffMultiplier = NormalizeDouble(validCrossDiffMultiplier, 0);
|
|
|
|
//
|
|
// Validate ...
|
|
if (mHandler == INVALID_HANDLE)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double fast[];
|
|
double slow[];
|
|
XPivot iPivot;
|
|
int count = 0;
|
|
bool has = false;
|
|
int idx = barIndex - 1;
|
|
datetime iPivotTime = NULL;
|
|
string symbol = GetSymbol();
|
|
double iFValue = EMPTY_VALUE;
|
|
double pFValue = EMPTY_VALUE;
|
|
double iSValue = EMPTY_VALUE;
|
|
double pSValue = EMPTY_VALUE;
|
|
bool isSwitchedToBullish = false;
|
|
bool isSwitchedToBearish = false;
|
|
double iSelectedValue = EMPTY_VALUE;
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
|
|
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
|
|
while (idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots)
|
|
{
|
|
//
|
|
idx++;
|
|
|
|
//
|
|
// Prepare ...
|
|
XClean(fast);
|
|
XClean(slow);
|
|
iPivot.Clean();
|
|
|
|
//
|
|
// Ignore First Item ...
|
|
if (idx == barIndex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Reading Buffer ...
|
|
int fastCount = CopyMAFast(idx, 2, fast);
|
|
int slowCount = CopyMASlow(idx, 2, slow);
|
|
count = MathMin(fastCount, slowCount);
|
|
has = IsValidSize(count);
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
iFValue = fast[0];
|
|
pFValue = fast[1];
|
|
|
|
//
|
|
iSValue = slow[0];
|
|
pSValue = slow[1];
|
|
|
|
//
|
|
// Validate Value ...
|
|
has =
|
|
HasMACross(
|
|
iDir,
|
|
idx,
|
|
validCrossDiffMultiplier //
|
|
) &&
|
|
NotEmptyZero(iFValue) &&
|
|
NotEmptyZero(iSValue) &&
|
|
NotEmptyZero(pFValue) &&
|
|
NotEmptyZero(pSValue);
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Direction Changed ...
|
|
isSwitchedToBullish = IsXBullish(iDir);
|
|
isSwitchedToBearish = IsXBearish(iDir);
|
|
has =
|
|
isSwitchedToBullish ||
|
|
isSwitchedToBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
// Calculate and Validate Type ...
|
|
// Peaks Only Valid when Confirmed by Bar High ...
|
|
iType =
|
|
isSwitchedToBearish
|
|
? X_PIVOT_TYPE_PEAK
|
|
: isSwitchedToBullish
|
|
? X_PIVOT_TYPE_VALE
|
|
: X_PIVOT_TYPE_NONE;
|
|
has = IsXValid(iType);
|
|
|
|
//
|
|
// Calculate and Validate Dir ...
|
|
iDir = IsXPeak(iType)
|
|
? X_DIRECTION_BEARISH
|
|
: IsXVale(iType)
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_NONE;
|
|
has = has &&
|
|
HasDirection(iDir);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
iPivotTime = GetBarTime(
|
|
symbol,
|
|
period,
|
|
idx //
|
|
);
|
|
|
|
//
|
|
// Select Value based on Pivot Type ...
|
|
iSelectedValue = IsXPeak(iType)
|
|
? MathMax(iFValue, iSValue)
|
|
: MathMin(iFValue, iSValue);
|
|
|
|
//
|
|
// Initialize and Validate Pivot ...
|
|
has = iPivot.Init(
|
|
iSelectedValue,
|
|
iPivotTime,
|
|
symbol,
|
|
iDir,
|
|
period,
|
|
iType //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iPivot.prefix = ToXString(XFIMA_PIVOT_MA_CROSS);
|
|
|
|
//
|
|
// Add Pivot to Collection only if not Exists ...
|
|
AddIfNotExists(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iPivot.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
XClean(fast);
|
|
XClean(slow);
|
|
iPivot.Clean();
|
|
|
|
//
|
|
// Check Moving Forward Condition ...
|
|
has =
|
|
idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots;
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
XClean(fast);
|
|
XClean(slow);
|
|
iPivot.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractHKPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
|
|
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
|
|
|
|
//
|
|
// Validate ...
|
|
if (mHandler == INVALID_HANDLE)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double open[];
|
|
XPivot iPivot;
|
|
int count = 0;
|
|
double close[];
|
|
bool has = false;
|
|
int idx = barIndex - 1;
|
|
datetime iPivotTime = NULL;
|
|
string symbol = GetSymbol();
|
|
bool isSwitchedToBullish = false;
|
|
bool isSwitchedToBearish = false;
|
|
double iSelectedValue = EMPTY_VALUE;
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
|
|
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
|
|
while (idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots)
|
|
{
|
|
//
|
|
idx++;
|
|
|
|
//
|
|
// Prepare ...
|
|
XClean(open);
|
|
XClean(close);
|
|
iPivot.Clean();
|
|
|
|
//
|
|
// Ignore First Item ...
|
|
if (idx == barIndex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Reading Buffer ...
|
|
int openCount = CopyHKOpen(idx, 2, open);
|
|
int closeCount = CopyHKClose(idx, 2, close);
|
|
count = MathMin(openCount, closeCount);
|
|
has = IsValidSize(count);
|
|
|
|
//
|
|
// Validate Value ...
|
|
has =
|
|
HasHKSwitch(
|
|
iDir,
|
|
idx //
|
|
) &&
|
|
NotEmptyZero(open[0]) &&
|
|
NotEmptyZero(open[1]) &&
|
|
NotEmptyZero(close[0]) &&
|
|
NotEmptyZero(close[1]);
|
|
if (has)
|
|
{
|
|
//
|
|
// Check Direction Changed ...
|
|
isSwitchedToBullish = IsXBullish(iDir);
|
|
isSwitchedToBearish = IsXBearish(iDir);
|
|
has =
|
|
isSwitchedToBullish ||
|
|
isSwitchedToBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
// Calculate and Validate Type ...
|
|
// Peaks Only Valid when Confirmed by Bar High ...
|
|
iType =
|
|
isSwitchedToBearish
|
|
? X_PIVOT_TYPE_PEAK
|
|
: isSwitchedToBullish
|
|
? X_PIVOT_TYPE_VALE
|
|
: X_PIVOT_TYPE_NONE;
|
|
has = IsXValid(iType);
|
|
|
|
//
|
|
// Calculate and Validate Dir ...
|
|
iDir = IsXPeak(iType)
|
|
? X_DIRECTION_BEARISH
|
|
: IsXVale(iType)
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_NONE;
|
|
has = has &&
|
|
HasDirection(iDir);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
iPivot.prefix = ToXString(XFIMA_PIVOT_HK);
|
|
|
|
//
|
|
iPivotTime = GetBarTime(
|
|
symbol,
|
|
period,
|
|
idx //
|
|
);
|
|
|
|
//
|
|
// Select Value based on Pivot Type ...
|
|
iSelectedValue = IsXPeak(iType)
|
|
? MathMax(open[0], close[0])
|
|
: MathMin(open[0], close[0]);
|
|
|
|
//
|
|
// Initialize and Validate Pivot ...
|
|
has = iPivot.Init(
|
|
iSelectedValue,
|
|
iPivotTime,
|
|
symbol,
|
|
iDir,
|
|
period,
|
|
iType //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
// Add Pivot to Collection only if not Exists ...
|
|
AddIfNotExists(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iPivot.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
XClean(open);
|
|
XClean(close);
|
|
iPivot.Clean();
|
|
|
|
//
|
|
// Check Moving Forward Condition ...
|
|
has =
|
|
idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots;
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
XClean(open);
|
|
XClean(close);
|
|
iPivot.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractSARPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
|
|
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
|
|
|
|
//
|
|
// Validate ...
|
|
if (mHandler == INVALID_HANDLE)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
XOHCL pBar;
|
|
XPivot iPivot;
|
|
bool has = false;
|
|
double tmpSarBuffer[];
|
|
int idx = barIndex - 1;
|
|
string symbol = GetSymbol();
|
|
double iValue = EMPTY_VALUE;
|
|
double pValue = EMPTY_VALUE;
|
|
bool isSwitchedToBullish = false;
|
|
bool isSwitchedToBearish = false;
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
|
|
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
|
|
while (idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots)
|
|
{
|
|
//
|
|
idx++;
|
|
|
|
//
|
|
// Prepare ...
|
|
iBar.Clean();
|
|
pBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpSarBuffer);
|
|
|
|
//
|
|
// Ignore First Item ...
|
|
if (idx == barIndex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Initialize Bar ...
|
|
has = iBar.Init(
|
|
symbol,
|
|
period,
|
|
idx //
|
|
);
|
|
has =
|
|
has &&
|
|
iBar.GetPreviousBar(pBar);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Reading Buffer ...
|
|
CopyBuffer(
|
|
mHandler, // Handler ...
|
|
XFIMA_SAR_LINE, // Handler Buffer Number ...
|
|
idx, // Bar Index ...
|
|
2, // Number of Requirements ...
|
|
tmpSarBuffer // Buffer ...
|
|
);
|
|
ArraySetAsSeries(tmpSarBuffer, true);
|
|
|
|
//
|
|
// Reading Values ...
|
|
iValue = tmpSarBuffer[0];
|
|
pValue = tmpSarBuffer[1];
|
|
|
|
//
|
|
// Validate Value ...
|
|
if (NotEmptyZero(iValue))
|
|
{
|
|
//
|
|
// Check Sar Direction Changed ...
|
|
isSwitchedToBullish = iValue < iBar.low &&
|
|
pValue > pBar.high;
|
|
isSwitchedToBearish = iValue > iBar.high &&
|
|
pValue < pBar.low;
|
|
has =
|
|
isSwitchedToBullish ||
|
|
isSwitchedToBearish;
|
|
if (has)
|
|
{
|
|
//
|
|
// Calculate and Validate Type ...
|
|
// Peaks Only Valid when Confirmed by Bar High ...
|
|
iType =
|
|
isSwitchedToBearish
|
|
? X_PIVOT_TYPE_PEAK
|
|
: isSwitchedToBullish
|
|
? X_PIVOT_TYPE_VALE
|
|
: X_PIVOT_TYPE_NONE;
|
|
has = IsXValid(iType);
|
|
|
|
//
|
|
// Calculate and Validate Dir ...
|
|
iDir = IsXPeak(iType)
|
|
? X_DIRECTION_BEARISH
|
|
: IsXVale(iType)
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_NONE;
|
|
has = has &&
|
|
HasDirection(iDir);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
//
|
|
// Initialize and Validate Pivot ...
|
|
has = iPivot.Init(
|
|
iValue,
|
|
iBar.time,
|
|
symbol,
|
|
iDir,
|
|
period,
|
|
iType //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iPivot.prefix = ToXString(XFIMA_PIVOT_SAR_SWITCH);
|
|
|
|
//
|
|
// Add Pivot to Collection only if not Exists ...
|
|
AddIfNotExists(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iPivot.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
pBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpSarBuffer);
|
|
|
|
//
|
|
// Check Moving Forward Condition ...
|
|
has =
|
|
idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots;
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
pBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpSarBuffer);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Specified Kind of Pivots ...
|
|
*
|
|
* @param pivots: XPivot, refrence Collection to hold Extracted pivots ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
|
|
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractZigZagPivots(
|
|
XPivot &pivots[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFPivots = 50,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
SpecifiedClean(pivots);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
requiredNumberOFPivots = NormalizeInt(requiredNumberOFPivots, 2);
|
|
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 50);
|
|
|
|
//
|
|
// Validate ...
|
|
if (mHandler == INVALID_HANDLE)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL iBar;
|
|
XPivot iPivot;
|
|
bool has = false;
|
|
int idx = barIndex - 1;
|
|
double tmpZigZagBuffer[];
|
|
double iValue = EMPTY_VALUE;
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
|
|
ENUM_X_PIVOT_TYPE iType = X_PIVOT_TYPE_NONE;
|
|
int maxAllowed = barIndex + maxAllowedLoopbackLength - 1;
|
|
while (idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots)
|
|
{
|
|
//
|
|
idx++;
|
|
|
|
//
|
|
// Prepare ...
|
|
iBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
|
|
//
|
|
// Ignore First Item ...
|
|
if (idx == barIndex)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Initialize Bar ...
|
|
has = iBar.Init(
|
|
symbol,
|
|
period,
|
|
idx //
|
|
);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Reading Buffer ...
|
|
CopyBuffer(
|
|
mHandler, // Handler ...
|
|
XFIMA_ZIGZAG_LINE, // Handler Buffer Number ...
|
|
idx, // Bar Index ...
|
|
1, // Number of Requirements ...
|
|
tmpZigZagBuffer // Buffer ...
|
|
);
|
|
ArraySetAsSeries(tmpZigZagBuffer, true);
|
|
|
|
//
|
|
// Read and Validate Value ...
|
|
iValue = tmpZigZagBuffer[0];
|
|
has = NotEmptyZero(iValue);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Calculate and Validate Type ...
|
|
iType =
|
|
iValue == iBar.high
|
|
? X_PIVOT_TYPE_PEAK
|
|
: iValue == iBar.low
|
|
? X_PIVOT_TYPE_VALE
|
|
: X_PIVOT_TYPE_NONE;
|
|
has = IsXValid(iType);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Calculate and Validate Dir ...
|
|
iDir =
|
|
IsXVale(iType)
|
|
? X_DIRECTION_BULLISH
|
|
: IsXPeak(iType)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(iDir);
|
|
if (!has)
|
|
{
|
|
//
|
|
iBar.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Initialize and Validate Pivot ...
|
|
has = iPivot.Init(
|
|
iValue,
|
|
iBar.time,
|
|
symbol,
|
|
iDir,
|
|
period,
|
|
iType //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iPivot.prefix = ToXString(XFIMA_PIVOT_ZIGZAG);
|
|
|
|
//
|
|
// Add Pivot to Collection only if not Exists ...
|
|
AddIfNotExists(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
|
|
//
|
|
// Check Moving Forward Condition ...
|
|
has =
|
|
idx < maxAllowed &&
|
|
ArraySize(pivots) < requiredNumberOFPivots;
|
|
if (!has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
iBar.Clean();
|
|
iPivot.Clean();
|
|
SpecifiedClean(tmpZigZagBuffer);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Validated Zones ...
|
|
*
|
|
* @param zones: XBoxZone, collection reference to holds results ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
* @param requiredNumberOFZones: int, required Number of Zones ...
|
|
* @param breakValidLength: int, Breake Validation Length of Zones ...
|
|
* @param validateFakeBreakes: bool, Validation Fake Breaked Zones ...
|
|
* @param shadowMultiplier: double a Shadow Multiplier for Validation ...
|
|
* @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ...
|
|
* @param validationLength: int, Validation Length of Zones ...
|
|
* @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int ExtractHKZones(
|
|
XBoxZone &zones[],
|
|
int barIndex = 0,
|
|
int requiredNumberOFZones = 50,
|
|
int breakValidLength = 3,
|
|
bool validateFakeBreakes = true,
|
|
double shadowMultiplier = 3,
|
|
double validationStrength = 1,
|
|
int validationLength = 21,
|
|
int maxAllowedLoopbackLength = 1500 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
SpecifiedClean(zones);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeInt(barIndex, 0);
|
|
validationLength = NormalizeInt(validationLength, 7);
|
|
shadowMultiplier = NormalizeDouble(shadowMultiplier, 1);
|
|
validationStrength = NormalizeDouble(validationStrength, 1);
|
|
requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5);
|
|
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100);
|
|
|
|
//
|
|
// Reading Values ...
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
double minAllowedStrength = (validationStrength * GetPoints(symbol));
|
|
|
|
//
|
|
int count = 0;
|
|
XBoxZone zone;
|
|
bool has = false;
|
|
int start = barIndex;
|
|
bool isBullish = false;
|
|
bool isBearish = false;
|
|
double up = EMPTY_VALUE;
|
|
double low = EMPTY_VALUE;
|
|
double open = EMPTY_VALUE;
|
|
double high = EMPTY_VALUE;
|
|
double down = EMPTY_VALUE;
|
|
double body = EMPTY_VALUE;
|
|
double close = EMPTY_VALUE;
|
|
double range = EMPTY_VALUE;
|
|
bool lowShadowPassed = false;
|
|
bool highShadowPassed = false;
|
|
double lowShadow = EMPTY_VALUE;
|
|
double highShadow = EMPTY_VALUE;
|
|
double startHKLow = EMPTY_VALUE;
|
|
double startHKOpen = EMPTY_VALUE;
|
|
double startHKHigh = EMPTY_VALUE;
|
|
double startHKClose = EMPTY_VALUE;
|
|
ENUM_X_DIRECTION dir = X_DIRECTION_NONE;
|
|
int end = start + maxAllowedLoopbackLength;
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Cleanup ...
|
|
zone.Clean();
|
|
dir = X_DIRECTION_NONE;
|
|
|
|
//
|
|
// Reading HK Buffesr ...
|
|
low = GetHKLow(i);
|
|
open = GetHKOpen(i);
|
|
high = GetHKHigh(i);
|
|
close = GetHKClose(i);
|
|
|
|
//
|
|
// Initialized Start Bar ...
|
|
if (i == start)
|
|
{
|
|
//
|
|
startHKLow = low;
|
|
startHKOpen = open;
|
|
startHKHigh = high;
|
|
startHKClose = close;
|
|
}
|
|
|
|
//
|
|
// Check Direction ...
|
|
isBullish = open < close;
|
|
isBearish = open > close;
|
|
dir =
|
|
(isBullish && !isBearish)
|
|
? X_DIRECTION_BULLISH
|
|
: (isBearish && !isBullish)
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
has = HasDirection(dir);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Calculate Requirements for Processing ...
|
|
up = isBullish
|
|
? close
|
|
: open;
|
|
down = isBullish
|
|
? open
|
|
: close;
|
|
body = MathAbs(up - down);
|
|
range = high - low;
|
|
highShadow = high - up;
|
|
lowShadow = down - low;
|
|
|
|
//
|
|
// Detecting Shadows ...
|
|
|
|
//
|
|
// Low Shadow ...
|
|
lowShadowPassed = lowShadow >= (shadowMultiplier * highShadow);
|
|
|
|
//
|
|
// High Shadow ...
|
|
highShadowPassed = highShadow >= (shadowMultiplier * lowShadow);
|
|
|
|
//
|
|
has = (lowShadowPassed && !highShadowPassed) ||
|
|
(highShadowPassed && !lowShadowPassed);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Filling Zone ...
|
|
|
|
//
|
|
zone.symbol = symbol;
|
|
zone.period = period;
|
|
zone.from = GetBarTime(
|
|
zone.symbol,
|
|
zone.period,
|
|
i //
|
|
);
|
|
zone.dir = lowShadowPassed
|
|
? X_DIRECTION_BULLISH
|
|
: highShadowPassed
|
|
? X_DIRECTION_BEARISH
|
|
: X_DIRECTION_NONE;
|
|
|
|
//
|
|
zone.upper =
|
|
IsXBullish(zone.dir)
|
|
? down
|
|
: IsXBearish(zone.dir)
|
|
? high
|
|
: EMPTY_VALUE;
|
|
|
|
//
|
|
zone.lower =
|
|
IsXBullish(zone.dir)
|
|
? low
|
|
: IsXBearish(zone.dir)
|
|
? up
|
|
: EMPTY_VALUE;
|
|
|
|
//
|
|
zone.to = TimeCurrent();
|
|
zone.type = ToXString(XFIMA_PIVOT_HK) + "_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance"
|
|
: "");
|
|
|
|
//
|
|
// Validate ...
|
|
has =
|
|
zone.IsValid() &&
|
|
HasDirection(zone.dir) &&
|
|
NotEmptyZero(zone.upper) &&
|
|
NotEmptyZero(zone.lower) &&
|
|
(zone.IsBullish()
|
|
? startHKLow > zone.upper
|
|
: startHKHigh < zone.lower) &&
|
|
(zone.upper - zone.lower) >= minAllowedStrength &&
|
|
ValidateHKZone(zone, validationLength, breakValidLength, validateFakeBreakes);
|
|
if (has)
|
|
{
|
|
//
|
|
AddIfNotExists(
|
|
zone,
|
|
zones //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
zone.Clean();
|
|
|
|
//
|
|
// Validating ...
|
|
result = ArraySize(zones);
|
|
has = IsValidSize(result) &&
|
|
result >= requiredNumberOFZones;
|
|
if (has)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resources ...
|
|
zone.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Values Retrievers ...
|
|
|
|
/**
|
|
* Filling Specified Bar index Boundary Values ...
|
|
*
|
|
* @param dest: double, reference collection to hold boundary Values ...
|
|
* @param barIndex: int, Specified Bar's Index ...
|
|
* @param containsFastSlow: bool, Contains XMA Fast / Slow ...
|
|
* @param containsMABond: bool, Contains XMA Boundary Upper / Lower ...
|
|
* @param containsHKBound: bool, Contains XHK Boundary Upper / Lower ...
|
|
* @param containsPBBond: bool, Contains XPB Boundary Upper / Lower ...
|
|
* @param containsFiboLevels: nool, Contains XFIBO Levels ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int FillBoundaryValues(
|
|
double &dest[],
|
|
int barIndex = 0,
|
|
bool containsFastSlow = true,
|
|
bool containsMABond = true,
|
|
bool containsHKBound = true,
|
|
bool containsPBBond = true,
|
|
bool containsFiboLevels = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Prepare ...
|
|
XClean(dest);
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
bool has = IsValid();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Read and Validate Values ...
|
|
|
|
//
|
|
double fast = GetMAFast(barIndex);
|
|
double slow = GetMASlow(barIndex);
|
|
|
|
//
|
|
double maBondUpper = GetMABondUpper(barIndex);
|
|
double maBondLower = GetMABondLower(barIndex);
|
|
|
|
//
|
|
double pbBondUpper = GetPBBondUpper(barIndex);
|
|
double pbBondLower = GetPBBondLower(barIndex);
|
|
|
|
//
|
|
double hkBondUpper = GetHKBondUpper(barIndex);
|
|
double hkBondLower = GetHKBondLower(barIndex);
|
|
|
|
//
|
|
double fiboUpper = GetFiboUpper(barIndex);
|
|
double fiboLower = GetFiboLower(barIndex);
|
|
double fiboMiddle = GetFiboMiddle(barIndex);
|
|
|
|
//
|
|
has =
|
|
NotEmptyZero(fast) &&
|
|
NotEmptyZero(slow) &&
|
|
NotEmptyZero(fiboLower) &&
|
|
NotEmptyZero(fiboUpper) &&
|
|
NotEmptyZero(fiboMiddle) &&
|
|
NotEmptyZero(maBondUpper) &&
|
|
NotEmptyZero(maBondLower) &&
|
|
NotEmptyZero(pbBondUpper) &&
|
|
NotEmptyZero(pbBondLower) &&
|
|
NotEmptyZero(hkBondUpper) &&
|
|
NotEmptyZero(hkBondLower);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Fill Dest ...
|
|
|
|
//
|
|
// XMA Fast / Slow ...
|
|
if (containsFastSlow)
|
|
{
|
|
//
|
|
Add(fast, dest);
|
|
Add(slow, dest);
|
|
}
|
|
|
|
//
|
|
// XMA Bound ...
|
|
if (containsMABond)
|
|
{
|
|
//
|
|
Add(maBondUpper, dest);
|
|
Add(maBondLower, dest);
|
|
}
|
|
|
|
//
|
|
// XHK Bond ...
|
|
if (containsHKBound)
|
|
{
|
|
//
|
|
Add(hkBondUpper, dest);
|
|
Add(hkBondLower, dest);
|
|
}
|
|
|
|
//
|
|
// XPB Bond ...
|
|
if (containsPBBond)
|
|
{
|
|
//
|
|
Add(pbBondUpper, dest);
|
|
Add(pbBondLower, dest);
|
|
}
|
|
|
|
//
|
|
// XFIBO Zones ...
|
|
if (containsFiboLevels)
|
|
{
|
|
//
|
|
Add(fiboLower, dest);
|
|
Add(fiboUpper, dest);
|
|
Add(fiboMiddle, dest);
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Fast, Slow, MA Bond Upper/Lower, HK Bond Upper/Lower and PB Bond Upper/Lower Min/Max ...
|
|
*
|
|
* @param min: double, minimum value ...
|
|
* @param max: double, maximum value ...
|
|
* @param barIndex: int, Specified Bar Index ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBoundaryValues(
|
|
double &min,
|
|
double &max,
|
|
int barIndex = 0,
|
|
bool containsFastSlow = true,
|
|
bool containsMABond = true,
|
|
bool containsHKBound = true,
|
|
bool containsPBBond = true,
|
|
bool containsFiboLevels = false //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Prepare ...
|
|
min = EMPTY_VALUE;
|
|
max = EMPTY_VALUE;
|
|
|
|
//
|
|
// Normalize ...
|
|
barIndex = NormalizeBarIndex(barIndex);
|
|
|
|
//
|
|
// Validate ...
|
|
result = IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double fast = GetMAFast(barIndex);
|
|
double slow = GetMASlow(barIndex);
|
|
|
|
//
|
|
double maBondUpper = GetMABondUpper(barIndex);
|
|
double maBondLower = GetMABondLower(barIndex);
|
|
|
|
//
|
|
double pbBondUpper = GetPBBondUpper(barIndex);
|
|
double pbBondLower = GetPBBondLower(barIndex);
|
|
|
|
//
|
|
double hkBondUpper = GetHKBondUpper(barIndex);
|
|
double hkBondLower = GetHKBondLower(barIndex);
|
|
|
|
//
|
|
double fiboUpper = GetFiboUpper(barIndex);
|
|
double fiboLower = GetFiboLower(barIndex);
|
|
double fiboMiddle = GetFiboMiddle(barIndex);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(fast) &&
|
|
NotEmptyZero(slow) &&
|
|
NotEmptyZero(fiboLower) &&
|
|
NotEmptyZero(fiboUpper) &&
|
|
NotEmptyZero(fiboMiddle) &&
|
|
NotEmptyZero(maBondUpper) &&
|
|
NotEmptyZero(maBondLower) &&
|
|
NotEmptyZero(pbBondUpper) &&
|
|
NotEmptyZero(pbBondLower) &&
|
|
NotEmptyZero(hkBondUpper) &&
|
|
NotEmptyZero(hkBondLower);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double values[];
|
|
|
|
//
|
|
if (containsFastSlow)
|
|
{
|
|
//
|
|
Add(fast, values);
|
|
Add(slow, values);
|
|
}
|
|
|
|
//
|
|
if (containsMABond)
|
|
{
|
|
//
|
|
Add(maBondUpper, values);
|
|
Add(maBondLower, values);
|
|
}
|
|
|
|
//
|
|
if (containsHKBound)
|
|
{
|
|
//
|
|
Add(hkBondUpper, values);
|
|
Add(hkBondLower, values);
|
|
}
|
|
|
|
//
|
|
if (containsPBBond)
|
|
{
|
|
//
|
|
Add(pbBondUpper, values);
|
|
Add(pbBondLower, values);
|
|
}
|
|
|
|
//
|
|
if (containsFiboLevels)
|
|
{
|
|
//
|
|
Add(fiboLower, values);
|
|
Add(fiboUpper, values);
|
|
Add(fiboMiddle, values);
|
|
}
|
|
|
|
//
|
|
result = HasChild(values);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
min = GetMin(values);
|
|
max = GetMax(values);
|
|
|
|
//
|
|
result =
|
|
NotEmptyZero(min) &&
|
|
NotEmptyZero(max) &&
|
|
min < max;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Fast MA ...
|
|
|
|
//
|
|
double GetMAFast(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MA_FAST_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMAFast(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MA_FAST_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Fast MA State ...
|
|
|
|
//
|
|
double GetMAFastState(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MA_FAST_STATE_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMAFastState(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MA_FAST_STATE_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Slow MA ...
|
|
|
|
//
|
|
double GetMASlow(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MA_SLOW_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMASlow(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MA_SLOW_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Slow MA State ...
|
|
|
|
//
|
|
double GetMASlowState(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MA_SLOW_STATE_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMASlowState(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MA_SLOW_STATE_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Upper MA ...
|
|
|
|
//
|
|
double GetMABondUpper(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MA_BOND_UPPER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMABondUpper(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MA_BOND_UPPER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Lower MA ...
|
|
|
|
//
|
|
double GetMABondLower(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MA_BOND_LOWER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMABondLower(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MA_BOND_LOWER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XPB ...
|
|
|
|
//
|
|
// Upper PB ...
|
|
|
|
//
|
|
double GetPBBondUpper(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_PB_BOND_UPPER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyPBBondUpper(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_PB_BOND_UPPER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Lower PB ...
|
|
|
|
//
|
|
double GetPBBondLower(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_PB_BOND_LOWER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyPBBondLower(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_PB_BOND_LOWER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Upper PB ...
|
|
|
|
//
|
|
double GetPBRawBondUpper(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_PB_BOND_RAW_UPPER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyPBRawBondUpper(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_PB_BOND_RAW_UPPER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Lower PB ...
|
|
|
|
//
|
|
double GetPBRawBondLower(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_PB_BOND_RAW_LOWER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyPBRawBondLower(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_PB_BOND_RAW_LOWER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// SAR ...
|
|
|
|
//
|
|
double GetSar(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_SAR_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopySar(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_SAR_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// SAR State ...
|
|
|
|
//
|
|
double GetSarState(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_SAR_STATE_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopySarState(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_SAR_STATE_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// PEAK ...
|
|
|
|
//
|
|
double GetPeak(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_PEAK_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyPeak(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_PEAK_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// VALE ...
|
|
|
|
//
|
|
double GetVale(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_VALE_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyVale(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_VALE_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// FIBO Zone ...
|
|
|
|
//
|
|
// FIBO Upper ...
|
|
|
|
//
|
|
double GetFiboUpper(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_FIBO_UPPER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyFiboUpper(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_FIBO_UPPER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// FIBO Middle ...
|
|
|
|
//
|
|
double GetFiboMiddle(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_FIBO_MIDDLE_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyFiboMiddle(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_FIBO_MIDDLE_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// FIBO Lower ...
|
|
|
|
//
|
|
double GetFiboLower(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_FIBO_LOWER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyFiboLower(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_FIBO_LOWER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// ZigZag ...
|
|
|
|
//
|
|
double GetZigZag(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_ZIGZAG_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyZigZag(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_ZIGZAG_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// CYCLES Range ...
|
|
|
|
//
|
|
// SHORT ...
|
|
|
|
//
|
|
// HH ...
|
|
|
|
//
|
|
double GetSHH(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_SC_HH_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopySHH(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_SC_HH_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
|
|
//
|
|
double GetSLL(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_SC_LL_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopySLL(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_SC_LL_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// MEDIUM ...
|
|
|
|
//
|
|
// HH ...
|
|
|
|
//
|
|
double GetMHH(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MC_HH_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMHH(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MC_HH_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
|
|
//
|
|
double GetMLL(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_MC_LL_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyMLL(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_MC_LL_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// LONG ...
|
|
|
|
//
|
|
// HH ...
|
|
|
|
//
|
|
double GetLHH(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_LC_HH_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyLHH(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_LC_HH_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
|
|
//
|
|
double GetLLL(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_LC_LL_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyLLL(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_LC_LL_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// HIND ...
|
|
|
|
//
|
|
// HH ...
|
|
|
|
//
|
|
double GetHHH(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HC_HH_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHHH(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HC_HH_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// LL ...
|
|
|
|
//
|
|
double GetHLL(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HC_LL_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHLL(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HC_LL_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK ...
|
|
|
|
//
|
|
// XHK Open ...
|
|
|
|
//
|
|
double GetHKOpen(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_OPEN_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKOpen(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_OPEN_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK High ...
|
|
|
|
//
|
|
double GetHKHigh(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_HIGH_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKHigh(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_HIGH_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Low ...
|
|
|
|
//
|
|
double GetHKLow(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_LOW_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKLow(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_LOW_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Close ...
|
|
|
|
//
|
|
double GetHKClose(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_CLOSE_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKClose(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_CLOSE_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Color ...
|
|
|
|
//
|
|
double GetHKColor(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_COLOR_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKColor(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_COLOR_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Raw ...
|
|
|
|
//
|
|
// XHK Raw Open ...
|
|
|
|
//
|
|
double GetHKRawOpen(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_RAW_OPEN_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKRawOpen(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_RAW_OPEN_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Raw High ...
|
|
|
|
//
|
|
double GetHKRawHigh(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_RAW_HIGH_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKRawHigh(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_RAW_HIGH_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Raw Low ...
|
|
|
|
//
|
|
double GetHKRawLow(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_RAW_LOW_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKRawLow(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_RAW_LOW_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Raw Close ...
|
|
|
|
//
|
|
double GetHKRawClose(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_RAW_CLOSE_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKRawClose(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_RAW_CLOSE_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Bond ...
|
|
|
|
//
|
|
// XHK Bond Upper ...
|
|
|
|
//
|
|
double GetHKBondUpper(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_BOND_UPPER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKBondUpper(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_BOND_UPPER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// XHK Bond Lower ...
|
|
|
|
//
|
|
double GetHKBondLower(
|
|
int barIndex // Bar Index
|
|
)
|
|
{
|
|
//
|
|
return ReadValue(
|
|
(int)XFIMA_HK_BOND_LOWER_LINE,
|
|
barIndex //
|
|
);
|
|
}
|
|
|
|
//
|
|
int CopyHKBondLower(
|
|
int start, // Start
|
|
int count, // Number of Items for read
|
|
double &buffer[], // Dest Buffer
|
|
bool asSeries = true // As Series Flag
|
|
)
|
|
{
|
|
//
|
|
return ReadValues(
|
|
buffer,
|
|
(int)XFIMA_HK_BOND_LOWER_LINE,
|
|
start,
|
|
count,
|
|
asSeries //
|
|
);
|
|
}
|
|
|
|
//
|
|
// Protected ...
|
|
protected:
|
|
//
|
|
// Private ...
|
|
private:
|
|
//
|
|
// Props ...
|
|
XFIMAInputs mInputs; // Inputs ...
|
|
|
|
//
|
|
// XHK Helper ...
|
|
|
|
/**
|
|
* Validate HK Zone ...
|
|
*
|
|
* @param zone: XBoxZone, reference to Specified Zone ...
|
|
* @param validationLength: int, Validation Length of Zones ...
|
|
* @param breakValidLength: int, Break Validation Length of Zones ...
|
|
* @param validateFakeBreakes: bool, Validation Fake Breaked Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool ValidateHKZone(
|
|
XBoxZone &zone,
|
|
int validationLength = 1,
|
|
int breakValidLength = 3,
|
|
bool validateFakeBreakes = true //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
// Normalize ...
|
|
validationLength = NormalizeInt(validationLength, 1);
|
|
breakValidLength = NormalizeInt(breakValidLength, 2);
|
|
|
|
//
|
|
// Validate ...
|
|
result = zone.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Requirements ...
|
|
double low = EMPTY_VALUE;
|
|
double open = EMPTY_VALUE;
|
|
double high = EMPTY_VALUE;
|
|
double close = EMPTY_VALUE;
|
|
|
|
//
|
|
int count = 0;
|
|
int start = zone.FromIndex() + 1;
|
|
int end = start + validationLength;
|
|
|
|
//
|
|
// Validate Before ...
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Reading HK ...
|
|
low = GetHKLow(i);
|
|
high = GetHKHigh(i);
|
|
result =
|
|
NotEmptyZero(low) &&
|
|
NotEmptyZero(high);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = zone.IsBullish()
|
|
? low > zone.lower
|
|
: high < zone.upper;
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Validating After ...
|
|
if (result)
|
|
{
|
|
//
|
|
start = zone.ToIndex() + 1;
|
|
count = zone.FromIndex() - start;
|
|
end = start + count;
|
|
for (int i = start; i < end; i++)
|
|
{
|
|
//
|
|
// Read HK ...
|
|
low = GetHKLow(i);
|
|
high = GetHKHigh(i);
|
|
result =
|
|
NotEmptyZero(low) &&
|
|
NotEmptyZero(high);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = zone.IsBullish()
|
|
? low > zone.lower
|
|
: high < zone.upper;
|
|
if (!result)
|
|
{
|
|
//
|
|
// Check For Fake Breake ...
|
|
if (validateFakeBreakes && breakValidLength > 0)
|
|
{
|
|
//
|
|
result = i - 1 >= 0;
|
|
if (result)
|
|
{
|
|
//
|
|
for (int j = i - 1; j >= zone.ToIndex(); j--)
|
|
{
|
|
//
|
|
// Reading HK ...
|
|
close = GetHKClose(j);
|
|
result = NotEmptyZero(close);
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = zone.IsBullish()
|
|
? close > zone.upper
|
|
: close < zone.lower;
|
|
if (result)
|
|
{
|
|
//
|
|
result = MathAbs(j - i) <= breakValidLength;
|
|
if (result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
if (!result)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Cleanup Resource ...
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
// |