1271 lines
19 KiB
Plaintext
1271 lines
19 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Seriallize Library
|
|
// ---------------------------------------
|
|
// Name: XPOILib
|
|
// Description: All models related to POIs ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright `023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../Libraries/x-saherelm.x-poi.lib.mq5"
|
|
|
|
//
|
|
// Extensions ...
|
|
|
|
/**
|
|
* Get Oldest Box Index ...
|
|
*
|
|
* @param source: XBoxZone instance Reference 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++)
|
|
{
|
|
//
|
|
XBoxZone iBox = source[i];
|
|
|
|
//
|
|
bool canSet =
|
|
!selected.IsValid()
|
|
? true
|
|
: selected.from > iBox.from;
|
|
if (canSet)
|
|
{
|
|
//
|
|
result = i;
|
|
selected = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
selected.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
int GetOldest(
|
|
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.from > iBox.from;
|
|
if (canSet)
|
|
{
|
|
//
|
|
result = i;
|
|
selected = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
selected.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Youngest Box Index ...
|
|
*
|
|
* @param source: XBoxZone instance Reference 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++)
|
|
{
|
|
//
|
|
XBoxZone iBox = source[i];
|
|
|
|
//
|
|
bool canSet =
|
|
!selected.IsValid()
|
|
? true
|
|
: selected.from < iBox.from;
|
|
if (canSet)
|
|
{
|
|
//
|
|
result = i;
|
|
selected = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
selected.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
int GetYoungest(
|
|
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.from < iBox.from;
|
|
if (canSet)
|
|
{
|
|
//
|
|
result = i;
|
|
selected = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
selected.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Highest Box Index ...
|
|
*
|
|
* @param source: XBoxZone instance Reference 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++)
|
|
{
|
|
//
|
|
XBoxZone iBox = source[i];
|
|
|
|
//
|
|
bool canSet =
|
|
!selected.IsValid()
|
|
? true
|
|
: selected.upper < iBox.upper;
|
|
if (canSet)
|
|
{
|
|
//
|
|
result = i;
|
|
selected = iBox;
|
|
}
|
|
|
|
//
|
|
iBox.Clean();
|
|
}
|
|
|
|
//
|
|
selected.Clean();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
int GetHighest(
|
|
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 Lowest Box Index ...
|
|
*
|
|
* @param source: XBoxZone instance Reference 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;
|
|
}
|
|
int GetLowest(
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Find Specified Box Index inside a Collection of Boxes ...
|
|
*
|
|
* @param box: XBoxZone instance Reference ...
|
|
* @param boxes: XBoxZone instance Reference Collection ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
bool FindIndex(
|
|
int &index,
|
|
XBoxZone &item,
|
|
XBoxZone &items[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
result = item.IsValid() &&
|
|
IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XBoxZone iBox = items[i];
|
|
|
|
//
|
|
bool isSame = item.IsSameAs(iBox);
|
|
if (isSame)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
bool FindIndex(
|
|
int &index,
|
|
XDirectionShift &item,
|
|
XDirectionShift &items[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
index = -1;
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
result = item.IsValid() &&
|
|
IsValidSize(count);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XDirectionShift iItem = items[i];
|
|
|
|
//
|
|
bool isSame = item.IsSameAs(iItem);
|
|
if (isSame)
|
|
{
|
|
//
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
result = IsValidIndex(index);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Remove Specified Box from Collection ...
|
|
*/
|
|
bool Remove(
|
|
XBoxZone &item,
|
|
XBoxZone &items[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
item.IsValid() &&
|
|
HasChild(items);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
result = FindIndex(
|
|
idx,
|
|
item,
|
|
items //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArrayRemove(
|
|
items,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
bool Remove(
|
|
XDirectionShift &item,
|
|
XDirectionShift &items[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
result =
|
|
item.IsValid() &&
|
|
HasChild(items);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int idx = -1;
|
|
result = FindIndex(
|
|
idx,
|
|
item,
|
|
items //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = ArrayRemove(
|
|
items,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Remove Specified Box from Collection ...
|
|
*/
|
|
int Removes(
|
|
XBoxZone &items[],
|
|
XBoxZone &sources[] //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool has = HasChild(items) &&
|
|
HasChild(sources);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
int idx = -1;
|
|
has = FindIndex(
|
|
idx,
|
|
items[i],
|
|
sources //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
has = ArrayRemove(
|
|
sources,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
int Removes(
|
|
XDirectionShift &items[],
|
|
XDirectionShift &sources[] //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool has = HasChild(items) &&
|
|
HasChild(sources);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
int idx = -1;
|
|
has = FindIndex(
|
|
idx,
|
|
items[i],
|
|
sources //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
has = ArrayRemove(
|
|
sources,
|
|
idx,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
if (has)
|
|
{
|
|
result++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Add items reference into source Collection only if it's not Exists ...alignas
|
|
*
|
|
* @param item: XBoxZone instance Reference, Specified Item to Add ...
|
|
* @param sources: XBoxZone instance Reference Collection, Source Items Collection ...
|
|
* @param maxAllowed: int, Max Allowed Collection Size ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool AddIfNotExists(
|
|
XBoxZone &item,
|
|
XBoxZone &sources[],
|
|
int maxAllowed = 50 //
|
|
)
|
|
{
|
|
//
|
|
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 //;
|
|
);
|
|
|
|
//
|
|
if (result &&
|
|
maxAllowed > 0)
|
|
{
|
|
//
|
|
CleanupArray(
|
|
sources,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
bool AddIfNotExists(
|
|
XDirectionShift &item,
|
|
XDirectionShift &sources[],
|
|
int maxAllowed = 50 //
|
|
)
|
|
{
|
|
//
|
|
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 //;
|
|
);
|
|
|
|
//
|
|
if (result &&
|
|
maxAllowed > 0)
|
|
{
|
|
//
|
|
CleanupArray(
|
|
sources,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Add items Collection reference Members into source Collection only if it's not Exists ...alignas
|
|
*
|
|
* @param items: XBoxZone instance Reference Collection, Specified Items to Add ...
|
|
* @param sources: XBoxZone instance Reference Collection, Source Items Collection ...
|
|
* @param maxAllowed: int, Max Allowed Collection Size ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int AddIfNotExists(
|
|
XBoxZone &items[],
|
|
XBoxZone &sources[],
|
|
int maxAllowed = 50 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool has = HasChild(items);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int before = ArraySize(sources);
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
has = AddIfNotExists(
|
|
items[i],
|
|
sources //
|
|
);
|
|
}
|
|
|
|
//
|
|
int after = ArraySize(sources);
|
|
|
|
//
|
|
result = after > before;
|
|
if (result &&
|
|
maxAllowed > 0)
|
|
{
|
|
//
|
|
CleanupArray(
|
|
sources,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
int AddIfNotExists(
|
|
XDirectionShift &items[],
|
|
XDirectionShift &sources[],
|
|
int maxAllowed = 50 //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
bool has = HasChild(items);
|
|
if (!has)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int before = ArraySize(sources);
|
|
|
|
//
|
|
int count = ArraySize(items);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
has = AddIfNotExists(
|
|
items[i],
|
|
sources //
|
|
);
|
|
}
|
|
|
|
//
|
|
int after = ArraySize(sources);
|
|
|
|
//
|
|
result = after > before;
|
|
if (result &&
|
|
maxAllowed > 0)
|
|
{
|
|
//
|
|
CleanupArray(
|
|
sources,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
/**
|
|
* 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];
|
|
datetime to = GetBarTime(
|
|
iBox.symbol,
|
|
iBox.period,
|
|
barIndex //
|
|
);
|
|
|
|
//
|
|
// Remove Indexed Box ...
|
|
ArrayRemove(
|
|
tmp,
|
|
0,
|
|
1 //
|
|
);
|
|
|
|
//
|
|
// Check Box Validating ...
|
|
has = IsBoxValid(
|
|
iBox,
|
|
barIndex,
|
|
barsLength //
|
|
);
|
|
if (has)
|
|
{
|
|
//
|
|
iBox.to = to;
|
|
|
|
//
|
|
AddRef(
|
|
iBox,
|
|
boxes //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Sorting ...
|
|
if (forceSorting)
|
|
{
|
|
//
|
|
// Check Has Result or not ...
|
|
has = HasChild(boxes);
|
|
if (has)
|
|
{
|
|
//
|
|
// Sorting ...
|
|
SortBoxes(
|
|
boxes,
|
|
maxAllowed //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
}
|
|
|
|
// |