last ...
This commit is contained in:
@@ -110,6 +110,12 @@ class XCXCATBEASignaller : XCBase
|
|||||||
//
|
//
|
||||||
// Props ...
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signalling Methods ...
|
||||||
|
bool allowSignallingBasedOnConditions; // Signalling and Entry based on Market Conditions ...
|
||||||
|
bool allowSignallingBasedOnTriggerBlocks; // Signalling Based on Trigger Block Detection ...
|
||||||
|
bool allowSignallingBasedOnTriggerBlocksInsideOther; // Signalling based on Trigger Blocks inside other Trigger Blocks ...
|
||||||
|
|
||||||
//
|
//
|
||||||
bool allowDraws; // Allow Draws or not ...
|
bool allowDraws; // Allow Draws or not ...
|
||||||
bool allowGuards; // Allow Guards or not ...
|
bool allowGuards; // Allow Guards or not ...
|
||||||
@@ -126,7 +132,12 @@ class XCXCATBEASignaller : XCBase
|
|||||||
XTriggerBlockValidationRules validations; // Trigger Block Validations ...
|
XTriggerBlockValidationRules validations; // Trigger Block Validations ...
|
||||||
|
|
||||||
//
|
//
|
||||||
|
XBoxZone cPeak; // Current Peak ...
|
||||||
|
XBoxZone cVale; // Current Vale ...
|
||||||
XBoxZone unavailableZones[]; // Un Available Zones ...
|
XBoxZone unavailableZones[]; // Un Available Zones ...
|
||||||
|
XTriggerBlock cTriggerBlock; // Currently Selected Trigger Block ...
|
||||||
|
XTriggerBlock triggerBlocks[]; // Founded Trigger Blocks ...
|
||||||
|
XTriggerBlock cInsideTriggerBlock; // a TriggerBlock which Currently Selected Trigger Block is Inside it ...
|
||||||
|
|
||||||
//
|
//
|
||||||
XCATBEAStrategyConditions mConditions;
|
XCATBEAStrategyConditions mConditions;
|
||||||
@@ -195,6 +206,8 @@ class XCXCATBEASignaller : XCBase
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
bool has = false;
|
bool has = false;
|
||||||
int barIndex = 0;
|
int barIndex = 0;
|
||||||
|
cTriggerBlock.Clean();
|
||||||
|
cInsideTriggerBlock.Clean();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check Guards ...
|
// Check Guards ...
|
||||||
@@ -320,6 +333,42 @@ class XCXCATBEASignaller : XCBase
|
|||||||
drawer.Draw(bar.time);
|
drawer.Draw(bar.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Trigger Blocks and Collect them ...
|
||||||
|
XTriggerBlock iTriggerBlock;
|
||||||
|
X121XCatbConditions iConditions;
|
||||||
|
has = DetectTriggerBlock(
|
||||||
|
helper,
|
||||||
|
barAnalyser,
|
||||||
|
iTriggerBlock,
|
||||||
|
iConditions,
|
||||||
|
validations,
|
||||||
|
filters,
|
||||||
|
barIndex,
|
||||||
|
10 // Loopback ...
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Add Trigger Block to Collection if not Exists ...
|
||||||
|
AddIfNotExists(
|
||||||
|
iTriggerBlock,
|
||||||
|
triggerBlocks //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
iConditions.Clean();
|
||||||
|
iTriggerBlock.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Trigger Blocks ...
|
||||||
|
if (allowDraws)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Handle To Updating ...
|
||||||
|
// datetime cTime = TimeCurrent();
|
||||||
|
// DrawTriggerBlocks(cTime);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Here we Check Active Session ...
|
// Here we Check Active Session ...
|
||||||
// and Prevent Moving forward if there is not
|
// and Prevent Moving forward if there is not
|
||||||
@@ -372,7 +421,34 @@ class XCXCATBEASignaller : XCBase
|
|||||||
helper.Update(barIndex);
|
helper.Update(barIndex);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Trigger Block Detection ...
|
// Detect Signal Setup Based on Market Conditions ...
|
||||||
|
if (!result &&
|
||||||
|
allowSignallingBasedOnConditions)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Detect Signalling Zone ...
|
||||||
|
result = DetectSignalZone(
|
||||||
|
helper,
|
||||||
|
barAnalyser,
|
||||||
|
mConditions.conditions,
|
||||||
|
mConditions.pivotZone,
|
||||||
|
barIndex,
|
||||||
|
10 // Loopback ...
|
||||||
|
);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Filling Conditions of Strategy ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Signal Setup Based on Trigger Block Detection ...
|
||||||
|
if (!result &&
|
||||||
|
allowSignallingBasedOnTriggerBlocks)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Detect Trigger Block ...
|
||||||
result = DetectTriggerBlock(
|
result = DetectTriggerBlock(
|
||||||
helper,
|
helper,
|
||||||
barAnalyser,
|
barAnalyser,
|
||||||
@@ -385,6 +461,10 @@ class XCXCATBEASignaller : XCBase
|
|||||||
);
|
);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// Use Trigger Block ...
|
||||||
|
UseTriggerBlock(mConditions.triggerBlock);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare Condition ...
|
// Prepare Condition ...
|
||||||
|
|
||||||
@@ -457,8 +537,158 @@ class XCXCATBEASignaller : XCBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Detect Signal Setup Based On Trigger Blocks Second Entry ...
|
||||||
|
if (!result &&
|
||||||
|
allowSignallingBasedOnTriggerBlocksInsideOther)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// First We Hvae to Select Peak and Vale ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Peak and Vale Exists ...
|
||||||
|
int peakIDX = GetYoungest(detector.peakPivots);
|
||||||
|
int valeIDX = GetYoungest(detector.valePivots);
|
||||||
|
result = IsValidIndex(peakIDX) &&
|
||||||
|
IsValidIndex(valeIDX);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cPeak = detector.peakPivots[peakIDX];
|
||||||
|
cVale = detector.valePivots[valeIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trigger Block Detection ...
|
||||||
|
result = HasChild(triggerBlocks) &&
|
||||||
|
ArraySize(triggerBlocks) > 1;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check Newest Trigger Block ...
|
||||||
|
int newestIDX = GetYoungest(triggerBlocks);
|
||||||
|
result = IsValidIndex(newestIDX);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cTriggerBlock = triggerBlocks[newestIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Trigger Block is New ...
|
||||||
|
int toIDX = cTriggerBlock.ToIndex() == 0;
|
||||||
|
bool isNewest = toIDX == 0;
|
||||||
|
if (isNewest)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Now we have to Check Newest Trigger Block Place ...
|
||||||
|
int insideTBIDX = DetectInsideTriggerBlock(
|
||||||
|
cTriggerBlock,
|
||||||
|
cInsideTriggerBlock,
|
||||||
|
triggerBlocks //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check InsideTB is Exists and Valid ...
|
||||||
|
result =
|
||||||
|
cInsideTriggerBlock.IsValid() &&
|
||||||
|
IsValidIndex(insideTBIDX);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Remove Peak from Detector Collections ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
ArrayRemove(
|
||||||
|
detector.peakPivots,
|
||||||
|
peakIDX,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
AddRef(
|
||||||
|
cPeak,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Vale from Detector Collections ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
ArrayRemove(
|
||||||
|
detector.peakPivots,
|
||||||
|
peakIDX,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
AddRef(
|
||||||
|
cVale,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Selected Trigger Block ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
RemoveTriggerBlock(
|
||||||
|
cTriggerBlock,
|
||||||
|
triggerBlocks //
|
||||||
|
);
|
||||||
|
UseTriggerBlock(cTriggerBlock);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Selected Inside Trigger Block ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
RemoveTriggerBlock(
|
||||||
|
cInsideTriggerBlock,
|
||||||
|
triggerBlocks //
|
||||||
|
);
|
||||||
|
UseTriggerBlock(cInsideTriggerBlock);
|
||||||
|
|
||||||
|
//
|
||||||
|
CleanupArray(
|
||||||
|
unavailableZones,
|
||||||
|
maxAllowedCollection //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Trigger Blocks if Allowed ...
|
||||||
|
if (allowDraws)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Draw Blocks ...
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
|
||||||
|
//
|
||||||
|
// mObjects.Clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detected Block ...
|
||||||
|
DrawTriggerBlock(
|
||||||
|
cTriggerBlock,
|
||||||
|
drawer.drawer,
|
||||||
|
mObjects,
|
||||||
|
cTime,
|
||||||
|
false // Draw Signal ...
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inside Block ...
|
||||||
|
DrawTriggerBlock(
|
||||||
|
cInsideTriggerBlock,
|
||||||
|
drawer.drawer,
|
||||||
|
mObjects,
|
||||||
|
cTime,
|
||||||
|
false // Draw Signal ...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Print("Salam ...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check a Signal Setup Exists or not ...
|
||||||
result = mConditions.IsValid() &&
|
result = mConditions.IsValid() &&
|
||||||
mConditions.IsSetuped();
|
mConditions.IsSetuped();
|
||||||
|
|
||||||
@@ -617,6 +847,14 @@ class XCXCATBEASignaller : XCBase
|
|||||||
*/
|
*/
|
||||||
void Init(XCATBEASignallerInputs &inputs)
|
void Init(XCATBEASignallerInputs &inputs)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
maxAllowedCollection = 50;
|
||||||
|
|
||||||
|
//
|
||||||
|
allowSignallingBasedOnConditions = false;
|
||||||
|
allowSignallingBasedOnTriggerBlocks = true;
|
||||||
|
allowSignallingBasedOnTriggerBlocksInsideOther = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
bool has = inputs.IsValid();
|
bool has = inputs.IsValid();
|
||||||
if (!has)
|
if (!has)
|
||||||
@@ -714,12 +952,16 @@ class XCXCATBEASignaller : XCBase
|
|||||||
* @return ( int )
|
* @return ( int )
|
||||||
*/
|
*/
|
||||||
int AddConditionsIfNotExists(
|
int AddConditionsIfNotExists(
|
||||||
int maxAllowed = 10 //
|
int maxAllowed = 50 //
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Args ...
|
||||||
|
maxAllowed = maxAllowedCollection;
|
||||||
|
|
||||||
//
|
//
|
||||||
bool isSetuped = IsValid(mConditions.setupTime) &&
|
bool isSetuped = IsValid(mConditions.setupTime) &&
|
||||||
HasDirection(mConditions.dir);
|
HasDirection(mConditions.dir);
|
||||||
@@ -788,6 +1030,178 @@ class XCXCATBEASignaller : XCBase
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add TriggerBlock if not Exists
|
||||||
|
* inside a Collection ...
|
||||||
|
*/
|
||||||
|
int AddIfNotExists(
|
||||||
|
XTriggerBlock &tb,
|
||||||
|
XTriggerBlock &tbs[],
|
||||||
|
int maxAllowed = 50 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Args ...
|
||||||
|
maxAllowed = maxAllowedCollection;
|
||||||
|
|
||||||
|
//
|
||||||
|
// First Validate ...
|
||||||
|
if (!tb.IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Exists ...
|
||||||
|
// and prevent moving forward if exists ...
|
||||||
|
int idx = -1;
|
||||||
|
bool isExists = FindTriggerBlockIndex(
|
||||||
|
idx,
|
||||||
|
tb,
|
||||||
|
tbs //
|
||||||
|
);
|
||||||
|
result = !isExists;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add if not Exists ...
|
||||||
|
AddRef(
|
||||||
|
tb,
|
||||||
|
tbs //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup ...
|
||||||
|
CleanupArray(
|
||||||
|
tbs,
|
||||||
|
maxAllowed //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(tbs);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use Specified Trigger Block and Make it Un Available ...
|
||||||
|
*
|
||||||
|
* @param tb: XTriggerBlock instance reference, Specified Used Trigger Block ...
|
||||||
|
*/
|
||||||
|
void UseTriggerBlock(XTriggerBlock &tb)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = tb.IsValid();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trigger Box ...
|
||||||
|
has = tb.trigger.IsValid();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
tb.trigger,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Order Block Box ...
|
||||||
|
has = tb.ob.IsValid();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
tb.ob,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fair Value Gap ...
|
||||||
|
has = tb.fvg.IsValid();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
tb.fvg,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Following Liquidity ...
|
||||||
|
has = tb.fLiquidity.IsValid();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
tb.fLiquidity,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reversal Liquidity ...
|
||||||
|
has = tb.rLiquidity.IsValid();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
tb.rLiquidity,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleaning Up ...
|
||||||
|
CleanupArray(
|
||||||
|
unavailableZones,
|
||||||
|
maxAllowedCollection //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw Exists Trigger Blocks ...
|
||||||
|
*/
|
||||||
|
void DrawTriggerBlocks(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check Has Child of trigger Blocks ...
|
||||||
|
bool has = HasChild(triggerBlocks);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Loop through Blocks ...
|
||||||
|
int count = ArraySize(triggerBlocks);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Draw Indexed Trigger Block ...
|
||||||
|
DrawTriggerBlock(
|
||||||
|
triggerBlocks[i],
|
||||||
|
drawer.drawer,
|
||||||
|
mObjects,
|
||||||
|
to,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Private ...
|
// Private ...
|
||||||
private:
|
private:
|
||||||
@@ -797,6 +1211,7 @@ class XCXCATBEASignaller : XCBase
|
|||||||
string provider;
|
string provider;
|
||||||
CArrayObj *mObjects;
|
CArrayObj *mObjects;
|
||||||
ENUM_TIMEFRAMES period;
|
ENUM_TIMEFRAMES period;
|
||||||
|
int maxAllowedCollection; // Max Allowed Collection Items ...
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize and Configure POI Detector and Drawer ...
|
// Initialize and Configure POI Detector and Drawer ...
|
||||||
|
|||||||
@@ -303,6 +303,346 @@ struct XTriggerBlockFilters
|
|||||||
//
|
//
|
||||||
// Extensions ...
|
// 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 ...
|
* Detect Trigger Block ...
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
Reference in New Issue
Block a user