This commit is contained in:
2025-06-02 03:41:33 +03:30
parent aca304dc6f
commit 2f0efd0285
3 changed files with 883 additions and 76 deletions
+340
View File
@@ -303,6 +303,346 @@ struct XTriggerBlockFilters
//
// Extensions ...
/**
* Get Newest Trigger Block Index inside a Collection ...
*
* @return ( int )
*/
int GetYoungest(XTriggerBlock &tbs[])
{
//
int result = -1;
//
// Checking Collection Has Childs ...
if (!HasChild(tbs))
{
return result;
}
//
datetime selected = NULL;
int count = ArraySize(tbs);
for (int i = 0; i < count; i++)
{
//
bool canSelect =
!IsValid(selected)
? true
: tbs[i].trigger.from > selected;
if (canSelect)
{
//
result = i;
selected = tbs[i].trigger.from;
}
}
//
return result;
}
/**
* Get Oldest Trigger Block Index inside a Collection ...
*
* @return ( int )
*/
int GetOldest(XTriggerBlock &tbs[])
{
//
int result = -1;
//
// Checking Collection Has Childs ...
if (!HasChild(tbs))
{
return result;
}
//
datetime selected = NULL;
int count = ArraySize(tbs);
for (int i = 0; i < count; i++)
{
//
bool canSelect =
!IsValid(selected)
? true
: tbs[i].trigger.from < selected;
if (canSelect)
{
//
result = i;
selected = tbs[i].trigger.from;
}
}
//
return result;
}
/**
* Get Highest Trigger Block Index inside a Collection ...
*
* @return ( int )
*/
int GetHighest(XTriggerBlock &tbs[])
{
//
int result = -1;
//
// Checking Collection Has Childs ...
if (!HasChild(tbs))
{
return result;
}
//
double selected = 0;
int count = ArraySize(tbs);
for (int i = 0; i < count; i++)
{
//
bool canSelect =
selected <= 0
? true
: tbs[i].trigger.lower > selected;
if (canSelect)
{
//
result = i;
selected = tbs[i].trigger.lower;
}
}
//
return result;
}
/**
* Get Lowest Trigger Block Index inside a Collection ...
*
* @return ( int )
*/
int GetLowest(XTriggerBlock &tbs[])
{
//
int result = -1;
//
// Checking Collection Has Childs ...
if (!HasChild(tbs))
{
return result;
}
//
double selected = 0;
int count = ArraySize(tbs);
for (int i = 0; i < count; i++)
{
//
bool canSelect =
selected <= 0
? true
: tbs[i].trigger.upper < selected;
if (canSelect)
{
//
result = i;
selected = tbs[i].trigger.upper;
}
}
//
return result;
}
/**
* Find Trigger Block Index inside a Colletion ...
*/
bool FindTriggerBlockIndex(
int &index,
XTriggerBlock &tb,
XTriggerBlock &tbs[] //
)
{
//
bool result = false;
//
index = -1;
//
result = tb.IsValid();
if (!result)
{
return result;
}
//
bool isExists = false;
bool has = HasChild(tbs);
if (has)
{
//
int count = ArraySize(tbs);
for (int i = 0; i < count; i++)
{
//
isExists = tb.trigger.IsSameAs(tbs[i].trigger);
if (isExists)
{
//
index = i;
break;
}
}
}
//
result =
isExists &&
IsValidIndex(index);
//
return result;
}
/**
* Remove Specified Trigger Block from a Collection, if Exists ...
*
* @param tb: XTriggerBlock instance reference, Specified Trigger Block for Checking ...
* @param tbs: XTriggerBlock instance reference Array, Collection of Trigger Blocks ...
*
* @return ( bool )
*/
bool RemoveTriggerBlock(
XTriggerBlock &tb,
XTriggerBlock &tbs[] //
)
{
//
bool result = false;
//
// Validate Args ...
result = tb.IsValid() &&
HasChild(tbs);
if (!result)
{
return result;
}
//
int idx = -1;
result = FindTriggerBlockIndex(
idx,
tb,
tbs //
);
if (!result)
{
return result;
}
//
result = ArrayRemove(
tbs,
idx,
1 //
);
//
return result;
}
/**
* Detect a TriggerBlock which Specified TriggerBlock is Inside of it ...
*
* @param tb: XTriggerBlock instance reference, Specified Trigger Block for Checking ...
* @param insideTB: XTriggerBlock instance reference, Holds founded inside Trigger Block ...
* @param tbs: XTriggerBlock instance collection, Specified Collection for Checking ...
* @param minimumLengthBetweenTBs: int, Minimum Bars between two Trigger Blocks ...
*
* @return ( int ) founded Inside TriggerBlock index ...
*/
int DetectInsideTriggerBlock(
XTriggerBlock &tb,
XTriggerBlock &insideTB,
XTriggerBlock &tbs[],
int minimumLengthBetweenTBs = 5 //
)
{
//
int result = -1;
//
// Normalize Args ...
minimumLengthBetweenTBs = NormalizeInt(minimumLengthBetweenTBs, 3);
//
// Check Collection has Childs ...
bool has = HasChild(tbs);
if (!has)
{
return result;
}
//
insideTB.Clean();
bool isBullish = tb.IsBullish();
bool isBearish = tb.IsBearish();
//
int count = ArraySize(tbs);
for (int i = 0; i < count; i++)
{
//
// Check Trigger Block Conditions ...
bool isInside =
//
// Check Not Same ...
!tb.trigger.IsSameAs(tbs[i].trigger) &&
//
// Check Direction ...
tb.trigger.dir == tbs[i].trigger.dir &&
//
// Check Length of TBS ...
(minimumLengthBetweenTBs <= 0
? true
: tb.trigger.FromIndex() + minimumLengthBetweenTBs <= tbs[i].trigger.FromIndex()) &&
//
// Check Inside it ...
(isBullish
? (tb.trigger.lower < tbs[i].trigger.upper &&
tb.trigger.lower > tbs[i].trigger.lower &&
tb.trigger.lower < tbs[i].trigger.GetMid())
: (tb.trigger.upper > tbs[i].trigger.lower &&
tb.trigger.upper < tbs[i].trigger.upper &&
tb.trigger.upper > tbs[i].trigger.GetMid())) &&
//
// Check Last ...
(!insideTB.IsValid()
? true
: isBullish
? insideTB.trigger.upper > tbs[i].trigger.upper
: insideTB.trigger.lower < tbs[i].trigger.lower)
//
;
if (isInside)
{
//
result = i;
insideTB = tbs[i];
}
}
//
return result;
}
/**
* Detect Trigger Block ...
*
+55 -3
View File
@@ -275,12 +275,64 @@ struct XCATBEAStrategyConditions
//
};
//
bool DetectSignalZone()
/**
* Detect Signal Zone based on Market Conditions ...
*
* @param helper: XCX121XCatbHelper instance pointer ...
* @param barAnalyser: XCBarAnalyser instance pointer ...
* @param conditions: X121XCatbConditions instance reference, hold signalling Conditions ...
* @param signalZone: XBoxZone instance reference, hold Signal Zone ...
* @param barIndex: int, Bar Index ...
* @param loopback: int, Loopback for Market Conditions ...
*
* @return ( bool )
*/
bool DetectSignalZone(
XCX121XCatbHelper *helper,
XCBarAnalyser *barAnalyser,
X121XCatbConditions &conditions,
XBoxZone &signalZone,
int barIndex = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
// Normalize Args ...
signalZone.Clean();
conditions.Clean();
loopback = NormalizeInt(loopback, 0);
barIndex = NormalizeInt(barIndex, 0);
//
// Validate Args ...
result =
helper != NULL &&
barAnalyser != NULL;
if (!result)
{
return result;
}
//
// Validate Result ...
result = signalZone.IsValid();
//
// Cleanup Resources ...
//
if (!result)
{
//
signalZone.Clean();
conditions.Clean();
}
//
return result;
}
}
//