last ...
This commit is contained in:
@@ -1624,6 +1624,49 @@ bool HasInsideBox(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove Specified Box from Collection ...
|
||||||
|
*/
|
||||||
|
bool RemoveBox(
|
||||||
|
XBoxZone &box,
|
||||||
|
XBoxZone &boxes[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
box.IsValid() &&
|
||||||
|
HasChild(boxes);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
result = FindBoxIndex(
|
||||||
|
idx,
|
||||||
|
box,
|
||||||
|
boxes //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArrayRemove(
|
||||||
|
boxes,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts to XBoxZone ...
|
* Converts to XBoxZone ...
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1052,26 +1052,25 @@ class XCXCATBEAExpert : public XCBase
|
|||||||
XCATBEAStrategyConditions iConditions = conditions[i];
|
XCATBEAStrategyConditions iConditions = conditions[i];
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare Signal Based on Conditions ...
|
// Define Signal Structure ...
|
||||||
XSignal iSignal;
|
XSignal iSignal;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if a Trigger Block Attached and Has Signal ...
|
// Check Conditions is Valid Triggered Conditions ...
|
||||||
// use it ...
|
|
||||||
has =
|
has =
|
||||||
iConditions.IsValid() &&
|
iConditions.IsValid() &&
|
||||||
iConditions.IsSetuped() &&
|
iConditions.IsSetuped() &&
|
||||||
iConditions.CanTrigger() &&
|
iConditions.CanTrigger();
|
||||||
iConditions.triggerBlock.IsValid() &&
|
|
||||||
iConditions.triggerBlock.signal.IsValid();
|
|
||||||
if (has)
|
if (has)
|
||||||
{
|
{
|
||||||
iSignal = iConditions.triggerBlock.signal;
|
//
|
||||||
|
// Preparing Signal ...
|
||||||
|
has = ToSignal(
|
||||||
|
iSignal,
|
||||||
|
iConditions //
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// if we Have any other Signalling senarios we can Handle them here ...
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Validate Signal ...
|
// Validate Signal ...
|
||||||
has = iSignal.IsValid();
|
has = iSignal.IsValid();
|
||||||
|
|||||||
@@ -137,6 +137,8 @@ class XCXCATBEASignaller : XCBase
|
|||||||
XBoxZone unavailableZones[]; // Un Available Zones ...
|
XBoxZone unavailableZones[]; // Un Available Zones ...
|
||||||
XTriggerBlock cTriggerBlock; // Currently Selected Trigger Block ...
|
XTriggerBlock cTriggerBlock; // Currently Selected Trigger Block ...
|
||||||
XTriggerBlock triggerBlocks[]; // Founded Trigger Blocks ...
|
XTriggerBlock triggerBlocks[]; // Founded Trigger Blocks ...
|
||||||
|
bool waitsUntilPeakInvalidate; // Waits Until Peak Invalidate ...
|
||||||
|
bool waitsUntilValeInvalidate; // Waits Until Vale Invalidate ...
|
||||||
XTriggerBlock cInsideTriggerBlock; // a TriggerBlock which Currently Selected Trigger Block is Inside it ...
|
XTriggerBlock cInsideTriggerBlock; // a TriggerBlock which Currently Selected Trigger Block is Inside it ...
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -330,20 +332,22 @@ class XCXCATBEASignaller : XCBase
|
|||||||
// Draw POI(s) ...
|
// Draw POI(s) ...
|
||||||
if (allowDraws)
|
if (allowDraws)
|
||||||
{
|
{
|
||||||
drawer.Draw(bar.time);
|
// drawer.Draw(bar.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Detect Trigger Blocks and Collect them ...
|
// Detect Trigger Blocks and Collect them ...
|
||||||
XTriggerBlock iTriggerBlock;
|
XTriggerBlock iTriggerBlock;
|
||||||
X121XCatbConditions iConditions;
|
X121XCatbConditions iConditions;
|
||||||
|
XTriggerBlockFilters iFilters;
|
||||||
|
XTriggerBlockValidationRules iValidations;
|
||||||
has = DetectTriggerBlock(
|
has = DetectTriggerBlock(
|
||||||
helper,
|
helper,
|
||||||
barAnalyser,
|
barAnalyser,
|
||||||
iTriggerBlock,
|
iTriggerBlock,
|
||||||
iConditions,
|
iConditions,
|
||||||
validations,
|
iValidations,
|
||||||
filters,
|
iFilters,
|
||||||
barIndex,
|
barIndex,
|
||||||
10 // Loopback ...
|
10 // Loopback ...
|
||||||
);
|
);
|
||||||
@@ -420,6 +424,174 @@ class XCXCATBEASignaller : XCBase
|
|||||||
// Update All Required Buffers ...
|
// Update All Required Buffers ...
|
||||||
helper.Update(barIndex);
|
helper.Update(barIndex);
|
||||||
|
|
||||||
|
//
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
|
||||||
|
//
|
||||||
|
// cPeak and cVale ...
|
||||||
|
// these Helpes Us to Detect Price Levels ...
|
||||||
|
//
|
||||||
|
// Draw Peak and Vale if Exists ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Peak ...
|
||||||
|
if (cPeak.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cPeak.to = cTime;
|
||||||
|
drawer.DrawBox(cPeak);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Vale ...
|
||||||
|
if (cVale.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cVale.to = cTime;
|
||||||
|
drawer.DrawBox(cVale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to Validate cPeak an cVale if Exists ...
|
||||||
|
XOHCL zBar;
|
||||||
|
XOHCL cBar;
|
||||||
|
bool isInited = zBar.Init(
|
||||||
|
symbol,
|
||||||
|
period,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
isInited = zBar.GetPreviousBar(cBar);
|
||||||
|
isInited = helper.GetConditions(
|
||||||
|
mConditions.conditions,
|
||||||
|
barIndex,
|
||||||
|
10 //
|
||||||
|
);
|
||||||
|
if (isInited)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate cPeak and cVale if Exists ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// cPeak ...
|
||||||
|
if (cPeak.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
isInited = cBar.high < cPeak.lower;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cPeak.Clean();
|
||||||
|
cVale.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
waitsUntilPeakInvalidate = false;
|
||||||
|
waitsUntilValeInvalidate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// cVale ...
|
||||||
|
if (cVale.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
isInited = cBar.low > cVale.upper;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cPeak.Clean();
|
||||||
|
cVale.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
waitsUntilPeakInvalidate = false;
|
||||||
|
waitsUntilValeInvalidate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try To Detect Peak and Vale based on cBar ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selecting Peak ...
|
||||||
|
if (!cPeak.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone tmpPeaks[];
|
||||||
|
detector.FillPeakPivots(tmpPeaks);
|
||||||
|
while (HasChild(tmpPeaks))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Find Index ...
|
||||||
|
int idx = GetLowest(tmpPeaks);
|
||||||
|
if (!IsValidIndex(idx))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select ...
|
||||||
|
cPeak = tmpPeaks[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpPeaks,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Peak ...
|
||||||
|
bool isValid = cPeak.lower > cBar.high;
|
||||||
|
if (isValid)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
cPeak.Clean();
|
||||||
|
}
|
||||||
|
Clean(tmpPeaks);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selecting Vale ...
|
||||||
|
if (!cVale.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone tmpVales[];
|
||||||
|
detector.FillValePivots(tmpVales);
|
||||||
|
while (HasChild(tmpVales))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Find Index ...
|
||||||
|
int idx = GetHighest(tmpVales);
|
||||||
|
if (!IsValidIndex(idx))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select ...
|
||||||
|
cVale = tmpVales[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpVales,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Vale ...
|
||||||
|
bool isValid = cVale.upper < cTriggerBlock.trigger.lower &&
|
||||||
|
cVale.upper < cInsideTriggerBlock.trigger.lower;
|
||||||
|
if (isValid)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
cVale.Clean();
|
||||||
|
}
|
||||||
|
Clean(tmpVales);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Detect Signal Setup Based on Market Conditions ...
|
// Detect Signal Setup Based on Market Conditions ...
|
||||||
if (!result &&
|
if (!result &&
|
||||||
@@ -545,114 +717,342 @@ class XCXCATBEASignaller : XCBase
|
|||||||
allowSignallingBasedOnTriggerBlocksInsideOther)
|
allowSignallingBasedOnTriggerBlocksInsideOther)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// First We Hvae to Select Peak and Vale ...
|
// Trigger Block Detection ...
|
||||||
|
result = HasChild(triggerBlocks) &&
|
||||||
//
|
ArraySize(triggerBlocks) > 1 &&
|
||||||
// Check Peak and Vale Exists ...
|
!waitsUntilPeakInvalidate &&
|
||||||
int peakIDX = GetYoungest(detector.peakPivots);
|
!waitsUntilValeInvalidate;
|
||||||
int valeIDX = GetYoungest(detector.valePivots);
|
|
||||||
result = IsValidIndex(peakIDX) &&
|
|
||||||
IsValidIndex(valeIDX);
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
cPeak = detector.peakPivots[peakIDX];
|
// Check Newest Trigger Block ...
|
||||||
cVale = detector.valePivots[valeIDX];
|
bool isTriggerBlockSelected = false;
|
||||||
|
XTriggerBlock tmpTBs[];
|
||||||
|
Copy(
|
||||||
|
triggerBlocks,
|
||||||
|
tmpTBs //
|
||||||
|
);
|
||||||
|
while (HasChild(tmpTBs))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int idx = GetYoungest(tmpTBs);
|
||||||
|
if (!IsValidIndex(idx))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select ...
|
||||||
|
// and Remove From Collection ...
|
||||||
|
cTriggerBlock = tmpTBs[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpTBs,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ...
|
||||||
|
isTriggerBlockSelected =
|
||||||
|
//
|
||||||
|
// Check Bar is Valid ...
|
||||||
|
cBar.IsValid() &&
|
||||||
|
//
|
||||||
|
// Currently Happens ...
|
||||||
|
(cTriggerBlock.trigger.to == zBar.time ||
|
||||||
|
cTriggerBlock.trigger.to == cBar.time) &&
|
||||||
|
//
|
||||||
|
// Price Validations ...
|
||||||
|
(cTriggerBlock.IsBullish()
|
||||||
|
? cBar.low > cTriggerBlock.trigger.lower
|
||||||
|
: cBar.high < cTriggerBlock.trigger.upper)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (isTriggerBlockSelected)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean Trigger Block ...
|
||||||
|
cTriggerBlock.Clean();
|
||||||
|
}
|
||||||
|
Clean(tmpTBs);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Trigger Block Detection ...
|
// Check Trigger Block Selection ...
|
||||||
result = HasChild(triggerBlocks) &&
|
result = isTriggerBlockSelected;
|
||||||
ArraySize(triggerBlocks) > 1;
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Check Newest Trigger Block ...
|
bool isBullish = cTriggerBlock.IsBullish();
|
||||||
int newestIDX = GetYoungest(triggerBlocks);
|
bool isBearish = cTriggerBlock.IsBearish();
|
||||||
result = IsValidIndex(newestIDX);
|
|
||||||
|
//
|
||||||
|
// 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)
|
if (result)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
cTriggerBlock = triggerBlocks[newestIDX];
|
// Now we Have to Detect Peak and Vales ...
|
||||||
|
result =
|
||||||
|
cPeak.IsValid() &&
|
||||||
|
cVale.IsValid();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check Trigger Block is New ...
|
// If Exists Before Validate them based Trigger Blocks ...
|
||||||
int toIDX = cTriggerBlock.ToIndex() == 0;
|
if (result)
|
||||||
bool isNewest = toIDX == 0;
|
|
||||||
if (isNewest)
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Now we have to Check Newest Trigger Block Place ...
|
// Validate cPeak and cVale based on
|
||||||
int insideTBIDX = DetectInsideTriggerBlock(
|
// cTriggerBlock and cInsideTriggerBlock ...
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
// Peak ...
|
||||||
|
cPeak.lower > cTriggerBlock.trigger.upper &&
|
||||||
|
cPeak.lower > cInsideTriggerBlock.trigger.upper &&
|
||||||
|
//
|
||||||
|
// Vale ...
|
||||||
|
cVale.upper < cTriggerBlock.trigger.lower &&
|
||||||
|
cVale.upper < cInsideTriggerBlock.trigger.lower &&
|
||||||
|
//
|
||||||
|
// Bar Validation ...
|
||||||
|
cBar.IsValid() &&
|
||||||
|
cBar.low > cVale.upper &&
|
||||||
|
cBar.high < cPeak.lower
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cPeak.Clean();
|
||||||
|
cVale.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
waitsUntilPeakInvalidate = false;
|
||||||
|
waitsUntilValeInvalidate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// if not Exists, or Clean them on Invalidating Process, try to Find Corrects ...
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Selecting Peak ...
|
||||||
|
XBoxZone tmpPeaks[];
|
||||||
|
detector.FillPeakPivots(tmpPeaks);
|
||||||
|
while (HasChild(tmpPeaks))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Find Index ...
|
||||||
|
int idx = GetLowest(tmpPeaks);
|
||||||
|
if (!IsValidIndex(idx))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select ...
|
||||||
|
cPeak = tmpPeaks[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpPeaks,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Peak ...
|
||||||
|
bool isValid =
|
||||||
|
//
|
||||||
|
// Bar Validation ...
|
||||||
|
cBar.IsValid() &&
|
||||||
|
cBar.high < cPeak.lower &&
|
||||||
|
//
|
||||||
|
// Peak Validation ...
|
||||||
|
cPeak.lower > cTriggerBlock.trigger.upper &&
|
||||||
|
cPeak.lower > cInsideTriggerBlock.trigger.upper;
|
||||||
|
if (isValid)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
cPeak.Clean();
|
||||||
|
}
|
||||||
|
Clean(tmpPeaks);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selecting Vale ...
|
||||||
|
XBoxZone tmpVales[];
|
||||||
|
detector.FillValePivots(tmpVales);
|
||||||
|
while (HasChild(tmpVales))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Find Index ...
|
||||||
|
int idx = GetHighest(tmpVales);
|
||||||
|
if (!IsValidIndex(idx))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select ...
|
||||||
|
cVale = tmpVales[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpVales,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Vale ...
|
||||||
|
bool isValid =
|
||||||
|
//
|
||||||
|
// Bar Validation ...
|
||||||
|
cBar.IsValid() &&
|
||||||
|
cBar.low > cVale.upper &&
|
||||||
|
//
|
||||||
|
// Vale Validation ...
|
||||||
|
cVale.upper < cTriggerBlock.trigger.lower &&
|
||||||
|
cVale.upper < cInsideTriggerBlock.trigger.lower;
|
||||||
|
if (isValid)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
cVale.Clean();
|
||||||
|
}
|
||||||
|
Clean(tmpVales);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Summarizing Result ...
|
||||||
|
result =
|
||||||
|
cPeak.IsValid() &&
|
||||||
|
cVale.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Peak and Vale Exists ...
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Remove Peak from Detector Collections ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
UseBox(cPeak);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Vale from Detector Collections ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
UseBox(cVale);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Selected Trigger Block ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
RemoveTriggerBlock(
|
||||||
cTriggerBlock,
|
cTriggerBlock,
|
||||||
|
triggerBlocks //
|
||||||
|
);
|
||||||
|
UseTriggerBlock(cTriggerBlock);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Selected Inside Trigger Block ...
|
||||||
|
// and Make it unavailable ...
|
||||||
|
RemoveTriggerBlock(
|
||||||
cInsideTriggerBlock,
|
cInsideTriggerBlock,
|
||||||
triggerBlocks //
|
triggerBlocks //
|
||||||
);
|
);
|
||||||
|
UseTriggerBlock(cInsideTriggerBlock);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check InsideTB is Exists and Valid ...
|
// Update Peak and Vales To ...
|
||||||
result =
|
cPeak.to = cTime;
|
||||||
cInsideTriggerBlock.IsValid() &&
|
cVale.to = cTime;
|
||||||
IsValidIndex(insideTBIDX);
|
|
||||||
if (result)
|
//
|
||||||
|
// Draw Peak and Vales ...
|
||||||
|
if (allowDraws)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Remove Peak from Detector Collections ...
|
drawer.DrawBox(cPeak);
|
||||||
// and Make it unavailable ...
|
drawer.DrawBox(cVale);
|
||||||
ArrayRemove(
|
}
|
||||||
detector.peakPivots,
|
|
||||||
peakIDX,
|
//
|
||||||
1 //
|
// Validate Peaks and Vales ...
|
||||||
);
|
bool isPeakPassed = false;
|
||||||
AddRef(
|
bool isValePassed = false;
|
||||||
cPeak,
|
cInsideTriggerBlock.trigger.to = cTime;
|
||||||
unavailableZones //
|
int toIDX = cInsideTriggerBlock.ToIndex();
|
||||||
);
|
int fromIDX = cInsideTriggerBlock.FromIndex();
|
||||||
|
for (int i = toIDX; i < fromIDX; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Reading Values ...
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remove Vale from Detector Collections ...
|
double iPeak = helper.GetPeak(i);
|
||||||
// and Make it unavailable ...
|
double iPPeak = helper.GetPeak(i + 1);
|
||||||
ArrayRemove(
|
|
||||||
detector.peakPivots,
|
|
||||||
peakIDX,
|
|
||||||
1 //
|
|
||||||
);
|
|
||||||
AddRef(
|
|
||||||
cVale,
|
|
||||||
unavailableZones //
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remove Selected Trigger Block ...
|
double iVale = helper.GetVale(i);
|
||||||
// and Make it unavailable ...
|
double iPVale = helper.GetVale(i + 1);
|
||||||
RemoveTriggerBlock(
|
|
||||||
cTriggerBlock,
|
|
||||||
triggerBlocks //
|
|
||||||
);
|
|
||||||
UseTriggerBlock(cTriggerBlock);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remove Selected Inside Trigger Block ...
|
bool isPeakOverLast = iPeak > iPPeak;
|
||||||
// and Make it unavailable ...
|
bool isPeakUnderLast = iPeak < iPPeak;
|
||||||
RemoveTriggerBlock(
|
|
||||||
cInsideTriggerBlock,
|
|
||||||
triggerBlocks //
|
|
||||||
);
|
|
||||||
UseTriggerBlock(cInsideTriggerBlock);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
CleanupArray(
|
bool isValeOverLast = iVale > iPVale;
|
||||||
unavailableZones,
|
bool isValeUnderLast = iVale < iPVale;
|
||||||
maxAllowedCollection //
|
|
||||||
);
|
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!isPeakPassed)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
isPeakPassed =
|
||||||
|
isBullish ? isPeakOverLast
|
||||||
|
: isPeakUnderLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!isValePassed)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
isValePassed =
|
||||||
|
isBullish
|
||||||
|
? isValeUnderLast
|
||||||
|
: isPeakOverLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
isPeakPassed &&
|
||||||
|
isValePassed;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// Draw Trigger Blocks if Allowed ...
|
// Draw Trigger Blocks if Allowed ...
|
||||||
if (allowDraws)
|
if (allowDraws)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
//
|
//
|
||||||
// Draw Blocks ...
|
// Draw Blocks ...
|
||||||
datetime cTime = TimeCurrent();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// mObjects.Clear();
|
// mObjects.Clear();
|
||||||
@@ -679,12 +1079,140 @@ class XCXCATBEASignaller : XCBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
Print("Salam ...");
|
if (isBullish)
|
||||||
|
{
|
||||||
|
waitsUntilPeakInvalidate = true;
|
||||||
|
}
|
||||||
|
else if (isBearish)
|
||||||
|
{
|
||||||
|
waitsUntilValeInvalidate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
mConditions.triggerBlock = cTriggerBlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Preparing Conditions based on result ...
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool isBullish = mConditions.triggerBlock.IsBullish();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Preparing mConditions ...
|
||||||
|
mConditions.dir =
|
||||||
|
mConditions
|
||||||
|
.triggerBlock
|
||||||
|
.GetDirection();
|
||||||
|
mConditions.symbol = symbol;
|
||||||
|
mConditions.period = period;
|
||||||
|
mConditions.provider = provider;
|
||||||
|
mConditions.reward = riskToRewardRatio;
|
||||||
|
mConditions.time = mConditions.conditions.bars[0].time;
|
||||||
|
mConditions.setupTime = mConditions.conditions.bars[0].time;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Target ...
|
||||||
|
double targets[];
|
||||||
|
for (int i = 1; i <= riskToRewardRatio; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(double)i,
|
||||||
|
targets //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate SL Additions ...
|
||||||
|
double iATR = 0;
|
||||||
|
if (barIndex > 0 &&
|
||||||
|
barIndex < ArraySize(helper.atrBuffer))
|
||||||
|
{
|
||||||
|
iATR = helper.atrBuffer[barIndex];
|
||||||
|
}
|
||||||
|
double slAdditional = slATRMultiplier * iATR;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Preparing Signal ...
|
||||||
|
result = ToSignal(
|
||||||
|
mConditions.triggerBlock.trigger,
|
||||||
|
mConditions.triggerBlock.signal,
|
||||||
|
targets,
|
||||||
|
slAdditional //
|
||||||
|
);
|
||||||
|
XSignal insideTBSignal;
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
ToSignal(
|
||||||
|
cInsideTriggerBlock.trigger,
|
||||||
|
insideTBSignal,
|
||||||
|
targets,
|
||||||
|
slAdditional //
|
||||||
|
);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Try to Use SL Based on Inside Trigger Block ...
|
||||||
|
double sl = 0;
|
||||||
|
double tp = 0;
|
||||||
|
bool useInsideTBForSL = true;
|
||||||
|
if (useInsideTBForSL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
sl = insideTBSignal.sl;
|
||||||
|
tp = insideTBSignal.tp;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add Target for usuall Signal TP ...
|
||||||
|
XTarget iTarget;
|
||||||
|
iTarget.doRF = true;
|
||||||
|
iTarget.target = mConditions.triggerBlock.signal.tp;
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iTarget,
|
||||||
|
mConditions.targets);
|
||||||
|
|
||||||
|
//
|
||||||
|
iTarget.Clean();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
sl = mConditions.triggerBlock.signal.sl;
|
||||||
|
tp = mConditions.triggerBlock.signal.tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
mConditions.sl = sl;
|
||||||
|
mConditions.tp = tp;
|
||||||
|
mConditions.pivot = sl;
|
||||||
|
mConditions.triggerBlock.signal.provider = provider;
|
||||||
|
mConditions.entry = mConditions.triggerBlock.signal.entry;
|
||||||
|
mConditions.point = mConditions.triggerBlock.signal.entry;
|
||||||
|
mConditions.type = ToPositionType(mConditions.triggerBlock.signal.type);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Trigger Block ...
|
||||||
|
if (allowDraws)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
DrawTriggerBlock(
|
||||||
|
mConditions.triggerBlock,
|
||||||
|
drawer.drawer,
|
||||||
|
mObjects,
|
||||||
|
NULL, // To ...
|
||||||
|
false // Draw Signal ...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -694,6 +1222,10 @@ class XCXCATBEASignaller : XCBase
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Cleanup Resource ...
|
// Cleanup Resource ...
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
cTriggerBlock.Clean();
|
||||||
|
cInsideTriggerBlock.Clean();
|
||||||
|
|
||||||
//
|
//
|
||||||
return result;
|
return result;
|
||||||
@@ -852,8 +1384,8 @@ class XCXCATBEASignaller : XCBase
|
|||||||
|
|
||||||
//
|
//
|
||||||
allowSignallingBasedOnConditions = false;
|
allowSignallingBasedOnConditions = false;
|
||||||
allowSignallingBasedOnTriggerBlocks = true;
|
allowSignallingBasedOnTriggerBlocks = false;
|
||||||
allowSignallingBasedOnTriggerBlocksInsideOther = false;
|
allowSignallingBasedOnTriggerBlocksInsideOther = true;
|
||||||
|
|
||||||
//
|
//
|
||||||
bool has = inputs.IsValid();
|
bool has = inputs.IsValid();
|
||||||
@@ -1090,6 +1622,52 @@ class XCXCATBEASignaller : XCBase
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use Specified Box and make it Unavailable ...
|
||||||
|
*
|
||||||
|
* @param box: XBoxZone instance reference ...
|
||||||
|
*/
|
||||||
|
void UseBox(XBoxZone &box)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Box ...
|
||||||
|
bool has = box.IsValid();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Box Added Before or not ...
|
||||||
|
int idx = -1;
|
||||||
|
has = FindBoxIndex(
|
||||||
|
idx,
|
||||||
|
box,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Adding Box Reference to
|
||||||
|
// Unavailable Zones ...
|
||||||
|
AddRef(
|
||||||
|
box,
|
||||||
|
unavailableZones //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Array ...
|
||||||
|
CleanupArray(
|
||||||
|
unavailableZones,
|
||||||
|
maxAllowedCollection //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use Specified Trigger Block and Make it Un Available ...
|
* Use Specified Trigger Block and Make it Un Available ...
|
||||||
*
|
*
|
||||||
@@ -1109,11 +1687,7 @@ class XCXCATBEASignaller : XCBase
|
|||||||
has = tb.trigger.IsValid();
|
has = tb.trigger.IsValid();
|
||||||
if (has)
|
if (has)
|
||||||
{
|
{
|
||||||
//
|
UseBox(tb.trigger);
|
||||||
AddRef(
|
|
||||||
tb.trigger,
|
|
||||||
unavailableZones //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1121,11 +1695,7 @@ class XCXCATBEASignaller : XCBase
|
|||||||
has = tb.ob.IsValid();
|
has = tb.ob.IsValid();
|
||||||
if (has)
|
if (has)
|
||||||
{
|
{
|
||||||
//
|
UseBox(tb.ob);
|
||||||
AddRef(
|
|
||||||
tb.ob,
|
|
||||||
unavailableZones //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1133,11 +1703,7 @@ class XCXCATBEASignaller : XCBase
|
|||||||
has = tb.fvg.IsValid();
|
has = tb.fvg.IsValid();
|
||||||
if (has)
|
if (has)
|
||||||
{
|
{
|
||||||
//
|
UseBox(tb.fvg);
|
||||||
AddRef(
|
|
||||||
tb.fvg,
|
|
||||||
unavailableZones //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1145,11 +1711,7 @@ class XCXCATBEASignaller : XCBase
|
|||||||
has = tb.fLiquidity.IsValid();
|
has = tb.fLiquidity.IsValid();
|
||||||
if (has)
|
if (has)
|
||||||
{
|
{
|
||||||
//
|
UseBox(tb.fLiquidity);
|
||||||
AddRef(
|
|
||||||
tb.fLiquidity,
|
|
||||||
unavailableZones //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1157,19 +1719,8 @@ class XCXCATBEASignaller : XCBase
|
|||||||
has = tb.rLiquidity.IsValid();
|
has = tb.rLiquidity.IsValid();
|
||||||
if (has)
|
if (has)
|
||||||
{
|
{
|
||||||
//
|
UseBox(tb.rLiquidity);
|
||||||
AddRef(
|
|
||||||
tb.rLiquidity,
|
|
||||||
unavailableZones //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Cleaning Up ...
|
|
||||||
CleanupArray(
|
|
||||||
unavailableZones,
|
|
||||||
maxAllowedCollection //
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,9 +32,9 @@
|
|||||||
//
|
//
|
||||||
enum ENUM_XCATB_PIVOTS
|
enum ENUM_XCATB_PIVOTS
|
||||||
{
|
{
|
||||||
XCA_NONE, // None
|
XCA_NONE, // None
|
||||||
XCA_PEAK, // Peak
|
XCA_PEAK, // Peak
|
||||||
XCA_VALE, // Vale
|
XCA_VALE, // Vale
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1258,6 +1258,45 @@ class XCXCATBEAPOIDetector : public XCBase
|
|||||||
return ArraySize(peakPivots);
|
return ArraySize(peakPivots);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int FillPeakPivots(XBoxZone &pivots[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!HasPeakPivots())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = CountPeakPivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iPivot = peakPivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iPivot,
|
||||||
|
pivots //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// VALE ...
|
// VALE ...
|
||||||
|
|
||||||
@@ -1279,6 +1318,45 @@ class XCXCATBEAPOIDetector : public XCBase
|
|||||||
return ArraySize(valePivots);
|
return ArraySize(valePivots);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int FillValePivots(XBoxZone &pivots[])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!HasValePivots())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = CountValePivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iPivot = valePivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iPivot,
|
||||||
|
pivots //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(pivots);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Protected ...
|
// Protected ...
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -275,6 +275,68 @@ struct XCATBEAStrategyConditions
|
|||||||
//
|
//
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts Strategy Conditions to Signal ...
|
||||||
|
*/
|
||||||
|
bool ToSignal(
|
||||||
|
XSignal &signal,
|
||||||
|
XCATBEAStrategyConditions &conditions //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Args ...
|
||||||
|
signal.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
result =
|
||||||
|
conditions.IsValid() &&
|
||||||
|
conditions.IsSetuped() &&
|
||||||
|
conditions.CanTrigger();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do Converting ...
|
||||||
|
signal.volume = 0.01;
|
||||||
|
signal.tp = conditions.tp;
|
||||||
|
signal.sl = conditions.sl;
|
||||||
|
signal.entry = conditions.entry;
|
||||||
|
signal.symbol = conditions.symbol;
|
||||||
|
signal.period = conditions.period;
|
||||||
|
signal.mode = X_ORDER_MODE_MARKET;
|
||||||
|
signal.time = conditions.triggerTime;
|
||||||
|
signal.provider = conditions.provider;
|
||||||
|
signal.type = conditions.type ==
|
||||||
|
X_POSITION_TYPE_LONG
|
||||||
|
? POSITION_TYPE_BUY
|
||||||
|
: POSITION_TYPE_SELL;
|
||||||
|
signal.conditions = conditions
|
||||||
|
.conditions
|
||||||
|
.GenerateSummary(
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false // Ignore False Conditions ...
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
conditions.targets,
|
||||||
|
signal.targets //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Result ...
|
||||||
|
result = signal.IsValid();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect Signal Zone based on Market Conditions ...
|
* Detect Signal Zone based on Market Conditions ...
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user