Files
MQL5Data/Libraries/x-saherelm.x-poi.extensions.lib.mq5
T
2025-09-25 18:36:56 +03:30

3265 lines
56 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 GetOldestBar(
XOHCL &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
!selected.IsValid()
? true
: selected.time > source[i].time;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* 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 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 GetYoungestBar(
XOHCL &source[] //
)
{
//
int result = -1;
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
for (int i = 0; i < count; i++)
{
//
bool canSet =
!selected.IsValid()
? true
: selected.time < source[i].time;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* 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 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 ...
* @param _priceType: Specified Price type ...
*
* @return ( int )
*/
int GetHighestBar(
XOHCL &source[],
ENUM_X_PRICE _priceType = X_PRICE_HIGH //
)
{
//
int result = -1;
//
if (!IsXValid(_priceType))
{
_priceType = X_PRICE_HIGH;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
double iPrice = EMPTY_VALUE;
double selectedPrice = EMPTY_VALUE;
for (int i = 0; i < count; i++)
{
//
iPrice = source[i].GetPrice(_priceType);
selectedPrice = selected.GetPrice(_priceType);
//
bool canSet =
!selected.IsValid()
? true
: selectedPrice < iPrice;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* 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 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 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 GetLowestBar(
XOHCL &source[],
ENUM_X_PRICE _priceType = X_PRICE_LOW //
)
{
//
int result = -1;
//
if (!IsXValid(_priceType))
{
_priceType = X_PRICE_LOW;
}
//
int count = ArraySize(source);
if (!IsValidSize(count))
{
return result;
}
//
XOHCL selected;
double iPrice = EMPTY_VALUE;
double selectedPrice = EMPTY_VALUE;
for (int i = 0; i < count; i++)
{
//
iPrice = source[i].GetPrice(_priceType);
selectedPrice = selected.GetPrice(_priceType);
//
bool canSet =
!selected.IsValid()
? true
: selectedPrice > iPrice;
if (canSet)
{
//
result = i;
selected = source[i];
}
}
//
selected.Clean();
//
return result;
}
/**
* 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 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 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 |
//+------------------------------------------------------------------+
int GetOldestBefore(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
IsSpecifiedValid(_time);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].from < _time;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetOldest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
return result;
}
int GetOldestAfter(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
IsSpecifiedValid(_time);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].from > _time;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetOldest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
return result;
}
int GetYoungestBefore(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
IsSpecifiedValid(_time);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].from < _time;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetYoungest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
return result;
}
int GetYoungestAfter(
datetime _time,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
IsSpecifiedValid(_time);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].from > _time;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetYoungest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
return result;
}
int GetHighestAbove(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
NotEmptyZero(_value);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].upper > _value;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetHighest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
return result;
}
int GetHighestBelow(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
NotEmptyZero(_value);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].upper < _value;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetHighest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
return result;
}
int GetLowestAbove(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
NotEmptyZero(_value);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].lower > _value;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetLowest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
return result;
}
int GetLowestBelow(
double _value,
XBoxZone &source[] //
)
{
//
int result = -1;
//
// Validate ...
bool has =
HasChild(source) &&
NotEmptyZero(_value);
if (!has)
{
return result;
}
//
int idx = -1;
XBoxZone tmps[];
int count = ArraySize(source);
for (int i = 0; i < count; i++)
{
//
has = source[i].lower < _value;
if (has)
{
//
AddIfNotExists(
source[i],
tmps //
);
}
}
has = HasChild(tmps);
if (!has)
{
//
result = -1;
return result;
}
//
idx = GetLowest(tmps);
has =
IsValidIndex(idx) &&
FindIndex(
result,
tmps[idx],
source //
);
//
// Cleanup Resources ...
SpecifiedClean(tmps);
//
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 = GetOldestBar(source);
}
//
// form Youngest to Oldest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetYoungestBar(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 = GetLowestBar(source, priceType);
}
//
// form Highest to Lowest ...
else if (sortDir == X_DIRECTION_BEARISH)
{
result = GetHighestBar(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_BULLISH,
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 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;
}
//+------------------------------------------------------------------+
//
//
//
//+------------------------------------------------------------------+
//| 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;
}
//
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 //
);
}
}
//
}
/**
* 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 //
)
{
//
bool result = false;
//
box.Clean();
toTime = NormalizeTime(toTime);
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
box.to = toTime;
box.from = bar.time;
box.lower = bar.low;
box.symbol = bar.symbol;
box.period = bar.period;
box.upper = bar.GetDown();
box.dir = X_DIRECTION_BULLISH;
box.type = "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 //
)
{
//
bool result = false;
//
box.Clean();
toTime = NormalizeTime(toTime);
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
box.to = toTime;
box.from = bar.time;
box.upper = bar.high;
box.symbol = bar.symbol;
box.period = bar.period;
box.lower = bar.GetUp();
box.dir = X_DIRECTION_BEARISH;
box.type = "Resistance";
//
result = box.IsValid();
if (!result)
{
box.Clean();
}
//
return result;
}
//+------------------------------------------------------------------+
//