Files
MQL5Data/Libraries/x-saherelm.x-poi.extensions.lib.mq5
T
2026-08-14 07:49:18 +03:30

6839 lines
125 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-ohcl.lib.mq5"
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
//
// Extensions ...
//+------------------------------------------------------------------+
//| Oldest Detection |
//+------------------------------------------------------------------+
/**
* Get Oldest Index of Specified Collection ...
*
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetOldest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
!selected.IsValid()
? true
: selected.from > source[i].from;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Oldest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param forDir: ENUM_X_DIRECTION, Specified Direction ...
*
* @return ( int )
*/
int GetOldestByDir(
XBoxZone &source[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
(!HasDirection(forDir)
? true
: forDir == source[i].dir) &&
(!selected.IsValid()
? true
: selected.from > source[i].from);
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Oldest Index of Specified Collection ...
*
* @param bar: XOHCL, Specified Bar ...
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetOldestByBar(
XOHCL &bar,
XBoxZone &source[] //
)
{
//
int result = -1;
//
if (!bar.IsValid())
{
return result;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, source[i]);
if (!isBoxValidForBar)
{
continue;
}
//
bool canSet =
!selected.IsValid()
? true
: selected.from > source[i].from;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Oldest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ...
*
* @return ( int )
*/
int GetOldest(
XPivot &source[],
ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE //
)
{
//
int result = -1;
//
// Validate ...
if (!HasChild(source))
{
return result;
}
//
bool has = false;
XPivot iPoint;
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
// Passed Type ...
has = !IsXValid(type)
? true
: type == source[i].type;
//
// Check Can Assign ...
has =
has &&
(!iPoint.IsValid() ||
(iPoint.IsValid() &&
source[i].GetAge() > iPoint.GetAge()));
if (has)
{
//
result = i;
iPoint = source[i];
}
}
//
// Validate Result ...
has =
iPoint.IsValid() &&
IsValidIndex(result);
if (!has)
{
//
result = -1;
iPoint.Clean();
return result;
}
//
iPoint.Clean();
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Youngest Detection |
//+------------------------------------------------------------------+
/**
* Get Youngest Index of Specified Collection ...
*
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetYoungest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
!selected.IsValid()
? true
: selected.from < source[i].from;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Youngest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param forDir: ENUM_X_DIRECTION, Specified Direction ...
*
* @return ( int )
*/
int GetYoungestByDir(
XBoxZone &source[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
(!HasDirection(forDir)
? true
: forDir == source[i].dir) &&
(!selected.IsValid()
? true
: selected.from < source[i].from);
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Youngest Index of Specified Collection ...
*
* @param bar: XOHCL, Specified Bar ...
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetYoungestByBar(
XOHCL &bar,
XBoxZone &source[] //
)
{
//
int result = -1;
//
if (!bar.IsValid())
{
return result;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, source[i]);
if (!isBoxValidForBar)
{
continue;
}
//
bool canSet =
!selected.IsValid()
? true
: selected.from < source[i].from;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Youngest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ...
*
* @return ( int )
*/
int GetYoungest(
XPivot &source[],
ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE //
)
{
//
int result = -1;
//
// Validate ...
if (!HasChild(source))
{
return result;
}
//
bool has = false;
XPivot iPoint;
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
// Passed Type ...
has = !IsXValid(type)
? true
: type == source[i].type;
//
// Check Can Assign ...
has =
has &&
(!iPoint.IsValid() ||
(iPoint.IsValid() &&
source[i].GetAge() < iPoint.GetAge()));
if (has)
{
//
result = i;
iPoint = source[i];
}
}
//
// Validate Result ...
has =
iPoint.IsValid() &&
IsValidIndex(result);
if (!has)
{
//
result = -1;
iPoint.Clean();
return result;
}
//
iPoint.Clean();
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Highest Detection |
//+------------------------------------------------------------------+
/**
* Get Highest Index of Specified Collection ...
*
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetHighest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
!selected.IsValid()
? true
: selected.upper < source[i].upper;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Highest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param forDir: ENUM_X_DIRECTION, Specified Direction ...
*
* @return ( int )
*/
int GetHighestByDir(
XBoxZone &source[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
(!HasDirection(forDir)
? true
: forDir == source[i].dir) &&
(!selected.IsValid()
? true
: selected.upper < source[i].upper);
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* Get Highest Index of Specified Collection ...
*
* @param bar: XOHCL, Specified Bar ...
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetHighestByBar(
XOHCL &bar,
XBoxZone &source[] //
)
{
//
int result = -1;
//
if (!bar.IsValid())
{
return result;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox);
if (!isBoxValidForBar)
{
//
iBox.Clean();
//
continue;
}
//
bool canSet =
!selected.IsValid()
? true
: selected.upper < iBox.upper;
if (canSet)
{
//
result = i;
selected = iBox;
}
//
iBox.Clean();
}
//
selected.Clean();
//
return result;
}
/**
* Get Highest Bar Price Index of Specified Collection ...
*
* @param source: reference collection, Provides Data Source ...
*
* @return ( int )
*/
int GetHighestBarPrice(
XOHCL &source[],
ENUM_X_PRICE priceType //
)
{
//
int result = -1;
//
// Validate ...
bool has = HasChild(source) &&
IsXValid(priceType);
if (!has)
{
return result;
}
//
double price = EMPTY_VALUE;
double selected = EMPTY_VALUE;
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
price = source[i].GetPrice(priceType);
has = !NotEmptyZero(selected)
? true
: price > selected;
if (has)
{
//
result = i;
selected = price;
}
}
//
return result;
}
/**
* Get Highest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ...
*
* @return ( int )
*/
int GetHighest(
XPivot &source[],
ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE //
)
{
//
int result = -1;
//
// Validate ...
if (!HasChild(source))
{
return result;
}
//
bool has = false;
XPivot iPoint;
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
// Passed Type ...
has = !IsXValid(type)
? true
: type == source[i].type;
//
// Check Can Assign ...
has =
has &&
(!iPoint.IsValid() ||
(iPoint.IsValid() &&
source[i].value > iPoint.value));
if (has)
{
//
result = i;
iPoint = source[i];
}
}
//
// Validate Result ...
has =
iPoint.IsValid() &&
IsValidIndex(result);
if (!has)
{
//
result = -1;
iPoint.Clean();
return result;
}
//
iPoint.Clean();
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Loest Detection |
//+------------------------------------------------------------------+
/**
* Get Lowest Index of Specified Collection ...
*
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetLowest(
XBoxZone &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool canSet =
!selected.IsValid()
? true
: selected.lower > iBox.lower;
if (canSet)
{
//
result = i;
selected = iBox;
}
//
iBox.Clean();
}
//
selected.Clean();
//
return result;
}
/**
* Get Lowest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param forDir: ENUM_X_DIRECTION, Specified Direction ...
*
* @return ( int )
*/
int GetLowestByDir(
XBoxZone &source[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool canSet =
(!HasDirection(forDir)
? true
: forDir == source[i].dir) &&
(!selected.IsValid()
? true
: selected.lower > iBox.lower);
if (canSet)
{
//
result = i;
selected = iBox;
}
//
iBox.Clean();
}
//
selected.Clean();
//
return result;
}
/**
* Get Lowest Index of Specified Collection ...
*
* @param bar: XOHCL, Specified Bar ...
* @param source: Specified Collection ...
*
* @return ( int )
*/
int GetLowestByBar(
XOHCL &bar,
XBoxZone &source[] //
)
{
//
int result = -1;
//
if (!bar.IsValid())
{
return result;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XBoxZone selected;
for (int i = 0; i < count; i++)
{
//
XBoxZone iBox = source[i];
//
bool isBoxValidForBar = IsBoxPlaceValidForBar(bar, iBox);
if (!isBoxValidForBar)
{
//
iBox.Clean();
//
continue;
}
//
bool canSet =
!selected.IsValid()
? true
: selected.lower > iBox.lower;
if (canSet)
{
//
result = i;
selected = iBox;
}
//
iBox.Clean();
}
//
selected.Clean();
//
return result;
}
/**
* Get Lowest Bar Price Index of Specified Collection ...
*
* @param source: reference collection, Provides Data Source ...
*
* @return ( int )
*/
int GetLowestBarPrice(
XOHCL &source[],
ENUM_X_PRICE priceType //
)
{
//
int result = -1;
//
// Validate ...
bool has = HasChild(source) &&
IsXValid(priceType);
if (!has)
{
return result;
}
//
double price = EMPTY_VALUE;
double selected = EMPTY_VALUE;
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
price = source[i].GetPrice(priceType);
has = !NotEmptyZero(selected)
? true
: price < selected;
if (has)
{
//
result = i;
selected = price;
}
}
//
return result;
}
/**
* Get Lowest Index of Specified Collection ...
*
* @param source: Specified Collection ...
* @param type: ENUM_X_PIVOT_TYPE, Specified Points Type ...
*
* @return ( int )
*/
int GetLowest(
XPivot &items[],
ENUM_X_PIVOT_TYPE type = X_PIVOT_TYPE_NONE //
)
{
//
int result = -1;
//
// Validate ...
if (!HasChild(items))
{
return result;
}
//
bool has = false;
XPivot iPoint;
int count = ArraySize(items);
for (int i = 0; i < count; i++)
{
//
// Passed Type ...
has = !IsXValid(type)
? true
: type == items[i].type;
//
// Check Can Assign ...
has =
has &&
(!iPoint.IsValid() ||
(iPoint.IsValid() &&
items[i].value < iPoint.value));
if (has)
{
//
result = i;
iPoint = items[i];
}
}
//
// Validate Result ...
has =
iPoint.IsValid() &&
IsValidIndex(result);
if (!has)
{
//
result = -1;
iPoint.Clean();
return result;
}
//
iPoint.Clean();
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Box |
//+------------------------------------------------------------------+
/**
* Extract all items which appears Before Specified Time ...
*
* @param _time: Specified Time ...
* @param dest: refrence collection to hold result ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetBeforeItems(
datetime _time,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
int count = ArraySize(source);
bool has = HasChild(source) &&
IsSpecifiedValid(_time);
if (!has)
{
return result;
}
//
// Loop through Items ...
for (int i = 0; i < count; i++)
{
//
has = source[i].from < _time;
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all items which appears After Specified Time ...
*
* @param _time: Specified Time ...
* @param dest: refrence collection to hold result ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetAfterItems(
datetime _time,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
int count = ArraySize(source);
bool has = HasChild(source) &&
IsSpecifiedValid(_time);
if (!has)
{
return result;
}
//
// Loop through Items ...
for (int i = 0; i < count; i++)
{
//
has = source[i].from > _time;
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all items which appears Above Specified Value ...
*
* @param _value: Specified Value ...
* @param dest: refrence collection to hold result ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetAboveItems(
double _value,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
int count = ArraySize(source);
bool has = HasChild(source) &&
NotEmptyZero(_value);
if (!has)
{
return result;
}
//
// Loop through Items ...
for (int i = 0; i < count; i++)
{
//
has = source[i].lower > _value;
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all items which appears Below Specified Value ...
*
* @param _value: Specified Value ...
* @param dest: refrence collection to hold result ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetBelowItems(
double _value,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
int count = ArraySize(source);
bool has = HasChild(source) &&
NotEmptyZero(_value);
if (!has)
{
return result;
}
//
// Loop through Items ...
for (int i = 0; i < count; i++)
{
//
has = source[i].upper < _value;
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Get Oldest Item Index of all items which appears Before Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetOldestBefore(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBeforeItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetOldest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Oldest Item Index of all items which appears After Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetOldestAfter(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAfterItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetOldest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Oldest Item Index of all items which appears Above Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetOldestAbove(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAboveItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetOldest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Oldest Item Index of all items which appears Below Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetOldestBelow(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBelowItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetOldest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Youngest Item Index of all items which appears Before Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetYoungestBefore(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBeforeItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetYoungest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Youngest Item Index of all items which appears After Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetYoungestAfter(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAfterItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetYoungest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Youngest Item Index of all items which appears Above Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetYoungestAbove(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAboveItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetYoungest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Youngest Item Index of all items which appears Below Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetYoungestBelow(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBelowItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetYoungest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Highest Item Index of all items which appears Before Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetHighestBefore(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBeforeItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetHighest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Highest Item Index of all items which appears After Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetHighestAfter(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAfterItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetHighest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Highest Item Index of all items which appears Above Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetHighestAbove(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAboveItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetHighest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Highest Item Index of all items which appears Below Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetHighestBelow(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBelowItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetHighest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Lowest Item Index of all items which appears Before Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetLowestBefore(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBeforeItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetLowest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Lowest Item Index of all items which appears After Specified Value ...
*
* @param _time: Specified Time ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetLowestAfter(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAfterItems(
_time,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetLowest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Lowest Item Index of all items which appears Above Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetLowestAbove(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetAboveItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetLowest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Get Lowest Item Index of all items which appears Below Specified Value ...
*
* @param _value: Specified Value ...
* @param source: refrence collection to provides data source ...
*
* @return ( int )
*/
int GetLowestBelow(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
XBoxZone tmps[];
int tmpsCount = GetBelowItems(
_value,
tmps, // Dest ...
source // Source ...
);
bool has = IsValidSize(tmpsCount);
int idx = GetLowest(tmps);
has =
has &&
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
SpecifiedClean(tmps);
//
return result;
}
/**
* Validate an Item Strength ...
*
* @param item: Specified Item for Validating ...
* @param minAllowedStrength: int, Minimum required Strength in Point ...
*
* @return ( bool )
*/
bool ValidateStrength(
XBoxZone &item,
int minAllowedStrength = 0 //
)
{
//
bool result = false;
//
// Normalize ...
minAllowedStrength = NormalizeInt(minAllowedStrength, 0);
//
// Validate ...
result = item.IsValid();
if (!result)
{
return result;
}
//
// If doent provide Specified Strength Validate Zone ...
result = minAllowedStrength <= 0;
if (result)
{
return result;
}
//
double points = GetPoints(item.symbol);
double requiredStrength = minAllowedStrength * points;
double itemStrength = item.upper - item.lower;
//
result =
itemStrength > 0 &&
requiredStrength > 0 &&
itemStrength > requiredStrength;
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Sort |
//+------------------------------------------------------------------+
/**
* Allowed Sort Param ...
**/
enum ENUM_X_SORT_BY
{
X_SORT_BY_NONE = 0, // None
X_SORT_BY_DATE = 1, // by Date
X_SORT_BY_VALUE = 2, // by Date
};
/**
* Check Specified Sort By Validation ...
*
* @param value: ENUM_X_SORT_BY, value to Validate ...
*
* @return ( bool )
*/
bool IsXValid(ENUM_X_SORT_BY value)
{
return value != X_SORT_BY_NONE;
}
/**
* Select Specified Index of a Collection by Sort Params ...
*
* @param source: Collection for Search ...
* @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ...
* @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ...
*
* @return ( int )
*/
template <typename T>
int SelectItemForSorting(
T &source[],
ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE,
ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH //
)
{
//
int result = -1;
//
// Validate ...
if (!HasChild(source) ||
!IsXValid(sortBy) ||
!HasDirection(sortDir))
{
return result;
}
//
// Sort By Date ...
if (sortBy == X_SORT_BY_DATE)
{
//
// Select Based on Sorting Direction ...
//
// form Oldest to Youngest ...
if (sortDir == X_DIRECTION_BULLISH)
{
result = GetOldest(source);
}
//
// form Youngest to Oldest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetYoungest(source);
}
//
// Not Valid ...
else
{
result = -1;
}
}
//
// Sort By Value ...
else if (sortBy == X_SORT_BY_VALUE)
{
//
// form Lowst to Highest ...
if (sortDir == X_DIRECTION_BULLISH)
{
result = GetLowest(source);
}
//
// form Highest to Lowest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetHighest(source);
}
//
// Not Valid ...
else
{
result = -1;
}
}
//
// Not Valid ...
else
{
result = -1;
}
//
return result;
}
/**
* Select Specified Index of a Collection by Sort Params ...
*
* @param source: Collection for Search ...
* @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ...
* @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ...
*
* @return ( int )
*/
int SelectBarForSorting(
XOHCL &source[],
ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE,
ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH,
ENUM_X_PRICE priceType = X_PRICE_NONE //
)
{
//
int result = -1;
//
// Validate ...
if (!HasChild(source) ||
!IsXValid(sortBy) ||
!HasDirection(sortDir))
{
return result;
}
//
// Sort By Date ...
if (sortBy == X_SORT_BY_DATE)
{
//
// Select Based on Sorting Direction ...
//
// form Oldest to Youngest ...
if (sortDir == X_DIRECTION_BULLISH)
{
result = GetOldest(source);
}
//
// form Youngest to Oldest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetYoungest(source);
}
//
// Not Valid ...
else
{
result = -1;
}
}
//
// Sort By Value ...
else if (sortBy == X_SORT_BY_VALUE)
{
//
// form Lowst to Highest ...
if (sortDir == X_DIRECTION_BULLISH)
{
result = GetLowest(source, priceType);
}
//
// form Highest to Lowest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetHighest(source, priceType);
}
//
// Not Valid ...
else
{
result = -1;
}
}
//
// Not Valid ...
else
{
result = -1;
}
//
return result;
}
/**
* Apply Sort on Specified Collection ...
*
* @param source: Collection Reference to Sort ...
* @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ...
* @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ...
* @param maxAllowed: int, Max Allowed Collection Size ...
*/
template <typename T>
void Sort(
T &source[],
ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE,
ENUM_X_DIRECTION sortDir = X_DIRECTION_BEARISH,
int maxAllowed = 0 //
)
{
//
int idx = -1;
bool has = false;
//
// Validate ...
has =
IsXValid(sortBy) &&
HasChild(source) &&
HasDirection(sortDir);
if (!has)
{
return;
}
//
// Copy source for Manipulating ...
T tmps[];
Copy(
source,
tmps //
);
//
// Clean Source Collection for Adding Sorted Items ...
Clean(source);
//
// Loop Through Temp Collection Has Child ...
while (HasChild(tmps))
{
//
// Select Based on Sorting Parameter ...
idx = SelectItemForSorting(
tmps,
sortBy,
sortDir //
);
//
// Validate Detected Index ...
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
// Add Detected Indexed Item to Source ...
AddRef(
tmps[idx],
source //
);
//
// Remove Item From Temp Collection ...
ArrayRemove(
tmps,
idx,
1 //
);
}
//
// Cleanup Collection if Max Items Reached ...
if (maxAllowed > 0)
{
//
CleanupArray(
source,
maxAllowed //
);
}
//
// Cleanup Resources ...
SpecifiedClean(tmps);
}
/**
* Apply Sort on Specified Collection ...
*
* @param source: Collection Reference to Sort ...
* @param sortBy: ENUM_X_SORT_BY, Specified Sort Param ...
* @param sortDir: ENUM_X_DIRECTION, Specified Sort Direction ...
* @param priceType: ENUM_X_PRICE, Price Selecting Method ...
* @param maxAllowed: int, Max Allowed Collection Size ...
*/
void SortBar(
XOHCL &source[],
ENUM_X_SORT_BY sortBy = X_SORT_BY_DATE,
ENUM_X_DIRECTION sortDir = X_DIRECTION_BULLISH,
ENUM_X_PRICE priceType = X_PRICE_NONE,
int maxAllowed = 0 //
)
{
//
int idx = -1;
bool has = false;
//
// Validate ...
has =
IsXValid(sortBy) &&
HasChild(source) &&
HasDirection(sortDir);
if (!has)
{
return;
}
//
// Copy source for Manipulating ...
XOHCL tmps[];
Copy(
source,
tmps //
);
//
// Clean Source Collection for Adding Sorted Items ...
Clean(source);
//
// Loop Through Temp Collection Has Child ...
while (HasChild(tmps))
{
//
// Select Based on Sorting Parameter ...
idx = SelectBarForSorting(
tmps,
sortBy,
sortDir,
priceType //
);
//
// Validate Detected Index ...
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
// Add Detected Indexed Item to Source ...
AddRef(
tmps[idx],
source //
);
//
// Remove Item From Temp Collection ...
ArrayRemove(
tmps,
idx,
1 //
);
}
//
// Cleanup Collection if Max Items Reached ...
if (maxAllowed > 0)
{
//
CleanupArray(
source,
maxAllowed //
);
}
//
// Cleanup Resources ...
SpecifiedClean(tmps);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Extraction |
//+------------------------------------------------------------------+
/**
* Extract Specific Types of Pivots From a Collection ...
*
* @param dest: reference Collection to Hold result ...
* @param source: Collection to Find Type Specific items ...
* @param _type: Specified item Type ...
*
* @return ( int )
*/
int ExtractPivots(
XPivot &dest[],
XPivot &source[],
ENUM_X_PIVOT_TYPE _type //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
int count = ArraySize(source);
bool has =
IsXValid(_type) &&
IsValidSize(count);
if (!has)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
// Check Type Passing ...
has = _type == source[i].type;
if (!has)
{
continue;
}
//
AddIfNotExists(
source[i],
dest //
);
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract Same Time Pivots ...
*
* @param item: XPivot, reference to Specified Pivot for Detect Same Times ...
* @param dest: XPivot, collection reference to holds Same Times Pivots ...
* @param source: XPivot, collection reference to Provide Data Source ...
*
* @return ( int )
*/
int ExtractSameTimePivots(
XPivot &item,
XPivot &dest[],
XPivot &source[] //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = HasChild(source) &&
item.IsValid();
if (!has)
{
return result;
}
//
// Do ...
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = item.time == source[i].time;
if (has)
{
AddIfNotExists(source[i], dest);
}
}
//
// Add item as a Child ...
AddIfNotExists(item, dest);
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract Pivots Data for Linear Regression Calculations ...
*
* @param xData: refrence Collection to Holds X-Axis Data ...
* @param yData: refrence Collection to Holds Y-Axis Data ...
* @param source: pivots Collection for Extraction ...
*
* @return ( int )
*/
int ExtractPivotsData(
double &xData[],
double &yData[],
XPivot &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(xData);
SpecifiedClean(yData);
//
// Validate ...
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iX = EMPTY_VALUE;
double iY = EMPTY_VALUE;
for (int i = 0; i < count; i++)
{
//
// Get Pivot Bar ...
has = source[i].GetBar(iBar);
if (!has)
{
continue;
}
//
iX = iBar.Index();
iY = source[i].value;
//
Add(
iX,
xData //
);
//
Add(
iY,
yData //
);
//
iBar.Clean();
}
//
iBar.Clean();
//
result = MathMin(ArraySize(xData), ArraySize(yData));
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Support and Resistance |
//+------------------------------------------------------------------+
/**
* Extract Support Levels of Pivots Collection ...
*
* @param _minor: refrence to Holds Minor Level ...
* @param _major: refrence to Holds Major Level ...
* @param source: Collection of Pivots ...
*
* @return ( bool )
*/
bool ExtractSupport(
double &_minor,
double &_major,
XPivot &source[] //
)
{
//
bool result = false;
//
// Prepare ...
_minor = EMPTY_VALUE;
_major = EMPTY_VALUE;
//
// Validate ...
int count = ArraySize(source);
result = IsValidSize(count);
if (!result)
{
return result;
}
//
bool has = false;
double tmp = EMPTY_VALUE;
double iValue = EMPTY_VALUE;
for (int i = 0; i < count; i++)
{
//
// Check Type ...
has = source[i].IsVale();
if (!has)
{
continue;
}
//
// Reading Value ...
iValue = source[i].value;
//
// Check Can Change Major ...
has = !NotEmpty(_major) ||
_major > iValue;
if (has)
{
//
tmp = _major;
_major = iValue;
}
//
// Check Can Change Minor ...
else
{
//
// Change Minor ...
has = !NotEmpty(tmp) ||
tmp > iValue;
if (has)
{
tmp = iValue;
}
}
}
//
// Last Update of Minore Minor ...
has = NotEmpty(tmp);
if (has)
{
_minor = tmp;
}
//
result = NotEmpty(_major) ||
NotEmpty(_minor);
//
return result;
}
/**
* Extract Resistance Levels of Pivots Collection ...
*
* @param _minor: refrence to Holds Minor Level ...
* @param _major: refrence to Holds Major Level ...
* @param source: Collection of Pivots ...
*
* @return ( bool )
*/
bool ExtractResistances(
double &_minor,
double &_major,
XPivot &source[] //
)
{
//
bool result = false;
//
// Prepare ...
_minor = EMPTY_VALUE;
_major = EMPTY_VALUE;
//
// Validate ...
int count = ArraySize(source);
result = IsValidSize(count);
if (!result)
{
return result;
}
//
bool has = false;
double tmp = EMPTY_VALUE;
double iValue = EMPTY_VALUE;
for (int i = 0; i < count; i++)
{
//
// Check Type ...
has = source[i].IsPeak();
if (!has)
{
continue;
}
//
// Reading Value ...
iValue = source[i].value;
//
// Check Can Change Major ...
has = !NotEmpty(_major) ||
_major < iValue;
if (has)
{
//
tmp = _major;
_major = iValue;
}
//
// Check Can Change Minor ...
else
{
//
// Change Minor ...
has = !NotEmpty(tmp) ||
tmp < iValue;
if (has)
{
tmp = iValue;
}
}
}
//
// Last Update of Minore Minor ...
has = NotEmpty(tmp);
if (has)
{
_minor = tmp;
}
//
result = NotEmpty(_major) ||
NotEmpty(_minor);
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Find Index |
//+------------------------------------------------------------------+
/**
* Find Specified Item index in a Collection ...
*
* @param index: int, reference to Hold Index if Exists ...
* @param item: Specified item to Detect ...
* @param source: Collection to Search for item ...
*
* @return ( bool )
*/
bool FindIndex(
int &index,
XBoxZone &item,
XBoxZone &source[] //
)
{
//
bool result = false;
//
index = -1;
//
int count = ArraySize(source);
result = item.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
bool isSame = item.IsSameAs(source[i]);
if (isSame)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Find Specified Item index in a Collection ...
*
* @param index: int, reference to Hold Index if Exists ...
* @param item: Specified item to Detect ...
* @param source: Collection to Search for item ...
*
* @return ( bool )
*/
bool FindIndex(
int &index,
XPivot &item,
XPivot &source[] //
)
{
//
bool result = false;
//
index = -1;
//
int count = ArraySize(source);
result = item.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
bool isSame = item.IsSameAs(source[i]);
if (isSame)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Find Specified Item index in a Collection ...
*
* @param index: int, reference to Hold Index if Exists ...
* @param item: Specified item to Detect ...
* @param source: Collection to Search for item ...
*
* @return ( bool )
*/
bool FindIndex(
int &index,
XDirectionShift &item,
XDirectionShift &source[] //
)
{
//
bool result = false;
//
index = -1;
//
int count = ArraySize(source);
result = item.IsValid() &&
IsValidSize(count);
if (!result)
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
bool isSame = item.IsSameAs(source[i]);
if (isSame)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Remove |
//+------------------------------------------------------------------+
/**
* Remove Specified Item from a Collection ...
*
* @param item: Specified Item ...
* @param source: Specified Collection for Remove item from it ...
*
* @return ( bool )
*/
bool Remove(
XPivot &item,
XPivot &source[] //
)
{
//
bool result = false;
//
result =
item.IsValid() &&
HasChild(source);
if (!result)
{
return result;
}
//
int idx = -1;
result = FindIndex(
idx,
item,
source //
);
if (!result)
{
return result;
}
//
result = ArrayRemove(
source,
idx,
1 //
);
//
return result;
}
/**
* Remove Specified Item from a Collection ...
*
* @param item: Specified Item ...
* @param source: Specified Collection for Remove item from it ...
*
* @return ( bool )
*/
bool Remove(
XBoxZone &item,
XBoxZone &source[] //
)
{
//
bool result = false;
//
result =
item.IsValid() &&
HasChild(source);
if (!result)
{
return result;
}
//
int idx = -1;
result = FindIndex(
idx,
item,
source //
);
if (!result)
{
return result;
}
//
result = ArrayRemove(
source,
idx,
1 //
);
//
return result;
}
/**
* Remove Specified Item from a Collection ...
*
* @param item: Specified Item ...
* @param source: Specified Collection for Remove item from it ...
*
* @return ( bool )
*/
bool Remove(
XDirectionShift &item,
XDirectionShift &source[] //
)
{
//
bool result = false;
//
result =
item.IsValid() &&
HasChild(source);
if (!result)
{
return result;
}
//
int idx = -1;
result = FindIndex(
idx,
item,
source //
);
if (!result)
{
return result;
}
//
result = ArrayRemove(
source,
idx,
1 //
);
//
return result;
}
/**
* Remove Specified items from a Collection ...
*
* @param items: Specified Items to Remove ...
* @param sources: Sepcified Collection for Removing items from it ...
*
* @return ( int )
*/
int Removes(
XBoxZone &items[],
XBoxZone &sources[] //
)
{
//
int result = 0;
//
bool has = HasChild(items) &&
HasChild(sources);
if (!has)
{
return result;
}
//
int idx = -1;
has = false;
int count = ArraySize(items);
for (int i = 0; i < count; i++)
{
//
// Detect Item Index in Collection ...
has = FindIndex(
idx,
items[i],
sources //
);
if (has)
{
//
// Remove Detected Index from Collection ...
has = ArrayRemove(
sources,
idx,
1 //
);
//
if (has)
{
//
// Count Removed Items ...
result++;
}
}
}
//
return result;
}
/**
* Remove Specified items from a Collection ...
*
* @param items: Specified Items to Remove ...
* @param sources: Sepcified Collection for Removing items from it ...
*
* @return ( int )
*/
int Removes(
XPivot &items[],
XPivot &sources[] //
)
{
//
int result = 0;
//
bool has = HasChild(items) &&
HasChild(sources);
if (!has)
{
return result;
}
//
int idx = -1;
has = false;
int count = ArraySize(items);
for (int i = 0; i < count; i++)
{
//
// Detect Item Index in Collection ...
has = FindIndex(
idx,
items[i],
sources //
);
if (has)
{
//
// Remove Detected Index from Collection ...
has = ArrayRemove(
sources,
idx,
1 //
);
//
if (has)
{
//
// Count Removed Items ...
result++;
}
}
}
//
return result;
}
/**
* Remove Specified items from a Collection ...
*
* @param items: Specified Items to Remove ...
* @param sources: Sepcified Collection for Removing items from it ...
*
* @return ( int )
*/
int Removes(
XDirectionShift &items[],
XDirectionShift &sources[] //
)
{
//
int result = 0;
//
bool has = HasChild(items) &&
HasChild(sources);
if (!has)
{
return result;
}
//
int idx = -1;
has = false;
int count = ArraySize(items);
for (int i = 0; i < count; i++)
{
//
// Detect Item Index in Collection ...
has = FindIndex(
idx,
items[i],
sources //
);
if (has)
{
//
// Remove Detected Index from Collection ...
has = ArrayRemove(
sources,
idx,
1 //
);
//
if (has)
{
//
// Count Removed Items ...
result++;
}
}
}
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Add If Not Exists |
//+------------------------------------------------------------------+
/**
* Add Specified Item to Specified Collection, if not Exists ...
*
* @param item: Item to Add ...
* @param sources: Collection to Add item ...
* @param maxAllowed: int, Max Allowed Collection Size ...
*
* @return ( bool )
*/
bool AddIfNotExists(
XBoxZone &item,
XBoxZone &sources[],
int maxAllowed = 0 //
)
{
//
bool result = false;
//
// Validate Args ...
result = item.IsValid();
if (!result)
{
return result;
}
//
// Check Item Exists or not ...
int idx = -1;
bool isExists = FindIndex(
idx,
item,
sources //
);
result = !isExists;
if (!result)
{
return result;
}
//
AddRef(
item,
sources //
);
//
// Handle Cleanup Collection
// if Max Reached ...
if (result &&
maxAllowed > 0)
{
//
CleanupArray(
sources,
maxAllowed //
);
}
//
return result;
}
/**
* Add Specified Item to Specified Collection, if not Exists ...
*
* @param item: Item to Add ...
* @param sources: Collection to Add item ...
* @param maxAllowed: int, Max Allowed Collection Size ...
*
* @return ( bool )
*/
bool AddIfNotExists(
XPivot &item,
XPivot &sources[],
int maxAllowed = 0 //
)
{
//
bool result = false;
//
// Validate Args ...
result = item.IsValid();
if (!result)
{
return result;
}
//
// Check Item Exists or not ...
int idx = -1;
bool isExists = FindIndex(
idx,
item,
sources //
);
result = !isExists;
if (!result)
{
return result;
}
//
AddRef(
item,
sources //
);
//
// Handle Cleanup Collection
// if Max Reached ...
if (result &&
maxAllowed > 0)
{
//
CleanupArray(
sources,
maxAllowed //
);
}
//
return result;
}
/**
* Add Specified Item to Specified Collection, if not Exists ...
*
* @param item: Item to Add ...
* @param sources: Collection to Add item ...
* @param maxAllowed: int, Max Allowed Collection Size ...
*
* @return ( bool )
*/
bool AddIfNotExists(
XDirectionShift &item,
XDirectionShift &sources[],
int maxAllowed = 0 //
)
{
//
bool result = false;
//
// Validate Args ...
result = item.IsValid();
if (!result)
{
return result;
}
//
// Check Item Exists or not ...
int idx = -1;
bool isExists = FindIndex(
idx,
item,
sources //
);
result = !isExists;
if (!result)
{
return result;
}
//
AddRef(
item,
sources //
);
//
// Handle Cleanup Collection
// if Max Reached ...
if (result &&
maxAllowed > 0)
{
//
CleanupArray(
sources,
maxAllowed //
);
}
//
return result;
}
template <typename T>
int FillNotExists(
T &dest[],
T &source[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
int maxAllowed = 0 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Normalize ...
maxAllowed = NormalizeInt(maxAllowed, 0);
//
// Validate ...
bool has = HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has =
source[i].IsValid() &&
(!HasDirection(forDir) || forDir == source[i].dir);
if (!has)
{
continue;
}
//
has = AddIfNotExists(source[i], dest);
if (has)
{
result++;
}
}
//
// Handle Cleanup Collection
// if Max Reached ...
if (maxAllowed > 0)
{
//
CleanupArray(
dest,
maxAllowed //
);
}
//
return result;
}
template <typename T>
int FillNotExists(
T &dest[],
T &source[],
bool forceClean = false,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
int maxAllowed = 0 //
)
{
//
int result = 0;
//
// Prepare ...
if (forceClean)
{
XClean(dest);
}
//
// Normalize ...
maxAllowed = NormalizeInt(maxAllowed, 0);
//
// Validate ...
bool has = HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has =
source[i].IsValid() &&
(!HasDirection(forDir) || forDir == source[i].dir);
if (!has)
{
continue;
}
//
has = AddIfNotExists(source[i], dest);
if (has)
{
result++;
}
}
//
// Handle Cleanup Collection
// if Max Reached ...
if (maxAllowed > 0)
{
//
CleanupArray(
dest,
maxAllowed //
);
}
//
return result;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Extract |
//+------------------------------------------------------------------+
/**
* Extract Specified Directional Items ...
*
* @param dest: reference collection to holds extracted items ...
* @param source: reference collection to provides data source ...
* @param forDir: Specified which direction to Extract items ...
*
* @return ( int )
*/
template <typename T>
int ExtractByDirection(
T &dest[],
T &source[],
ENUM_X_DIRECTION forDir //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = HasChild(source) &&
HasDirection(forDir);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].dir == forDir;
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
//+------------------------------------------------------------------+
//
//
//
//+------------------------------------------------------------------+
//| Other Extensions |
//+------------------------------------------------------------------+
/**
* Validate Boxes ...
* @param box: XBoxZone instance reference for Validate ...
* @param barIndex: int, Bar Index ...
* @param barsLength: int, Bars Length for Validation ...
*
* @return ( bool )
*/
bool IsBoxValid(
XBoxZone &box,
int barIndex = 0,
int barsLength = 3 //
)
{
//
bool result = false;
//
// Normalize Bar Index ...
barIndex = NormalizeInt(barIndex, 0);
barsLength = NormalizeInt(barsLength, 1);
//
// Ceck Input Box is Valid ...
result = box.IsValid();
if (!result)
{
return result;
}
//
// Check Input Box is Breaked or not ...
// Breaktion Found using Counting Over/Under Close Bars ...
bool isBullish = box.IsBullish();
double appliedPrice = box.GetInDirectionalPrice();
result = NotEmptyZero(appliedPrice);
if (!result)
{
return result;
}
//
int toIDX = box.ToIndex();
//
XOHCL iBar;
int edgeBreakes = 0;
for (int i = barIndex; i <= toIDX; i++)
{
//
// Initialize Indexed Bar ...
result = iBar.Init(
box.symbol,
box.period,
i //
);
//
// Checking Price ...
result =
//
// Checking Bar Validation ...
result &&
//
// Checking Price Breaked or not ...
(isBullish
? iBar.close < box.lower
: iBar.close > box.upper);
if (result)
{
edgeBreakes++;
}
else
{
edgeBreakes = 0;
}
//
result = edgeBreakes >= barsLength;
if (result)
{
break;
}
//
iBar.Clean();
}
//
iBar.Clean();
//
// return true;
//
result =
edgeBreakes < barsLength;
//
return result;
}
/**
* Validate a Box based on Price ...
*
* @param box: XBoxZone instance, box to Validate ...
* @param barIndex: int, Start Validating Bar's Index ...
* @param pType: ENUM_X_BOUNDARY_PRICE, Price Type for Validation ...
*
* @return ( bool )
*/
bool IsBoxValid(
XBoxZone &box,
int barIndex = 0,
ENUM_X_BOUNDARY_PRICE pType = X_BOUNDARY_PRICE_UP_DOWN //
)
{
//
bool result = false;
//
// Normalize Bar Index ...
barIndex = NormalizeInt(barIndex, 0);
//
// Validaet ...
result =
box.IsValid() &&
IsXValid(pType);
if (!result)
{
return result;
}
//
bool isBullish = box.IsBullish();
//
int fromIDX = box.FromIndex();
result =
IsValidIndex(fromIDX) &&
barIndex < fromIDX;
if (!result)
{
return result;
}
//
// Loop through ...
XOHCL iBar;
bool has = false;
double appliedPrice = EMPTY_VALUE;
for (int i = barIndex; i < fromIDX; i++)
{
//
// Initialize Bar ...
iBar.Clean();
has = iBar.Init(box.symbol, box.period, i);
if (!has)
{
//
result = false;
break;
}
//
// Calculate Applied Price ...
switch (pType)
{
//
case X_BOUNDARY_PRICE_UP_DOWN:
//
appliedPrice =
isBullish
? iBar.GetDown()
: iBar.GetUp();
break;
//
case X_BOUNDARY_PRICE_HIGH_LOW:
//
appliedPrice =
isBullish
? iBar.low
: iBar.high;
break;
//
default:
appliedPrice = EMPTY_VALUE;
break;
}
has = NotEmptyZero(appliedPrice);
if (!has)
{
//
result = false;
break;
}
//
has =
has &&
result &&
(isBullish
? appliedPrice >= box.lower
: appliedPrice <= box.upper);
if (!has) {
//
result = false;
break;
}
//
iBar.Clean();
}
//
return result;
}
//
void SortBoxes(
XBoxZone &items[],
int maxAllowed = 0 //
)
{
//
int idx = -1;
bool has = false;
//
has = HasChild(items);
if (!has)
{
return;
}
//
XBoxZone tmp[];
Copy(
items,
tmp //
);
Clean(items);
//
while (HasChild(tmp))
{
//
idx = GetOldest(tmp);
has = IsValidIndex(idx);
if (!has)
{
break;
}
//
XBoxZone iBox = tmp[idx];
ArrayRemove(
tmp,
idx,
1 //
);
//
AddRef(
iBox,
items //
);
}
//
if (maxAllowed > 0)
{
//
CleanupArray(
items,
maxAllowed //
);
}
//
Clean(tmp);
}
/**
* Check a BaxHas Valid Place for Specified Bar ...
*
* @param bar: XOHCL instance reference, Specified Bar ...
* #param box: XBoxZone instance reference, Specified Box ...
*
* @return ( bool )
*/
bool IsBoxPlaceValidForBar(
XOHCL &bar,
XBoxZone &box //
)
{
//
bool result = false;
//
result = bar.IsValid() &&
box.IsValid();
if (!result)
{
return result;
}
//
result =
box.IsBullish()
? bar.low > box.upper
: bar.high < box.upper;
//
return result;
}
//
void ValidateBoxes(
XBoxZone &boxes[],
int barIndex = 0,
int barsLength = 3,
bool forceSorting = false,
int maxAllowed = 0 //
)
{
//
bool has = false;
//
// Normalize Args ...
barIndex = NormalizeInt(barIndex, 0);
barsLength = NormalizeInt(barsLength, 3);
//
// Validate Args ...
has = HasChild(boxes);
if (!has)
{
return;
}
//
// Copy Boxes to tmp ...
XBoxZone tmp[];
Copy(
boxes,
tmp //
);
Clean(boxes);
//
// Looping Through Exists Boxes ...
while (HasChild(tmp))
{
//
// Select Indexed Box ...
XBoxZone iBox = tmp[0];
//
// Remove Indexed Box ...
ArrayRemove(
tmp,
0,
1 //
);
//
// Check Box Validating ...
has = IsBoxValid(
iBox,
barIndex,
barsLength //
);
if (has)
{
//
AddRef(
iBox,
boxes //
);
}
}
//
// Sorting ...
if (forceSorting)
{
//
// Check Has Result or not ...
has = HasChild(boxes);
if (has)
{
//
// Sorting ...
SortBoxes(
boxes,
maxAllowed //
);
}
}
//
}
void UpdateToTime(
XBoxZone &zones[],
datetime toTime = NULL //
)
{
//
// Normalize ...
toTime = NormalizeTime(toTime);
//
// Validate ...
bool has = HasChild(zones);
if (!has)
{
return;
}
//
int count = ArraySize(zones);
for (int i = 0; i < count; i++)
{
zones[i].to = toTime;
}
}
/**
* Remove Breaked Zones from a Collection ...
*
* @param source: XBoxZone, reference to Specified Collection ...
*
* @return ( int )
*/
int RemoveBreakedZones(
XBoxZone &source[],
bool forceBreak = false //
)
{
//
int result = 0;
//
// Validate ...
bool has = HasChild(source);
if (!has)
{
return result;
}
//
XBoxZone iZone;
XBoxZone tmps[];
Copy(
source,
tmps //
);
XClean(source);
XOHCL tmpBars[];
int breakerBars = 0;
while (HasChild(tmps))
{
//
iZone.Clean();
iZone = tmps[0];
ArrayRemove(tmps, 0, 1);
has = IsXValid(iZone.breakAt);
if (has)
{
continue;
}
//
if (forceBreak)
{
//
breakerBars = GetBreakerBars(iZone, tmpBars);
has = IsValidSize(breakerBars);
}
if (has)
{
continue;
}
//
AddIfNotExists(
iZone,
source //
);
}
//
result = ArraySize(source);
//
return result;
}
/**
* Remove Filled Zones ...
*
* @param source: XBoxZone, collection reference to Provide Data Source ...
* @param zoneRangeFilledFactor: double, Filling Factor ...
*
* @return ( int )
*/
int RemoveFilledZones(
XBoxZone &source[],
double zoneRangeFilledFactor = 0.8 //
)
{
//
int result = 0;
//
// Validate ...
bool has = HasChild(source);
if (!has)
{
return result;
}
//
XBoxZone iTMP;
XBoxZone tmp[];
Copy(source, tmp);
XClean(source);
while (HasChild(tmp))
{
//
iTMP.Clean();
iTMP = tmp[0];
ArrayRemove(tmp, 0, 1);
//
has = IsFilled(iTMP, zoneRangeFilledFactor);
if (!has)
{
AddIfNotExists(iTMP, source);
}
}
//
result = ArraySize(source);
//
return result;
}
// #region Zone Converters ...
/**
* Converts a Bar to Pivot ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param pivot: XPivot, reference to holds result ...
* @param forDir: ENUM_X_DIRECTION, specified Pivot Direction ...
* @param prefix: string, Specified Pivot Prefix (used for Object Type) ...
* @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ...
* @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ...
*
* @return ( bool )
*/
bool ToPivot(
XOHCL &bar,
XPivot &pivot,
ENUM_X_DIRECTION forDir,
string prefix = NULL,
ENUM_X_PRICE peakPriceType = X_PRICE_HIGH,
ENUM_X_PRICE valePriceType = X_PRICE_LOW //
)
{
//
bool result = false;
//
// Prepare ...
pivot.Clean();
//
// Normalize ...
if (!IsXValid(peakPriceType))
{
peakPriceType = X_PRICE_HIGH;
}
if (!IsXValid(valePriceType))
{
valePriceType = X_PRICE_LOW;
}
//
// Validate ...
result = bar.IsValid() &&
HasDirection(forDir) &&
IsXValid(peakPriceType) &&
IsXValid(valePriceType);
if (!result)
{
return result;
}
//
// Check Direction ...
bool isBullish = IsSpecifiedBullish(forDir);
//
// Prepare Value of Pivot ...
double iValue =
isBullish
? bar.GetPrice(valePriceType)
: bar.GetPrice(peakPriceType);
//
// Prepare Pivot Type ...
ENUM_X_PIVOT_TYPE iType =
isBullish
? X_PIVOT_TYPE_VALE
: X_PIVOT_TYPE_PEAK;
//
// Initialize Pivot ...
result = pivot.Init(
iValue,
bar.time,
bar.symbol,
forDir,
bar.period,
iType //
);
if (result)
{
//
// Set Prefix if Pivot initialized successfully ...
pivot.prefix = prefix;
}
//
// Validate ...
result = pivot.IsValid();
if (!result)
{
pivot.Clean();
}
//
return result;
}
/**
* Converts a Bar to Pattern Pivot ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param pivot: XPivot, reference to holds result ...
* @param patternDir: ENUM_X_DIRECTION, specified Pivot Direction ...
* @param pattern: ENUM_X_BAR_PATTERN, Specified Pattern Type ...
* @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ...
* @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ...
*
* @return ( bool )
*/
bool ToPivot(
XOHCL &bar,
XPivot &pivot,
ENUM_X_DIRECTION patternDir,
ENUM_X_BAR_PATTERN pattern,
ENUM_X_PRICE peakPriceType = X_PRICE_HIGH,
ENUM_X_PRICE valePriceType = X_PRICE_LOW //
)
{
//
bool result = false;
//
// Prepare ...
pivot.Clean();
//
// Normalize ...
if (!IsXValid(peakPriceType))
{
peakPriceType = X_PRICE_HIGH;
}
if (!IsXValid(valePriceType))
{
valePriceType = X_PRICE_LOW;
}
//
// Validate ...
result = bar.IsValid() &&
IsXValid(pattern) &&
IsXValid(peakPriceType) &&
IsXValid(valePriceType) &&
HasDirection(patternDir);
if (!result)
{
return result;
}
//
datetime iTime = bar.time;
string iSymbol = bar.symbol;
string iPrefix = ToXString(pattern);
ENUM_TIMEFRAMES iPeriod = bar.period;
double iValue = IsXBullish(patternDir)
? bar.GetPrice(X_PRICE_LOW)
: IsXBearish(patternDir)
? bar.GetPrice(X_PRICE_HIGH)
: EMPTY_VALUE;
ENUM_X_PIVOT_TYPE iType = IsXBullish(patternDir)
? X_PIVOT_TYPE_VALE
: IsXBearish(patternDir)
? X_PIVOT_TYPE_PEAK
: X_PIVOT_TYPE_NONE;
//
result = pivot.Init(
iValue,
iTime,
iSymbol,
patternDir,
iPeriod,
iType //
);
if (result)
{
pivot.prefix = iPrefix;
}
//
// Cleanup Resources ...
if (!result)
{
pivot.Clean();
}
//
return result;
}
/**
* Converts POI Bar to Box ...
*
* @param bar: XOHCL, reference to Specified Pattern ...
* @param box: XBoxZone, reference to holds result ...
* @param forDir: ENUM_X_DIRECTION, Specified Pattern Direction ...
* @param prefix: string, Specified Pattern Type ...
* @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ...
* @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ...
* @param setFromByBreakerBar: bool, Set Box From Time to Breaker Bar ...
*
* @return ( bool )
*/
bool ToBox(
XOHCL &bar,
XBoxZone &box,
ENUM_X_DIRECTION forDir,
string prefix = NULL,
ENUM_X_PRICE peakPriceType = X_PRICE_HIGH,
ENUM_X_PRICE valePriceType = X_PRICE_LOW,
bool setFromByBreakerBar = false //
)
{
//
bool result = false;
//
// Prepare ...
box.Clean();
//
// Normalize ...
if (!IsXValid(peakPriceType))
{
peakPriceType = X_PRICE_HIGH;
}
if (!IsXValid(valePriceType))
{
valePriceType = X_PRICE_LOW;
}
//
// Validate ...
result = bar.IsValid() &&
HasDirection(forDir) &&
IsXValid(peakPriceType) &&
IsXValid(valePriceType);
if (!result)
{
return result;
}
//
// Check if is Valid Pattern ...
ENUM_X_BAR_PATTERN iPattern = ToBarPattern(prefix);
result = IsXValid(iPattern);
if (result)
{
//
// Conver to Box as Pattern ...
result = ToBox(
bar,
box,
forDir,
iPattern,
peakPriceType,
valePriceType,
setFromByBreakerBar //
);
}
//
// There is not any Valid Pattern Provided ...
else
{
//
bool isBullish = IsXBullish(forDir);
double peakPrice = bar.GetPrice(peakPriceType);
double valePrice = bar.GetPrice(valePriceType);
//
string iType = prefix;
datetime iAt = bar.time;
datetime iTo = bar.time;
double iUpper = peakPrice;
double iLower = valePrice;
string iSymbol = bar.symbol;
datetime iFrom = bar.BeforeOn();
ENUM_TIMEFRAMES iPeriod = bar.period;
//
// Assign Values to Box ...
box.at = iAt;
box.to = iTo;
box.from = iFrom;
box.type = iType;
box.dir = forDir;
box.upper = iUpper;
box.lower = iLower;
box.symbol = iSymbol;
box.period = iPeriod;
}
//
// Validate result ...
result = box.IsValid();
if (!result)
{
//
box.Clean();
return result;
}
//
return result;
}
/**
* Converts Pattern Bar to Box ...
*
* @param bar: XOHCL, reference to Specified Pattern ...
* @param box: XBoxZone, reference to holds result ...
* @param forDir: ENUM_X_DIRECTION, Specified Pattern Direction ...
* @param prefix: string, Specified Pattern Type ...
* @param peakPriceType: ENUM_X_PRICE, Specified Peak Pivot's Applied Price ...
* @param valePriceType: ENUM_X_PRICE, Specified Vale Pivot's Applied Price ...
* @param setFromByBreakerBar: bool, Set Box From Time to Breaker Bar ...
*
* @return ( bool )
*/
bool ToBox(
XOHCL &bar,
XBoxZone &box,
ENUM_X_DIRECTION patternDir,
ENUM_X_BAR_PATTERN pattern,
ENUM_X_PRICE peakPriceType = X_PRICE_HIGH,
ENUM_X_PRICE valePriceType = X_PRICE_LOW,
bool setFromByBreakerBar = false //
)
{
//
bool result = false;
//
// Prepare ...
box.Clean();
//
// Normalize ...
if (!IsXValid(peakPriceType))
{
peakPriceType = X_PRICE_HIGH;
}
if (!IsXValid(valePriceType))
{
valePriceType = X_PRICE_LOW;
}
//
// Validate ...
result = bar.IsValid() &&
IsXValid(pattern) &&
IsXValid(peakPriceType) &&
IsXValid(valePriceType) &&
HasDirection(patternDir);
if (!result)
{
return result;
}
//
// Define Requirements ...
XOHCL tmpBar;
XBoxZone tmpBox;
bool has = false;
datetime iAt = bar.time;
datetime iTo = bar.time;
double iUpper = EMPTY_VALUE;
double iLower = EMPTY_VALUE;
string iSymbol = bar.symbol;
datetime iFrom = bar.BeforeOn();
string iType = ToXString(pattern);
ENUM_TIMEFRAMES iPeriod = bar.period;
//
bool isBullish = IsXBullish(patternDir);
double peakPrice = bar.GetPrice(peakPriceType);
double valePrice = bar.GetPrice(valePriceType);
//
// Calculate Requirements Based on Pattern Type and Direction ...
switch (pattern)
{
//
case X_BAR_PATTERN_HIGH: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
has = GetBreakerBar(
bar,
tmpBar,
peakPriceType,
peakPriceType,
X_DIRECTION_BULLISH //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper = peakPrice;
iLower = bar.GetUp();
}
break;
//
case X_BAR_PATTERN_LOW: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
has = GetBreakerBar(
bar,
tmpBar,
valePriceType,
valePriceType,
X_DIRECTION_BEARISH //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper = bar.GetDown();
iLower = valePrice;
}
break;
//
case X_BAR_PATTERN_MOMENTUM: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper = peakPrice;
iLower = valePrice;
}
break;
//
case X_BAR_PATTERN_ENGULFED: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper = peakPrice;
iLower = valePrice;
}
break;
//
case X_BAR_PATTERN_TRUE_GAPED: {
//
tmpBar.Clean();
has = bar.GetPreviousBar(tmpBar);
if (has)
{
//
iFrom = tmpBar.time;
//
iUpper =
isBullish
? valePrice
: tmpBar.GetPrice(valePriceType);
iLower =
isBullish
? tmpBar.GetPrice(peakPriceType)
: peakPrice;
}
}
break;
//
case X_BAR_PATTERN_PINNED: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper =
isBullish
? bar.GetDown()
: peakPrice;
iLower =
isBullish
? valePrice
: bar.GetUp();
}
break;
//
case X_BAR_PATTERN_STAR: {
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
//
if (setFromByBreakerBar)
{
iFrom = tmpBar.time;
}
//
int idx = -1;
int mLength = tmpBar.Index() - bar.Index();
iLower = bar.FindLowest(idx, mLength, valePriceType);
iUpper = bar.FindHighest(idx, mLength, peakPriceType);
}
}
break;
//
case X_BAR_PATTERN_PIERCING: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper = peakPrice;
iLower = valePrice;
}
break;
//
case X_BAR_PATTERN_RISING: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper = peakPrice;
iLower = valePrice;
}
break;
//
case X_BAR_PATTERN_FLAG: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
int idx = -1;
int mLength = 3;
iUpper = bar.FindHighest(idx, mLength, peakPriceType);
iLower = bar.FindLowest(idx, mLength, valePriceType);
}
break;
//
case X_BAR_PATTERN_SIGNALKEY: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
has = bar.GetPreviousBar(tmpBar);
if (has)
{
//
iUpper = MathMax(peakPrice, tmpBar.GetPrice(peakPriceType));
iLower = MathMin(valePrice, tmpBar.GetPrice(valePriceType));
}
}
break;
//
case X_BAR_PATTERN_OB: {
//
tmpBox.Clean();
has = ToOBBox(
bar,
tmpBox,
patternDir //
);
if (has)
{
//
iFrom = tmpBox.from;
iUpper = tmpBox.upper;
iLower = tmpBox.lower;
}
}
break;
//
case X_BAR_PATTERN_FVG: {
//
tmpBox.Clean();
has = ToFVGBox(
bar,
tmpBox,
patternDir //
);
if (has)
{
//
iFrom = tmpBox.from;
iUpper = tmpBox.upper;
iLower = tmpBox.lower;
}
}
break;
//
case X_BAR_PATTERN_SUPPORT: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper =
isBullish
? peakPrice
: valePrice;
iLower =
isBullish
? peakPrice
: valePrice;
}
break;
//
case X_BAR_PATTERN_RESISTANCE: {
//
if (setFromByBreakerBar)
{
//
tmpBar.Clean();
ENUM_X_PRICE iPType = isBullish
? valePriceType
: peakPriceType;
has = GetBreakerBar(
bar,
tmpBar,
iPType,
iPType,
patternDir //
);
if (has)
{
iFrom = tmpBar.time;
}
}
//
iUpper =
isBullish
? peakPrice
: valePrice;
iLower =
isBullish
? peakPrice
: valePrice;
}
break;
}
//
// Assign Values to Box ...
box.at = iAt;
box.to = iTo;
box.from = iFrom;
box.type = iType;
box.upper = iUpper;
box.lower = iLower;
box.symbol = iSymbol;
box.period = iPeriod;
box.dir = patternDir;
//
result = box.IsValid();
//
// Cleanup Resources ...
if (!result)
{
box.Clean();
}
tmpBar.Clean();
tmpBox.Clean();
//
return result;
}
/**
* Converts Order Flow to Zone ...
*
* @param zone: XBoxZone, reference to holds result ...
* @param orderFlow: XBoxZone, collection reference to provides order flow ...
*
* @return ( bool )
*/
bool ToBox(
XBoxZone &zone,
XBoxZone &orderFlow[] //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
//
// Validate ...
result = HasChild(orderFlow);
if (!result)
{
return result;
}
//
zone = orderFlow[0];
int idx = GetHighest(orderFlow);
if (IsValidIndex(idx))
{
zone.upper = orderFlow[idx].upper;
}
idx = GetLowest(orderFlow);
if (IsValidIndex(idx))
{
zone.lower = orderFlow[idx].lower;
}
//
zone.type = "XOrderFlowP";
//
result = zone.IsValid();
//
return result;
}
/**
* Converts a Bar to OB Box ...
*
* @param bar: XOHCL, Specified Bar ...
* @param box: XBoxZone, destination Box ...
* @param forDir: ENUM_X_DIRECTION, Specified Direction ...
*
* @return ( bool )
*/
bool ToOBBox(
XOHCL &bar,
XBoxZone &box,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
// Prepare ...
box.Clean();
//
// Normalize ...
if (!HasDirection(forDir))
{
forDir = bar.GetDirection();
}
//
// Validate ...
result = bar.IsValid() &&
HasDirection(forDir) &&
bar.GetDirection() == forDir;
if (!result)
{
return result;
}
//
// Detect OB Start Bar ...
XOHCL obStartBar;
result = GetDirectionalBar(
bar,
obStartBar,
Opposit(forDir) //
);
if (!result)
{
//
obStartBar.Clean();
return result;
}
//
box.dir = forDir;
box.to = bar.time;
box.at = bar.time;
box.symbol = bar.symbol;
box.period = bar.period;
box.from = obStartBar.time;
box.type = ToXString(X_BAR_PATTERN_OB);
box.lower = MathMin(obStartBar.low, bar.low);
box.upper = MathMax(obStartBar.high, bar.high);
//
result = box.IsValid();
//
// Cleanup Resources ...
if (!result)
{
box.Clean();
}
obStartBar.Clean();
//
return result;
}
/**
* Converts a Bar to FVG Box ...
*
* @param bar: XOHCL, Specified Bar ...
* @param box: XBoxZone, destination Box ...
* @param forDir: ENUM_X_DIRECTION, Specified Direction ...
*
* @return ( bool )
*/
bool ToFVGBox(
XOHCL &bar,
XBoxZone &box,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
// Prepare ...
box.Clean();
//
// Normalize ...
if (!HasDirection(forDir))
{
forDir = bar.GetDirection();
}
//
// Validate ...
result = bar.IsValid() &&
HasDirection(forDir) &&
bar.GetDirection() == forDir;
if (!result)
{
return result;
}
//
// Detect FVG Start Bar ...
XOHCL fvgStartBar;
result = bar.BarAt(
bar.Index() + 2,
fvgStartBar);
if (!result)
{
//
fvgStartBar.Clean();
return result;
}
//
bool isBullish = IsXBullish(forDir);
//
box.dir = forDir;
box.to = bar.time;
box.at = bar.time;
box.upper =
isBullish
? bar.low
: bar.high;
box.symbol = bar.symbol;
box.period = bar.period;
box.lower =
isBullish
? fvgStartBar.high
: fvgStartBar.low;
box.from = fvgStartBar.time;
box.type = ToXString(X_BAR_PATTERN_FVG);
//
result = box.IsValid();
//
// Cleanup Resources ...
if (!result)
{
box.Clean();
}
fvgStartBar.Clean();
//
return result;
}
/**
* Converts a Bar to Support Box ...
*
* @param bar: XOHCL, Specified Bar ...
* @param box: XBoxZone, destination Box ...
* @param toTime: datetime, Specified Box to Time ...
*
* @return ( bool )
*/
bool ToSupportBox(
XOHCL &bar,
XBoxZone &box,
datetime toTime = NULL,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
box.Clean();
//
// Normalize ...
toTime = NormalizeTime(toTime);
validationLength = NormalizeInt(validationLength, 0);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
XOHCL breaker;
result = GetBreakerBar(
bar,
breaker,
X_PRICE_LOW,
X_PRICE_DOWN,
X_DIRECTION_BEARISH,
500 //
);
if (!result)
{
breaker.Clean();
}
//
box.to = toTime;
box.at = bar.time;
box.from =
breaker.IsValid()
? breaker.time
: validationLength <= 0
? bar.time
: GetBarTime(
bar.symbol,
bar.period,
bar.Index() + validationLength //
);
box.lower = bar.low;
box.symbol = bar.symbol;
box.period = bar.period;
box.upper = bar.GetDown();
box.dir = X_DIRECTION_BULLISH;
box.type = ToXString(X_BAR_PATTERN_SUPPORT);
//
result = box.IsValid();
if (!result)
{
box.Clean();
}
//
return result;
}
/**
* Converts a Bar to Resistance Box ...
*
* @param bar: XOHCL, Specified Bar ...
* @param box: XBoxZone, destination Box ...
* @param toTime: datetime, Specified Box to Time ...
*
* @return ( bool )
*/
bool ToResistanceBox(
XOHCL &bar,
XBoxZone &box,
datetime toTime = NULL,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
box.Clean();
//
// Normalize ...
toTime = NormalizeTime(toTime);
validationLength = NormalizeInt(validationLength, 0);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
XOHCL breaker;
result = GetBreakerBar(
bar,
breaker,
X_PRICE_HIGH,
X_PRICE_UP,
X_DIRECTION_BULLISH,
500 //
);
if (!result)
{
breaker.Clean();
}
//
box.to = toTime;
box.at = bar.time;
box.from =
breaker.IsValid()
? breaker.time
: validationLength <= 0
? bar.time
: GetBarTime(
bar.symbol,
bar.period,
bar.Index() + validationLength //
);
box.upper = bar.high;
box.symbol = bar.symbol;
box.period = bar.period;
box.lower = bar.GetUp();
box.dir = X_DIRECTION_BEARISH;
box.type = ToXString(X_BAR_PATTERN_RESISTANCE);
//
result = box.IsValid();
if (!result)
{
box.Clean();
}
//
return result;
}
// #endregion
// #region Zone Checkers ...
/**
* Check a Zone is Filled or Not ...
*
* @param zone: XBoxZone, reference to Specified Zone ...
* @param zoneRangeFilledFactor: double, Filling Factor ...
*
* @return ( bool )
*/
bool IsFilled(
XBoxZone &zone,
double zoneRangeFilledFactor = 0.8 //
)
{
//
bool result = false;
//
// Validate ...
result = zone.IsValid() &&
zoneRangeFilledFactor > 0 &&
zoneRangeFilledFactor < 1;
if (!result)
{
//
result = true;
return result;
}
//
XOHCL iBar;
int toIDX = zone.ToIndex();
int fromIDX = zone.FromIndex();
double zoneRangeFactor = zone.GetRange() / 100;
double useValue = zone.lower + (zoneRangeFactor * zoneRangeFilledFactor);
for (int i = toIDX; i < fromIDX; i++)
{
//
// Initialize Indexed Bar ...
iBar.Clean();
result = iBar.Init(zone.symbol, zone.period, i);
result =
result &&
(zone.IsBullish()
? iBar.GetPrice(X_PRICE_LOW) <= useValue
: iBar.GetPrice(X_PRICE_HIGH) >= useValue);
if (result)
{
break;
}
}
//
// Cleanup ...
iBar.Clean();
//
return result;
}
/**
* Check Specified Zone is Breaked by Specified Bar or not ...
*
* @param bar: Specified Bar ...
* @param zone: Specified Zone ...
* @param forceBarEdge: bool, flag to Check Breaktion by high ot low ...
*
* @return ( bool )
*/
bool IsBreaked(
XOHCL &bar,
XBoxZone &zone,
bool forceBarEdge = false //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
// Check Break ...
result =
zone.IsBullish()
? bar.close < zone.lower
: bar.close > zone.upper;
//
// Apply Force Bar Edge ...
if (forceBarEdge)
{
//
result =
result &&
zone.IsBullish()
? bar.low > zone.upper
: bar.high < zone.lower;
}
//
return result;
}
/**
* Check Specified Zone is Tested by Specified Bar or not ...
*
* @param bar: Specified Bar ...
* @param zone: Specified Zone ...
*
* @return ( bool )
*/
bool IsTested(
XOHCL &bar,
XBoxZone &zone //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
// Check Test ...
result =
zone.IsBullish()
? bar.low < zone.upper && bar.low > zone.lower
: bar.high > zone.lower &&
bar.high < zone.upper;
//
return result;
}
/**
* Check Specified Zone is Rejected by Specified Bar or not ...
*
* @param bar: Specified Bar ...
* @param zone: Specified Zone ...
*
* @return ( bool )
*/
bool IsRejected(
XOHCL &bar,
XBoxZone &zone //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
// Check Test ...
result =
IsTested(bar, zone) &&
(zone.IsBullish()
? bar.GetDown() >= zone.upper
: bar.GetUp() <= zone.lower);
//
return result;
}
/**
* Check Specified Bar is Inside Specified Zone or not ...
*
* @param bar: Specified Bar ...
* @param zone: Specified Zone ...
*
* @return ( bool )
*/
bool IsInside(
XOHCL &bar,
XBoxZone &zone //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
// Check Inside ...
result =
zone.IsBullish()
? bar.low < zone.upper &&
bar.low > zone.lower
: bar.high > zone.lower &&
bar.high < zone.upper;
//
return result;
}
/**
* Check Specified Bar is Acted On Specified Zone or not ...
*
* @param bar: Specified Bar ...
* @param zone: Specified Zone ...
*
* @return ( bool )
*/
bool IsActed(
XOHCL &bar,
XBoxZone &zone //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
// Get Previous Bar ...
XOHCL pBar;
result = bar.GetPreviousBar(pBar);
if (!result)
{
return result;
}
//
// Previous Bar must one of Following States:
// - Tested;
// - Inside;
// - Breaked;
bool isTested = IsTested(pBar, zone);
bool isInside = IsInside(pBar, zone);
bool isBreaked = IsBreaked(pBar, zone);
result = isTested ||
isInside ||
isBreaked;
if (!result)
{
return result;
}
//
// Current Bar Must Close Over / Under Zone ...
result =
zone.IsBullish()
? bar.close > zone.upper
: zone.IsBearish()
? bar.close < zone.lower
: false;
//
// Cleanup Resources ...
pBar.Clean();
//
return result;
}
/**
* Check Specified Zone is Breaked or not ...
*
* @param zone: XBoxZone, reference to Specified Zone ...
* @param priceType: ENUM_X_PRICE, Specified Price Type for Zone Break Detection ...
*
* @return ( bool )
*/
bool IsBreaked(
XBoxZone &zone,
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
)
{
//
bool result = false;
//
// Validate ...
result = zone.IsValid() &&
IsXValid(priceType);
if (!result)
{
//
result = true;
return result;
}
//
XOHCL iBar;
double iPrice;
bool isBullish;
int start = zone.ToIndex();
int end = zone.FromIndex();
for (int i = start; i < end; i++)
{
//
// Initialize Indexed Bar ...
iBar.Clean();
result = iBar.Init(zone.symbol, zone.period, i);
if (!result)
{
//
result = true;
break;
}
//
isBullish = zone.IsBullish();
iPrice = iBar.GetPrice(priceType);
result = isBullish
? iPrice < zone.lower
: iPrice > zone.upper;
if (result)
{
break;
}
}
//
// Cleanup ...
iBar.Clean();
//
return result;
}
/**
* Check Specified Bar is Acted On Specified Zone or not ...
*
* @param bar: Specified Bar ...
* @param zone: Specified Zone ...
* @param validationLength: Specified Length for Breaks ...
*
* @return ( bool )
*/
bool IsValidBreaked(
XOHCL &bar,
XBoxZone &zone,
int validationLength = 3 //
)
{
//
bool result = false;
//
// Normalize ...
validationLength = NormalizeInt(validationLength, 1);
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
XOHCL iBar;
int count = 0;
int start = bar.Index();
int end = start + validationLength;
for (int i = start; i < end; i++)
{
//
// Initialize Indexed Bar ...
result = bar.BarAt(i, iBar);
if (!result)
{
break;
}
//
result = IsBreaked(iBar, zone);
if (result)
{
count++;
}
}
//
result = IsValidSize(count) &&
count >= validationLength;
//
// Cleanup Resources ...
iBar.Clean();
//
return result;
}
/**
* Check Specified Bar is Fake Breaked Specified Zone or not ...
*
* @param bar: Specified Bar ...
* @param zone: Specified Zone ...
* @param validationLength: Specified Length for Breaks ...
*
* @return ( bool )
*/
bool IsFakeBreaked(
XOHCL &bar,
XBoxZone &zone,
int validationLength = 3 //
)
{
//
bool result = false;
//
// Normalize ...
validationLength = NormalizeInt(validationLength, 1);
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
// Check Bar Must Acting Zone ...
result = zone.IsBullish()
? bar.close > zone.upper
: zone.IsBearish()
? bar.close < zone.lower
: false;
if (!result)
{
return result;
}
//
// Detect Breaker Bars ...
XOHCL breakerBars[];
int breakerBarsCount = GetBreakerBars(
zone,
breakerBars //
);
result = IsValidSize(breakerBarsCount);
if (!result)
{
//
XClean(breakerBars);
return result;
}
//
// Get Youngest Breaker Bars ...
int idx = GetYoungest(breakerBars);
result = IsValidIndex(idx);
if (!result)
{
//
XClean(breakerBars);
return result;
}
//
result = breakerBars[idx].Index() - bar.Index() <= validationLength;
//
// Cleanup Resources ...
XClean(breakerBars);
//
return result;
}
/**
* Check Specified ZOne is Affected by Specified Bar or not ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param zone: XBoxZone, reference to Specified Zone ...
*
* @return ( bool )
*/
bool IsZoneAffected(
XOHCL &bar,
XBoxZone &zone //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
zone.IsValid();
if (!result)
{
return result;
}
//
bool isActed = IsActed(bar, zone);
bool isTested = IsTested(bar, zone);
bool isFakeBreaked = IsFakeBreaked(bar, zone);
//
result = isActed ||
isTested ||
isFakeBreaked;
//
return result;
}
// #endregion
// #region Zones Hasers ...
/**
* Check a Bar is Inside a Zone or not ...
*
* @param index: int, reference to holds detected index ...
* @param bar: reference to Specified Bar ...
* @param source: reference collection to provide source ...
*
* @return ( bool )
*/
bool HasInside(
int &index,
XOHCL &bar,
XBoxZone &source[] //
)
{
//
XBoxZone selected[];
int count = ExtractInsides(bar, selected, source);
bool result = IsValidSize(count);
if (result)
{
//
index = GetYoungest(selected);
if (IsValidIndex(index))
{
result = FindIndex(index, selected[index], source);
}
}
//
XClean(selected);
//
return result;
}
/**
* Check a Bar is Reject a Zone or not ...
*
* @param index: int, reference to holds detected index ...
* @param bar: reference to Specified Bar ...
* @param source: reference collection to provide source ...
*
* @return ( bool )
*/
bool HasRejected(
int &index,
XOHCL &bar,
XBoxZone &source[] //
)
{
//
XBoxZone selected[];
int count = ExtractRejecteds(bar, selected, source);
bool result = IsValidSize(count);
if (result)
{
//
index = GetYoungest(selected);
if (IsValidIndex(index))
{
result = FindIndex(index, selected[index], source);
}
}
//
XClean(selected);
//
return result;
}
/**
* Check a Bar is Break a Zone or not ...
*
* @param index: int, reference to holds detected index ...
* @param bar: reference to Specified Bar ...
* @param source: reference collection to provide source ...
*
* @return ( bool )
*/
bool HasBreaked(
int &index,
XOHCL &bar,
XBoxZone &source[] //
)
{
//
XBoxZone selected[];
int count = ExtractBreakeds(bar, selected, source);
bool result = IsValidSize(count);
if (result)
{
//
index = GetYoungest(selected);
if (IsValidIndex(index))
{
result = FindIndex(index, selected[index], source);
}
}
//
XClean(selected);
//
return result;
}
/**
* Check a Bar is Act a Zone or not ...
*
* @param index: int, reference to holds detected index ...
* @param bar: reference to Specified Bar ...
* @param source: reference collection to provide source ...
*
* @return ( bool )
*/
bool HasActed(
int &index,
XOHCL &bar,
XBoxZone &source[] //
)
{
//
XBoxZone selected[];
int count = ExtractActeds(bar, selected, source);
bool result = IsValidSize(count);
if (result)
{
//
index = GetYoungest(selected);
if (IsValidIndex(index))
{
result = FindIndex(index, selected[index], source);
}
}
//
XClean(selected);
//
return result;
}
// #endregion
// #region Zone Extractors ...
/**
* Extract Affected Zones for Specified Bar ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param source: XBoxZone, reference collection to Provide Data Source ...
* @param dest: XBoxZone, reference collection to holds result ...
* @param forDir: ENUM_X_DIRECTION, Specified Zones Direction to Lookup ...
*
* @return ( int )
*/
int ExtractAffectedZones(
XOHCL &bar,
XBoxZone &source[],
XBoxZone &dest[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = bar.IsValid() &&
HasChild(source);
if (!has)
{
return result;
}
//
bool isActed;
bool isTested;
bool isInside;
bool isFakeBreaked;
for (int i = 0; i < ArraySize(source); i++)
{
//
// Validate Direction ...
has =
!HasDirection(forDir) ||
forDir == source[i].dir;
if (!has)
{
continue;
}
//
// Check Affected ...
isActed = IsActed(bar, source[i]);
isTested = IsTested(bar, source[i]);
isInside = IsInside(bar, source[i]);
isFakeBreaked = IsFakeBreaked(bar, source[i]);
//
has =
isActed ||
isTested ||
isInside ||
isFakeBreaked;
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all Items which Specified Bar is inside them ...
*
* @param bar: reference to Specified Bar ...
* @param dest: reference to result ...
* @param source: reference collection to provide source ...
*
* @return ( int )
*/
int ExtractInsides(
XOHCL &bar,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
bool has = bar.IsValid() &&
HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = IsInside(
bar,
source[i] //
);
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all Items which Specified Bar is Acted them ...
*
* @param bar: reference to Specified Bar ...
* @param dest: reference to result ...
* @param source: reference collection to provide source ...
*
* @return ( int )
*/
int ExtractActeds(
XOHCL &bar,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = bar.IsValid() &&
HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = IsActed(
bar,
source[i] //
);
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all Items which Specified Bar is Breaked them ...
*
* @param bar: reference to Specified Bar ...
* @param dest: reference to result ...
* @param source: reference collection to provide source ...
*
* @return ( int )
*/
int ExtractBreakeds(
XOHCL &bar,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
bool has = bar.IsValid() &&
HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = IsBreaked(
bar,
source[i] //
);
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Extract all Items which Specified Bar is Rejected them ...
*
* @param bar: reference to Specified Bar ...
* @param dest: reference to result ...
* @param source: reference collection to provide source ...
*
* @return ( int )
*/
int ExtractRejecteds(
XOHCL &bar,
XBoxZone &dest[],
XBoxZone &source[] //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(dest);
//
// Validate ...
bool has = bar.IsValid() &&
HasChild(source);
if (!has)
{
return result;
}
//
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = IsRejected(
bar,
source[i] //
);
if (has)
{
//
AddIfNotExists(
source[i],
dest //
);
}
}
//
result = ArraySize(dest);
//
return result;
}
/**
* Collect all Bars which Breakes Specified Zone ...
*
* @param zone: reference to Specified Zone ...
* @param dest: reference Collection to hold result ...
*
* @return ( int )
*/
int GetBreakerBars(
XBoxZone &zone,
XOHCL &dest[] //
)
{
//
int result = 0;
//
// Validate ...
bool has = zone.IsValid();
if (!has)
{
return result;
}
//
// Prepare ...
SpecifiedClean(dest);
//
// Do Action ...
XOHCL iBar;
int start = zone.ToIndex();
int end = zone.FromIndex();
for (int i = start; i < end; i++)
{
//
// Initialize indexed Bar ...
has = iBar.Init(
zone.symbol,
zone.period,
i //
);
if (!has)
{
continue;
}
//
has = IsBreaked(
iBar,
zone,
false // Breakes by Close ...
);
if (has)
{
//
AddIfNotExists(
iBar,
dest //
);
}
//
iBar.Clean();
}
//
result = ArraySize(dest);
//
iBar.Clean();
//
return result;
}
/**
* Collect all Bars which Inside Specified Zone ...
*
* @param zone: reference to Specified Zone ...
* @param dest: reference Collection to hold result ...
*
* @return ( int )
*/
int GetInsideBars(
XBoxZone &zone,
XOHCL &dest[] //
)
{
//
int result = 0;
//
// Validate ...
bool has = zone.IsValid();
if (!has)
{
return result;
}
//
// Prepare ...
SpecifiedClean(dest);
//
// Do Action ...
XOHCL iBar;
int start = zone.ToIndex();
int end = zone.FromIndex();
for (int i = start; i < end; i++)
{
//
// Initialize indexed Bar ...
has = iBar.Init(
zone.symbol,
zone.period,
i //
);
if (!has)
{
continue;
}
//
has = IsInside(
iBar,
zone //
);
if (has)
{
//
AddIfNotExists(
iBar,
dest //
);
}
//
iBar.Clean();
}
//
result = ArraySize(dest);
//
iBar.Clean();
//
return result;
}
/**
* Collect all Bars which Tested Specified Zone ...
*
* @param zone: reference to Specified Zone ...
* @param dest: reference Collection to hold result ...
*
* @return ( int )
*/
int GetTesterBars(
XBoxZone &zone,
XOHCL &dest[] //
)
{
//
int result = 0;
//
// Validate ...
bool has = zone.IsValid();
if (!has)
{
return result;
}
//
// Prepare ...
SpecifiedClean(dest);
//
// Do Action ...
XOHCL iBar;
int start = zone.ToIndex();
int end = zone.FromIndex();
for (int i = start; i < end; i++)
{
//
// Initialize indexed Bar ...
has = iBar.Init(
zone.symbol,
zone.period,
i //
);
if (!has)
{
continue;
}
//
has = IsTested(
iBar,
zone //
);
if (has)
{
//
AddIfNotExists(
iBar,
dest //
);
}
//
iBar.Clean();
}
//
result = ArraySize(dest);
//
iBar.Clean();
//
return result;
}
/**
* Validate Zones Range ...
*
* @param source: XBoxZone, collection reference to Validate ...
* @param minAllowedRange: double, min allowed range to Validate ...
*
* @return ( int )
*/
int ValidateZonesRange(
XBoxZone &source[],
double minAllowedRange //
)
{
//
int result = 0;
//
// Validate ...
bool has = HasChild(source) &&
minAllowedRange > 0;
if (!has)
{
return result;
}
//
XBoxZone iTMP;
XBoxZone tmps[];
Copy(source, tmps);
XClean(source);
while (HasChild(tmps))
{
//
iTMP.Clean();
iTMP = tmps[0];
ArrayRemove(tmps, 0, 1);
//
// Check Range Validation ...
has = iTMP.GetRange() > minAllowedRange;
if (has)
{
AddIfNotExists(iTMP, source);
}
}
//
result = ArraySize(source);
//
// Cleanup ...
XClean(tmps);
iTMP.Clean();
//
return result;
}
/**
* Remove Breaked Zones ...
*
* @param source: XBoxZone, collection reference to Remove Breaked Zones ...
* @param priceType: ENUM_X_PRICE, Specified Price type of Break Detection ...
*
* @return ( int )
*/
int RemoveBreakedZones(
XBoxZone &source[],
ENUM_X_PRICE priceType = X_PRICE_CLOSE //
)
{
//
int result = 0;
//
// Validate ...
if (!HasChild(source) || !IsXValid(priceType))
{
return result;
}
//
XBoxZone tmp[];
Copy(source, tmp);
XClean(source);
XBoxZone iTMP;
bool isBreaked = false;
while (HasChild(tmp))
{
//
iTMP.Clean();
iTMP = tmp[0];
ArrayRemove(tmp, 0, 1);
//
isBreaked = IsBreaked(iTMP, priceType);
if (!isBreaked)
{
//
AddIfNotExists(iTMP, source);
}
}
//
result = ArraySize(source);
//
// Cleanup ...
XClean(tmp);
iTMP.Clean();
//
return result;
}
// #endregion
//+------------------------------------------------------------------+
// #region Bar Extensions ...
/**
* Check Specified Bar is Breaked or not ...
*
* @param bar: XOHCL, Specified Bar for Checking Proce ...
* @param breakerBar: XOHCL, Hold's Breaker Bar if Exists ...
* @param barIndex: int, Start Checking Bar till Bar's Index ...
* @param breakDir: ENUM_X_DIRECTION, Checking Direction Type, if Bullish Break Price must bigger, otherwise must lower ...
* @param barPriceType: ENUM_X_PRICE, Price type to Check Break ...
* @param breakPriceType: ENUM_X_PRICE, Price Type to Break Bar's Price ...
*
* @return ( bool )
*/
bool IsBarBreaked(
XOHCL &bar,
XOHCL &breakerBar,
int barIndex = 0,
ENUM_X_DIRECTION breakDir = X_DIRECTION_NONE,
ENUM_X_PRICE barPriceType = X_PRICE_CLOSE,
ENUM_X_PRICE breakPriceType = X_PRICE_CLOSE //
)
{
//
bool result = false;
//
// Normalize ...
breakerBar.Clean();
if (barIndex < 0)
{
barIndex = 0;
}
//
// Validate ...
result =
bar.IsValid() &&
HasDirection(breakDir) &&
IsXValid(barPriceType) &&
IsXValid(breakPriceType) &&
barIndex < bar.Index();
if (!result)
{
return result;
}
//
// Loop for Validating ...
XOHCL tmpBar;
bool has = false;
double tmpPrice = EMPTY_VALUE;
double barPrice = bar.GetPrice(barPriceType);
for (int i = barIndex; i < bar.Index(); i++)
{
//
has = tmpBar.Init(bar.symbol, bar.period, i);
if (!has)
{
continue;
}
//
tmpPrice = tmpBar.GetPrice(breakPriceType);
has = NotEmptyZero(tmpPrice);
if (!has)
{
//
tmpBar.Clean();
//
continue;
}
//
has =
IsXBullish(breakDir)
? tmpPrice > barPrice
: tmpPrice < barPrice;
if (has)
{
//
breakerBar = tmpBar;
tmpBar.Clean();
break;
}
//
tmpBar.Clean();
}
//
result = breakerBar.IsValid();
//
return result;
}
// #endregion
//