3916 lines
88 KiB
Plaintext
3916 lines
88 KiB
Plaintext
|
|
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Seriallize Library
|
|
// ---------------------------------------
|
|
// Name: XPOILib
|
|
// Description: All models related to POIs ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright `023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
|
|
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
|
|
|
|
//
|
|
enum ENUM_X_OBFVG_FVG_FILTERS
|
|
{
|
|
X_OBFVG_FVG_FILTER_NONE,
|
|
X_OBFVG_FVG_FILTER_INSIDE_OR,
|
|
X_OBFVG_FVG_FILTER_ABOVE_BELOW,
|
|
};
|
|
|
|
//
|
|
enum ENUM_X_OBFVG_FVG_SELECTION
|
|
{
|
|
X_OBFVG_FVG_SELECT_NONE,
|
|
X_OBFVG_FVG_SELECT_OLDEST,
|
|
X_OBFVG_FVG_SELECT_LOWEST,
|
|
X_OBFVG_FVG_SELECT_HIGHEST,
|
|
X_OBFVG_FVG_SELECT_YOUNGEST,
|
|
X_OBFVG_FVG_SELECT_HIGHEST_LOWEST,
|
|
X_OBFVG_FVG_SELECT_LOWEST_HIGHEST,
|
|
};
|
|
|
|
//
|
|
struct XOBFVGPivot
|
|
{
|
|
//
|
|
// Props ...
|
|
double value;
|
|
datetime at;
|
|
|
|
//
|
|
// Constructor ...
|
|
XOBFVGPivot()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
void Clean()
|
|
{
|
|
//
|
|
value = 0;
|
|
at = NULL;
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
//
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
value > 0 &&
|
|
IsValid(at);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
};
|
|
|
|
//
|
|
struct XOBFVG
|
|
{
|
|
//
|
|
// Props ...
|
|
XCFVG *fvg;
|
|
XCOrderBlock *ob;
|
|
|
|
//
|
|
// Constructor ...
|
|
XOBFVG()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
void Clean()
|
|
{
|
|
//
|
|
ZeroMemory(ob);
|
|
ZeroMemory(fvg);
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
//
|
|
bool IsValid()
|
|
{
|
|
return HasOB() &&
|
|
HasFVG();
|
|
}
|
|
|
|
//
|
|
bool HasOB()
|
|
{
|
|
return ob != NULL &&
|
|
ob.IsValid();
|
|
}
|
|
|
|
//
|
|
bool HasFVG()
|
|
{
|
|
return fvg != NULL &&
|
|
fvg.IsValid();
|
|
}
|
|
|
|
//
|
|
ENUM_X_DIRECTION GetDirection()
|
|
{
|
|
//
|
|
ENUM_X_DIRECTION result = X_DIRECTION_NONE;
|
|
|
|
//
|
|
bool isValid = IsValid();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ob.GetDirection();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool IsBullish()
|
|
{
|
|
return IsBullish(GetDirection());
|
|
}
|
|
|
|
//
|
|
bool IsBearish()
|
|
{
|
|
return IsBearish(GetDirection());
|
|
}
|
|
|
|
//
|
|
int GetSwings(
|
|
XOBFVGPivot &pivots[] //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(pivots);
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
ENUM_X_DIRECTION forDir = GetDirection();
|
|
bool isBullish = IsBullish(forDir);
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
XOBFVGPivot iPivot;
|
|
bool isPassed = false;
|
|
double appliedPrice = 0;
|
|
bool isBodyState = false;
|
|
|
|
//
|
|
// Start ...
|
|
isPassed = ob.IsStarted(
|
|
forDir,
|
|
passedBar,
|
|
isBodyState //
|
|
);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
appliedPrice =
|
|
isBullish
|
|
? passedBar.low
|
|
: passedBar.high;
|
|
|
|
//
|
|
iPivot.Clean();
|
|
iPivot.value = appliedPrice;
|
|
iPivot.at = passedBar.time;
|
|
|
|
//
|
|
AddRef(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// Activation ...
|
|
isPassed = ob.IsActivated(
|
|
forDir,
|
|
passedBar,
|
|
isBodyState //
|
|
);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
appliedPrice =
|
|
isBullish
|
|
? passedBar.low
|
|
: passedBar.high;
|
|
|
|
//
|
|
iPivot.Clean();
|
|
iPivot.value = appliedPrice;
|
|
iPivot.at = passedBar.time;
|
|
|
|
//
|
|
AddRef(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
// Worked ...
|
|
isPassed = ob.IsWorked(
|
|
forDir,
|
|
passedBar,
|
|
isBodyState //
|
|
);
|
|
if (isPassed)
|
|
{
|
|
//
|
|
appliedPrice =
|
|
isBullish
|
|
? passedBar.low
|
|
: passedBar.high;
|
|
|
|
//
|
|
iPivot.Clean();
|
|
iPivot.value = appliedPrice;
|
|
iPivot.at = passedBar.time;
|
|
|
|
//
|
|
AddRef(
|
|
iPivot,
|
|
pivots //
|
|
);
|
|
|
|
//
|
|
iPivot.Clean();
|
|
}
|
|
|
|
//
|
|
passedBar.Clean();
|
|
|
|
//
|
|
result = ArraySize(pivots);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void UpdateTo(datetime value = NULL)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
has = HasOB();
|
|
if (has)
|
|
{
|
|
ob.To(value);
|
|
}
|
|
|
|
//
|
|
has = HasFVG();
|
|
if (has)
|
|
{
|
|
fvg.To(value);
|
|
}
|
|
}
|
|
};
|
|
|
|
//
|
|
//
|
|
// Model Exists Founded POIs ...
|
|
struct XPOIState
|
|
{
|
|
//
|
|
string symbol;
|
|
ENUM_TIMEFRAMES period;
|
|
datetime time;
|
|
|
|
//
|
|
XCSwing *swings[]; // Holds Founded Swing ...
|
|
XCSwing *swingLows[]; // Holds Founded Swing Lows ...
|
|
XCSwing *swingHighs[]; // Holds Founded Swing Highs ...
|
|
|
|
//
|
|
XCMomentumBar *momentumBars[]; // Holds Founded Momentum Bars ...
|
|
XCMomentumBar *bullishMomentumBars[]; // Holds Founded Bullish Momentum Bars ...
|
|
XCMomentumBar *bearishMomentumBars[]; // Holds Founded Bearish Momentum Bars ...
|
|
|
|
//
|
|
XCRejectionBar *rejectionBars[]; // Holds Founded Rejection Bars ...
|
|
XCRejectionBar *bullishRejectionBars[]; // Holds Founded Bullish Rejection Bars ...
|
|
XCRejectionBar *bearishRejectionBars[]; // Holds Founded Bearish Rejection Bars ...
|
|
|
|
//
|
|
XCSupportZone *supportZones[]; // Holds Founded Support Zones ...
|
|
XCResistanceZone *resistanceZones[]; // Holds Founded Resistance Zones ...
|
|
|
|
//
|
|
XCSupplyZone *supplyZones[]; // Holds Founded Supply Zones ...
|
|
XCDemandZone *demandZones[]; // Holds Founded Demand Zones ...
|
|
|
|
//
|
|
XCOrderBlock *orderBlocks[]; // Holds Founded Order Blocks ...
|
|
XCOrderBlock *bullishOrderBlocks[]; // Holds Founded Bullish Order Blocks ...
|
|
XCOrderBlock *bearishOrderBlocks[]; // Holds Founded Bearish Order Blocks ...
|
|
|
|
//
|
|
XCFVG *fairValueGaps[]; // Holds Founded Fair Value Gaps ...
|
|
XCFVG *bullishFairValueGaps[]; // Holds Founded Bullish Fair Value Gaps ...
|
|
XCFVG *bearishFairValueGaps[]; // Holds Founded Bearish Fair Value Gaps ...
|
|
|
|
//
|
|
// Constructor ...
|
|
void XPOIState()
|
|
{
|
|
Clean();
|
|
}
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Cleanup all props ...
|
|
*/
|
|
void Clean()
|
|
{
|
|
//
|
|
time = NULL;
|
|
symbol = NULL;
|
|
period = NULL;
|
|
|
|
//
|
|
Clean(swings);
|
|
Clean(swingLows);
|
|
Clean(swingHighs);
|
|
|
|
//
|
|
Clean(momentumBars);
|
|
Clean(bullishMomentumBars);
|
|
Clean(bearishMomentumBars);
|
|
|
|
//
|
|
Clean(rejectionBars);
|
|
Clean(bullishRejectionBars);
|
|
Clean(bearishRejectionBars);
|
|
|
|
//
|
|
Clean(supportZones);
|
|
Clean(resistanceZones);
|
|
|
|
//
|
|
Clean(supplyZones);
|
|
Clean(demandZones);
|
|
|
|
//
|
|
Clean(orderBlocks);
|
|
Clean(bullishOrderBlocks);
|
|
Clean(bearishOrderBlocks);
|
|
|
|
//
|
|
Clean(fairValueGaps);
|
|
Clean(bullishFairValueGaps);
|
|
Clean(bearishFairValueGaps);
|
|
|
|
//
|
|
ZeroMemory(this);
|
|
}
|
|
|
|
/**
|
|
* Validate ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool IsValid()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
IsSpecifiedValid(symbol) &&
|
|
IsSpecifiedValid(period) &&
|
|
IsSpecifiedValid(time);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check State has Childs or not ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool HasChild()
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
//
|
|
IsValidSize(CountSwingHighs()) ||
|
|
IsValidSize(CountSwingLows()) ||
|
|
IsValidSize(CountBullishMomentumBars()) ||
|
|
IsValidSize(CountBearishMomentumBars()) ||
|
|
IsValidSize(CountBullishRejectionBars()) ||
|
|
IsValidSize(CountBearishRejectionBars()) ||
|
|
IsValidSize(CountSupportZones()) ||
|
|
IsValidSize(CountResistanceZones()) ||
|
|
IsValidSize(CountSupplyZones()) ||
|
|
IsValidSize(CountDemandZones()) ||
|
|
IsValidSize(CountBullishOrderBlocks()) ||
|
|
IsValidSize(CountBearishOrderBlocks()) ||
|
|
IsValidSize(CountBullishFairValueGaps()) ||
|
|
IsValidSize(CountBearishFairValueGaps())
|
|
//
|
|
;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Fill Dest State by Current State's Data ...
|
|
*
|
|
* @param dest: XPOIState instance, reference to specified dest ...
|
|
*
|
|
*/
|
|
void Fill(XPOIState &dest)
|
|
{
|
|
//
|
|
if (!IsValid() ||
|
|
!HasChild())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
dest.symbol = symbol;
|
|
dest.period = period;
|
|
dest.time = time;
|
|
|
|
//
|
|
Copy(
|
|
swingHighs,
|
|
dest.swingHighs,
|
|
false //
|
|
);
|
|
Copy(
|
|
swingLows,
|
|
dest.swingLows,
|
|
false //
|
|
);
|
|
Copy(
|
|
bullishMomentumBars,
|
|
dest.bullishMomentumBars,
|
|
false //
|
|
);
|
|
Copy(
|
|
bearishMomentumBars,
|
|
dest.bearishMomentumBars,
|
|
false //
|
|
);
|
|
Copy(
|
|
bullishRejectionBars,
|
|
dest.bullishRejectionBars,
|
|
false //
|
|
);
|
|
Copy(
|
|
bearishRejectionBars,
|
|
dest.bearishRejectionBars,
|
|
false //
|
|
);
|
|
Copy(
|
|
supportZones,
|
|
dest.supportZones,
|
|
false //
|
|
);
|
|
Copy(
|
|
resistanceZones,
|
|
dest.resistanceZones,
|
|
false //
|
|
);
|
|
Copy(
|
|
supplyZones,
|
|
dest.supplyZones,
|
|
false //
|
|
);
|
|
Copy(
|
|
demandZones,
|
|
dest.demandZones,
|
|
false //
|
|
);
|
|
Copy(
|
|
bullishOrderBlocks,
|
|
dest.bullishOrderBlocks,
|
|
false //
|
|
);
|
|
Copy(
|
|
bearishOrderBlocks,
|
|
dest.bearishOrderBlocks,
|
|
false //
|
|
);
|
|
Copy(
|
|
bullishFairValueGaps,
|
|
dest.bullishFairValueGaps,
|
|
false //
|
|
);
|
|
Copy(
|
|
bearishFairValueGaps,
|
|
dest.bearishFairValueGaps,
|
|
false //
|
|
);
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
// Counters ...
|
|
|
|
//
|
|
int CountSwings()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(swings);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasSwings()
|
|
{
|
|
return IsValidSize(CountSwings());
|
|
}
|
|
|
|
//
|
|
int CountSwingHighs()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(swingHighs);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasSwingHighs()
|
|
{
|
|
return IsValidSize(CountSwingHighs());
|
|
}
|
|
|
|
//
|
|
int CountSwingLows()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(swingLows);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasSwingLows()
|
|
{
|
|
return IsValidSize(CountSwingLows());
|
|
}
|
|
|
|
//
|
|
int CountMomentumBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(momentumBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasMomentumBars()
|
|
{
|
|
return IsValidSize(CountMomentumBars());
|
|
}
|
|
|
|
//
|
|
int CountBullishMomentumBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bullishMomentumBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBullishMomentumBars()
|
|
{
|
|
return IsValidSize(CountBullishMomentumBars());
|
|
}
|
|
|
|
//
|
|
int CountBearishMomentumBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bearishMomentumBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBearishMomentumBars()
|
|
{
|
|
return IsValidSize(CountBearishMomentumBars());
|
|
}
|
|
|
|
//
|
|
int CountRejectionBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(rejectionBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasRejectionBars()
|
|
{
|
|
return IsValidSize(CountRejectionBars());
|
|
}
|
|
|
|
//
|
|
int CountBullishRejectionBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bullishRejectionBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBullishRejectionBars()
|
|
{
|
|
return IsValidSize(CountBullishRejectionBars());
|
|
}
|
|
|
|
//
|
|
int CountBearishRejectionBars()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bearishRejectionBars);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBearishRejectionBars()
|
|
{
|
|
return IsValidSize(CountBearishRejectionBars());
|
|
}
|
|
|
|
//
|
|
int CountSupportZones()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(supportZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasSupportZones()
|
|
{
|
|
return IsValidSize(CountSupportZones());
|
|
}
|
|
|
|
//
|
|
int CountResistanceZones()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(resistanceZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasResistanceZones()
|
|
{
|
|
return IsValidSize(CountResistanceZones());
|
|
}
|
|
|
|
//
|
|
int CountSupplyZones()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(supplyZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasSupplyZones()
|
|
{
|
|
return IsValidSize(CountSupplyZones());
|
|
}
|
|
|
|
//
|
|
int CountDemandZones()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(demandZones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasDemandZones()
|
|
{
|
|
return IsValidSize(CountDemandZones());
|
|
}
|
|
|
|
//
|
|
int CountOrderBlocks()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(orderBlocks);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasOrderBlocks()
|
|
{
|
|
return IsValidSize(CountOrderBlocks());
|
|
}
|
|
|
|
//
|
|
int CountBullishOrderBlocks()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bullishOrderBlocks);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBullishOrderBlocks()
|
|
{
|
|
return IsValidSize(CountBullishOrderBlocks());
|
|
}
|
|
|
|
//
|
|
int CountBearishOrderBlocks()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bearishOrderBlocks);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBearishOrderBlocks()
|
|
{
|
|
return IsValidSize(CountBearishOrderBlocks());
|
|
}
|
|
|
|
//
|
|
int CountFairValueGaps()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(fairValueGaps);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasFairValueGaps()
|
|
{
|
|
return IsValidSize(CountFairValueGaps());
|
|
}
|
|
|
|
//
|
|
int CountBullishFairValueGaps()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bullishFairValueGaps);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBullishFairValueGaps()
|
|
{
|
|
return IsValidSize(CountBullishFairValueGaps());
|
|
}
|
|
|
|
//
|
|
int CountBearishFairValueGaps()
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (!IsValid())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArraySize(bearishFairValueGaps);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool HasBearishFairValueGaps()
|
|
{
|
|
return IsValidSize(CountBearishFairValueGaps());
|
|
}
|
|
|
|
//
|
|
void UpdateTo(datetime value = NULL)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
has = HasMomentumBars();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountMomentumBars();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
momentumBars[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBullishMomentumBars();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBullishMomentumBars();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bullishMomentumBars[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBearishMomentumBars();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBearishMomentumBars();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bearishMomentumBars[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasRejectionBars();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountRejectionBars();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
rejectionBars[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBullishRejectionBars();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBullishRejectionBars();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bullishRejectionBars[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBearishRejectionBars();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBearishRejectionBars();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bearishRejectionBars[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasSupportZones();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountSupportZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
supportZones[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasResistanceZones();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountResistanceZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
resistanceZones[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasSupplyZones();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountSupplyZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
supplyZones[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasDemandZones();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountDemandZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
demandZones[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasOrderBlocks();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountOrderBlocks();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
orderBlocks[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBullishOrderBlocks();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBullishOrderBlocks();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bullishOrderBlocks[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBearishOrderBlocks();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBearishOrderBlocks();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bearishOrderBlocks[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasFairValueGaps();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountFairValueGaps();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
fairValueGaps[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBullishFairValueGaps();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBullishFairValueGaps();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bullishFairValueGaps[i].To(value);
|
|
}
|
|
}
|
|
|
|
//
|
|
has = HasBearishFairValueGaps();
|
|
if (has)
|
|
{
|
|
//
|
|
count = CountBearishFairValueGaps();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
bearishFairValueGaps[i].To(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Filter Zones ...
|
|
|
|
//
|
|
// Support ...
|
|
int FilterSupportZones(
|
|
XCSupportZone *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasSupportZones();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BULLISH;
|
|
count = CountSupportZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCSupportZone *iZone = supportZones[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Resistance ...
|
|
int FilterResistanceZones(
|
|
XCResistanceZone *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasResistanceZones();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BEARISH;
|
|
count = CountResistanceZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCResistanceZone *iZone = resistanceZones[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Supply ...
|
|
int FilterSupplyZones(
|
|
XCSupplyZone *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasSupplyZones();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BEARISH;
|
|
count = CountSupplyZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCSupplyZone *iZone = supplyZones[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Demand ...
|
|
int FilterDemandZones(
|
|
XCDemandZone *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasDemandZones();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BULLISH;
|
|
count = CountDemandZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCDemandZone *iZone = demandZones[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// OrderBlock ...
|
|
int FilterOrderBlocks(
|
|
XCOrderBlock *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasOrderBlocks();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
count = CountOrderBlocks();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iZone = orderBlocks[i];
|
|
passedDir = iZone.GetDirection();
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bullish OrderBlock ...
|
|
int FilterBullishOrderBlocks(
|
|
XCOrderBlock *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasBullishOrderBlocks();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BULLISH;
|
|
count = CountBullishOrderBlocks();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iZone = bullishOrderBlocks[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bearish OrderBlock ...
|
|
int FilterBearishOrderBlocks(
|
|
XCOrderBlock *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasBearishOrderBlocks();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BEARISH;
|
|
count = CountBearishOrderBlocks();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iZone = bearishOrderBlocks[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// FairValueGap ...
|
|
int FilterFairValueGaps(
|
|
XCFVG *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasFairValueGaps();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
count = CountFairValueGaps();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCFVG *iZone = fairValueGaps[i];
|
|
passedDir = iZone.GetDirection();
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bullish FairValueGap ...
|
|
int FilterBullishFairValueGaps(
|
|
XCFVG *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasBullishFairValueGaps();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BULLISH;
|
|
count = CountBullishFairValueGaps();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCFVG *iZone = bullishFairValueGaps[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Bearish FairValueGap ...
|
|
int FilterBearishFairValueGaps(
|
|
XCFVG *&dest[],
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
int idx = -1;
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasBearishFairValueGaps();
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XOHCL passedBar;
|
|
ENUM_X_DIRECTION passedDir = X_DIRECTION_NONE;
|
|
passedDir = X_DIRECTION_BEARISH;
|
|
count = CountBearishFairValueGaps();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XCFVG *iZone = bearishFairValueGaps[i];
|
|
|
|
//
|
|
// Check Started State ...
|
|
if (startState == XZONE_STATE_PASSED ||
|
|
startState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isStarted = iZone.IsStarted(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
startState == XZONE_STATE_FAILED
|
|
? !isStarted
|
|
: !forceStartedBodyOut
|
|
? isStarted
|
|
: isStarted &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Activation State ...
|
|
if (activeState == XZONE_STATE_PASSED ||
|
|
activeState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyIn = false;
|
|
bool isActivated = iZone.IsActivated(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyIn,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
activeState == XZONE_STATE_FAILED
|
|
? !isActivated
|
|
: !forceActivatedBodyIn
|
|
? isActivated
|
|
: isActivated &&
|
|
isBodyIn;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Break State ...
|
|
if (breakState == XZONE_STATE_PASSED ||
|
|
breakState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isBreaked = iZone.IsBreaked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
forceStartedBodyOut,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
breakState == XZONE_STATE_FAILED
|
|
? !isBreaked
|
|
: !forceBreakedBodyOut
|
|
? isBreaked
|
|
: isBreaked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Work State ...
|
|
if (workState == XZONE_STATE_PASSED ||
|
|
workState == XZONE_STATE_FAILED)
|
|
{
|
|
//
|
|
bool ignoreActivation = activeState != XZONE_STATE_PASSED;
|
|
|
|
//
|
|
bool isBodyOut = false;
|
|
bool isWorked = iZone.IsWorked(
|
|
passedDir,
|
|
passedBar,
|
|
isBodyOut,
|
|
ignoreActivation,
|
|
forceStartedBodyOut,
|
|
forceActivatedBodyIn,
|
|
forPeriod //
|
|
);
|
|
|
|
//
|
|
bool isPassed =
|
|
workState == XZONE_STATE_FAILED
|
|
? !isWorked
|
|
: !forceWorkedBodyOut
|
|
? isWorked
|
|
: isWorked &&
|
|
isBodyOut;
|
|
|
|
//
|
|
passedBar.Clean();
|
|
if (!isPassed)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check Filtered Zone Doesn't Exists ...
|
|
has = FindIndex(
|
|
idx,
|
|
iZone,
|
|
dest //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
passedBar.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
Add(
|
|
iZone,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
// End For ...
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
void Filter(
|
|
XPOIState &dest,
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_FAILED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int count = 0;
|
|
bool has = false;
|
|
|
|
//
|
|
dest.Clean();
|
|
|
|
//
|
|
if (!IsValid(forPeriod))
|
|
{
|
|
forPeriod = period;
|
|
}
|
|
|
|
//
|
|
has = IsValid() &&
|
|
HasChild();
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
dest = this;
|
|
|
|
//
|
|
// Support Zones ...
|
|
FilterSupportZones(
|
|
dest.supportZones,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// Resistance Zones ...
|
|
FilterResistanceZones(
|
|
dest.resistanceZones,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// Supply Zones ...
|
|
FilterSupplyZones(
|
|
dest.supplyZones,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// Demand Zones ...
|
|
FilterDemandZones(
|
|
dest.demandZones,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// OrderBlocks ...
|
|
FilterOrderBlocks(
|
|
dest.orderBlocks,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// Bullish OrderBlocks ...
|
|
FilterBullishOrderBlocks(
|
|
dest.bullishOrderBlocks,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// Bearish OrderBlocks ...
|
|
FilterBearishOrderBlocks(
|
|
dest.bearishOrderBlocks,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// FairValueGaps ...
|
|
FilterFairValueGaps(
|
|
dest.fairValueGaps,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// Bullish FairValueGaps ...
|
|
FilterBullishFairValueGaps(
|
|
dest.bullishFairValueGaps,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
// Bearish FairValueGaps ...
|
|
FilterBearishFairValueGaps(
|
|
dest.bearishFairValueGaps,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
|
|
//
|
|
}
|
|
|
|
//
|
|
};
|
|
|
|
//
|
|
int ExtractOBFVGs(
|
|
XOBFVG &dest[],
|
|
XPOIState &obState,
|
|
XPOIState &fvgState,
|
|
//
|
|
ENUM_X_OBFVG_FVG_FILTERS filterFVGs = X_OBFVG_FVG_FILTER_INSIDE_OR,
|
|
ENUM_X_OBFVG_FVG_SELECTION selectFVG = X_OBFVG_FVG_SELECT_HIGHEST_LOWEST,
|
|
//
|
|
ENUM_TIMEFRAMES forPeriod = NULL,
|
|
//
|
|
// Start ...
|
|
ENUM_XZONE_STATE startState = XZONE_STATE_PASSED,
|
|
bool forceStartedBodyOut = false,
|
|
//
|
|
// Activation ...
|
|
ENUM_XZONE_STATE activeState = XZONE_STATE_FAILED,
|
|
bool forceActivatedBodyIn = false,
|
|
//
|
|
// Breaktion ...
|
|
ENUM_XZONE_STATE breakState = XZONE_STATE_FAILED,
|
|
bool forceBreakedBodyOut = false,
|
|
//
|
|
// Works ...
|
|
ENUM_XZONE_STATE workState = XZONE_STATE_IGNORED,
|
|
bool forceWorkedBodyOut = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool has = false;
|
|
|
|
//
|
|
Clean(dest);
|
|
|
|
//
|
|
has = obState.IsValid() &&
|
|
fvgState.IsValid() &&
|
|
obState.HasChild() &&
|
|
fvgState.HasChild() &&
|
|
selectFVG != X_OBFVG_FVG_SELECT_NONE &&
|
|
filterFVGs != X_OBFVG_FVG_FILTER_NONE;
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XCOrderBlock *obs[];
|
|
int obsCount = obState.FilterOrderBlocks(
|
|
obs,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
has = IsValidSize(obsCount);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
XCFVG *fvgs[];
|
|
int fvgsCount = fvgState.FilterFairValueGaps(
|
|
fvgs,
|
|
forPeriod,
|
|
startState,
|
|
forceStartedBodyOut,
|
|
activeState,
|
|
forceActivatedBodyIn,
|
|
breakState,
|
|
forceBreakedBodyOut,
|
|
workState,
|
|
forceWorkedBodyOut //
|
|
);
|
|
has = IsValidSize(fvgsCount);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < obsCount; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iOB = obs[i];
|
|
XCFVG *iFVG = NULL;
|
|
|
|
//
|
|
ENUM_X_DIRECTION iOBDir = iOB.GetDirection();
|
|
bool isIOBBullish = IsBullish(iOBDir);
|
|
|
|
//
|
|
XCFVG *iFVGs[];
|
|
for (int j = 0; j < fvgsCount; j++)
|
|
{
|
|
//
|
|
XCFVG *jFVG = fvgs[j];
|
|
ENUM_X_DIRECTION jFVGDir = jFVG.GetDirection();
|
|
|
|
//
|
|
bool isSameDir = iOBDir == jFVGDir;
|
|
bool isFromPassed = jFVG.From() >= iOB.From();
|
|
bool isInsideOr = IsInsideOrDiff(
|
|
jFVG,
|
|
iOB //
|
|
);
|
|
bool isAbove = IsAboveDiff(
|
|
jFVG,
|
|
iOB,
|
|
true //
|
|
);
|
|
bool isBelow = IsBelowDiff(
|
|
jFVG,
|
|
iOB,
|
|
true //
|
|
);
|
|
|
|
//
|
|
bool isFilterPassed =
|
|
filterFVGs == X_OBFVG_FVG_FILTER_ABOVE_BELOW
|
|
? isIOBBullish
|
|
? isAbove
|
|
: isBelow
|
|
: filterFVGs == X_OBFVG_FVG_FILTER_INSIDE_OR
|
|
? isInsideOr
|
|
: false;
|
|
|
|
//
|
|
has =
|
|
isSameDir &&
|
|
isFromPassed &&
|
|
isFilterPassed;
|
|
if (has)
|
|
{
|
|
//
|
|
Add(
|
|
jFVG,
|
|
iFVGs //
|
|
);
|
|
}
|
|
}
|
|
has = HasChild(iFVGs);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
idx = selectFVG == X_OBFVG_FVG_SELECT_OLDEST
|
|
? GetOldest(iFVGs)
|
|
: selectFVG == X_OBFVG_FVG_SELECT_YOUNGEST
|
|
? GetYoungest(iFVGs)
|
|
: selectFVG == X_OBFVG_FVG_SELECT_HIGHEST_LOWEST
|
|
? isIOBBullish
|
|
? GetHighest(iFVGs)
|
|
: GetLowest(iFVGs)
|
|
: selectFVG == X_OBFVG_FVG_SELECT_LOWEST_HIGHEST
|
|
? isIOBBullish
|
|
? GetLowest(iFVGs)
|
|
: GetHighest(iFVGs)
|
|
: selectFVG == X_OBFVG_FVG_SELECT_LOWEST
|
|
? GetLowest(iFVGs)
|
|
: selectFVG == X_OBFVG_FVG_SELECT_HIGHEST
|
|
? GetHighest(iFVGs)
|
|
: -1;
|
|
|
|
//
|
|
has = IsValidIndex(idx);
|
|
if (!has)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
iFVG = iFVGs[idx];
|
|
Clean(iFVGs);
|
|
|
|
//
|
|
XOBFVG iOBFVG;
|
|
iOBFVG.ob = iOB;
|
|
iOBFVG.fvg = iFVG;
|
|
|
|
//
|
|
has = iOBFVG.IsValid();
|
|
if (!has)
|
|
{
|
|
//
|
|
iOBFVG.Clean();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
AddRef(
|
|
iOBFVG,
|
|
dest //
|
|
);
|
|
|
|
//
|
|
iOBFVG.Clean();
|
|
}
|
|
|
|
//
|
|
result = ArraySize(dest);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
void SpecifiedUpdateTo(
|
|
XOBFVG &items[],
|
|
datetime value = NULL //
|
|
)
|
|
{
|
|
//
|
|
value = NormalizeTime(value);
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
bool has = HasChild(items);
|
|
if (!has)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
items[i].UpdateTo(value);
|
|
}
|
|
}
|
|
|
|
//
|