This commit is contained in:
2025-05-27 12:55:30 +03:30
parent 34ff9b1477
commit e15c645f01
2 changed files with 1084 additions and 141 deletions
+869 -29
View File
@@ -136,11 +136,13 @@ struct XTriggerBlock
//
// Extensions ...
bool DetectTriggerBlock(
XCPOIDrawer *drawer,
//
bool DetectSignalZone1(
XCPOIDrawer *&drawer,
XCX121XCatbHelper *helper,
XCBarAnalyser *barAnalyser,
XBoxZone &signalZone,
X121XCatbConditions &conditions,
XTriggerBlock &tb,
int barIndex = 0,
int loopback = 10 //
)
@@ -148,16 +150,20 @@ bool DetectTriggerBlock(
//
bool result = false;
//
// Checking Conditions ...
//
// Normalize Args ...
tb.Clean();
signalZone.Clean();
conditions.Clean();
barIndex = NormalizeInt(barIndex, 0);
loopback = NormalizeInt(loopback, 0);
//
// Validate Args ...
result = helper != NULL;
result = helper != NULL &&
barAnalyser != NULL;
if (!result)
{
return result;
@@ -173,7 +179,7 @@ bool DetectTriggerBlock(
if (!result)
{
//
tb.Clean();
signalZone.Clean();
conditions.Clean();
}
@@ -182,10 +188,75 @@ bool DetectTriggerBlock(
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
int p4IDX = p3IDX + 1;
//
// Checking Conditions ...
//
// Detect Bar Verifications ...
//
ENUM_X_DIRECTION iDir;
//
// Rejected ...
bool isRejected =
barAnalyser
.IsRejected(
conditions.bars[cIDX],
iDir //
);
bool isBullishRejected =
isRejected &&
IsBullish(iDir);
bool isBearishRejected =
isRejected &&
IsBearish(iDir);
//
// Engulfed ...
bool isEngulfed =
barAnalyser
.IsEngulfed(
conditions.bars[cIDX],
iDir //
);
bool isBullishEngulfed =
isEngulfed &&
IsBullish(iDir);
bool isBearishEngulfed =
isEngulfed &&
IsBearish(iDir);
//
// Momentum ...
bool isMomentum =
barAnalyser
.IsMomentum(
conditions.bars[cIDX],
iDir //
);
bool isBullishMomentum =
isMomentum &&
IsBullish(iDir);
bool isBearishMomentum =
isMomentum &&
IsBearish(iDir);
//
bool isBarBullishPressured =
isBullishRejected ||
isBullishEngulfed ||
isBullishMomentum;
//
bool isBarBearishPressured =
isBearishRejected ||
isBearishEngulfed ||
isBearishMomentum;
//
// Detect Indicator Base Start Directional Movement ...
@@ -542,41 +613,734 @@ bool DetectTriggerBlock(
//
;
//
// Check for Vale and Peak ...
//
bool isPeakOverLast =
//
(conditions.peakBuffer[cIDX] > conditions.peakBuffer[pIDX] &&
conditions.peakBuffer[pIDX] <= conditions.peakBuffer[p2IDX] &&
conditions.bars[cIDX].close > conditions.peakBuffer[pIDX])
//
;
//
bool isValeUnderLast =
//
(conditions.valeBuffer[cIDX] < conditions.valeBuffer[pIDX] &&
conditions.valeBuffer[pIDX] >= conditions.valeBuffer[p2IDX] &&
conditions.bars[cIDX].close < conditions.valeBuffer[pIDX])
//
;
//
// Start Different Conditions Implemntation ...
//
// Condition 1:
// ---------------------------
// Descriptions:
//
//
// ---------------------------
//
// Bullish ...
bool isCond1Bullish = false;
//
// Bearish ...
bool isCond1Bearish = false;
//
// Try to Summarize Conditions ...
//
bool isBullishPassed =
//
//isSarBullishStart &&
// isTrendBullishStart &&
// isADXBullishStart &&
isDeltaBullishStart &&
isVolumeBullishStart &&
isSBarBullishStart
// &&
// isHKSBarBullishStart
isCond1Bullish
//
;
//
bool isBearishPassed =
//
// isSarBearishStart &&
// isTrendBearishStart &&
// isADXBearishStart &&
isDeltaBearishStart &&
isVolumeBearishStart &&
isSBarBearishStart
// &&
// isHKSBarBearishStart
isCond1Bearish
//
;
//
// Summarize Result ...
result =
isBullishPassed ||
isBearishPassed;
//
return result;
}
bool DetectTriggerBlock(
XCPOIDrawer *drawer,
XCX121XCatbHelper *helper,
XCBarAnalyser *barAnalyser,
X121XCatbConditions &conditions,
XTriggerBlock &tb,
int barIndex = 0,
int loopback = 10 //
)
{
//
bool result = false;
//
// Normalize Args ...
tb.Clean();
conditions.Clean();
barIndex = NormalizeInt(barIndex, 0);
loopback = NormalizeInt(loopback, 0);
//
// Validate Args ...
result = helper != NULL;
if (!result)
{
return result;
}
//
// Reading Market Conditions ...
result = helper.GetConditions(
conditions,
barIndex,
loopback //
);
if (!result)
{
//
tb.Clean();
conditions.Clean();
}
//
int zIDX = 0;
int cIDX = zIDX + 1;
int pIDX = cIDX + 1;
int p2IDX = pIDX + 1;
int p3IDX = p2IDX + 1;
int p4IDX = p3IDX + 1;
//
// Checking Conditions ...
//
// Detect Bar Verifications ...
//
ENUM_X_DIRECTION iDir;
//
// Rejected ...
bool isRejected =
barAnalyser
.IsRejected(
conditions.bars[cIDX],
iDir //
);
bool isBullishRejected =
isRejected &&
IsBullish(iDir);
bool isBearishRejected =
isRejected &&
IsBearish(iDir);
//
// Engulfed ...
bool isEngulfed =
barAnalyser
.IsEngulfed(
conditions.bars[cIDX],
iDir //
);
bool isBullishEngulfed =
isEngulfed &&
IsBullish(iDir);
bool isBearishEngulfed =
isEngulfed &&
IsBearish(iDir);
//
// Momentum ...
bool isMomentum =
barAnalyser
.IsMomentum(
conditions.bars[cIDX],
iDir //
);
bool isBullishMomentum =
isMomentum &&
IsBullish(iDir);
bool isBearishMomentum =
isMomentum &&
IsBearish(iDir);
//
bool isBarBullishPressured =
isBullishRejected ||
isBullishEngulfed ||
isBullishMomentum;
//
bool isBarBearishPressured =
isBearishRejected ||
isBearishEngulfed ||
isBearishMomentum;
//
// Detect Indicator Base Start Directional Movement ...
//
// SAR ...
//
bool isSarBullishStart =
//
(
//
// Current SAR is Directional ...
conditions.isSarBullish &&
//
// Previous InDirectional Sar Exists ...
helper.lastSarBearish.IsValid() &&
//
// Current Close is Over previous Sar ...
conditions.bars[cIDX].close > helper.lastSarBearish.after &&
//
// Before Close is not Over previous Sar ...
conditions.bars[pIDX].close <= helper.lastSarBearish.after
//
)
//
;
//
bool isSarBearishStart =
//
(
//
// Current SAR is Directional ...
conditions.isSarBearish &&
//
// Previous InDirectional Sar Exists ...
helper.lastSarBullish.IsValid() &&
//
// Current Close is Under previous ...
conditions.bars[cIDX].close < helper.lastSarBullish.after &&
//
// Before Close is not Under previous ...
conditions.bars[pIDX].close >= helper.lastSarBullish.after
//
)
//
;
//
// TREND ...
//
bool isTrendBullishStart =
//
(
//
// Current Trend is Directional ...
conditions.isTrendBullish &&
//
// Previous InDirectiona; Trend Exists ...
helper.lastTrendBearish.IsValid() &&
//
// Current Close is Over previous ...
conditions.bars[cIDX].close > helper.lastTrendBearish.after &&
//
// Before close is not Over previous ...
conditions.bars[pIDX].close <= helper.lastTrendBearish.after
//
)
//
;
//
bool isTrendBearishStart =
//
(
//
// Current Trend is Directional ...
conditions.isTrendBearish &&
//
// Previous InDirectiona; Trend Exists ...
helper.lastTrendBullish.IsValid() &&
//
// Current Close is Under previous ...
conditions.bars[cIDX].close < helper.lastTrendBullish.after &&
//
// Before close is not Under previous ...
conditions.bars[pIDX].close >= helper.lastTrendBullish.after
//
)
//
;
//
// ADX ...
//
bool isADXBullishStart =
//
(
//
// ADX Value is Switched to Strong ...
conditions.adxBuffer[cIDX] > conditions.adxThreshold &&
conditions.adxBuffer[pIDX] <= conditions.adxThreshold &&
//
// ADX must Up ...
conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] &&
//
// ADX +DI is Bigger than -DI ...
conditions.adxpBuffer[cIDX] > conditions.adxnBuffer[cIDX] &&
//
// ADX +DI is Up ...
conditions.adxpBuffer[cIDX] > conditions.adxpBuffer[pIDX]
//
)
//
;
//
bool isADXBearishStart =
//
(
//
// ADX Value is Switched to Strong ...
conditions.adxBuffer[cIDX] > conditions.adxThreshold &&
conditions.adxBuffer[pIDX] <= conditions.adxThreshold &&
//
// ADX must Up ...
conditions.adxBuffer[cIDX] > conditions.adxBuffer[pIDX] &&
//
// ADX -DI is Bigger than +DI ...
conditions.adxnBuffer[cIDX] > conditions.adxpBuffer[cIDX] &&
//
// ADX -DI is Up ...
conditions.adxnBuffer[cIDX] > conditions.adxnBuffer[pIDX]
//
)
//
;
//
// DELTA ...
//
bool isDeltaBullishStart =
//
// Check State ...
(
//
// Delta is Up ...
conditions.deltaBuffer[cIDX] > conditions.deltaBuffer[pIDX] &&
//
// Delta Signal is Up ...
conditions.deltaSignalBuffer[cIDX] > conditions.deltaSignalBuffer[pIDX] &&
//
// Delta Crossed Over Delta Signal ...
conditions.deltaBuffer[cIDX] > conditions.deltaSignalBuffer[cIDX]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastDeltaBearish.IsValid() &&
//
// Current Close is Over last ...
conditions.bars[cIDX].close > helper.lastDeltaBearish.after &&
//
// Before Close is not Over last ...
conditions.bars[pIDX].close <= helper.lastDeltaBearish.after
//
;
//
bool isDeltaBearishStart =
//
// Check State ...
(
//
// Delta is Down ...
conditions.deltaBuffer[cIDX] < conditions.deltaBuffer[pIDX] &&
//
// Delta Signal is Down ...
conditions.deltaSignalBuffer[cIDX] < conditions.deltaSignalBuffer[pIDX] &&
//
// Delta Crossed Under Delta Signal ...
conditions.deltaBuffer[cIDX] < conditions.deltaSignalBuffer[cIDX]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastDeltaBullish.IsValid() &&
//
// Current Close is Under last ...
conditions.bars[cIDX].close < helper.lastDeltaBullish.after &&
//
// Before Close is not Under last ...
conditions.bars[pIDX].close >= helper.lastDeltaBullish.after
//
;
//
// VOLUME ...
//
bool isVolumeBullishStart =
//
(
//
//
// Volume is Up ...
conditions.bullishVolumeBuffer[1] > conditions.bullishVolumeBuffer[2] &&
//
// Volume Signal is Up ...
conditions.bullishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[2] &&
//
// Volume Signals Crossed Over ...
conditions.bullishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[1]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastVolumeBearish.IsValid() &&
//
// Current Close is Over last ...
conditions.bars[cIDX].close > helper.lastVolumeBearish.after &&
//
// Before Close is not Over last ...
conditions.bars[pIDX].close <= helper.lastVolumeBearish.after
//
;
//
bool isVolumeBearishStart =
//
(
//
//
// Volume is Up ...
conditions.bearishVolumeBuffer[1] > conditions.bearishVolumeBuffer[2] &&
//
// Volume Signal is Up ...
conditions.bearishVolumeSignalBuffer[1] > conditions.bearishVolumeSignalBuffer[2] &&
//
// Volume Signals Crossed Over ...
conditions.bearishVolumeSignalBuffer[1] > conditions.bullishVolumeSignalBuffer[1]
//
)
//
&&
//
// Check Last InDirectional Exists ...
helper.lastVolumeBullish.IsValid() &&
//
// Current Close is Over last ...
conditions.bars[cIDX].close < helper.lastVolumeBullish.after &&
//
// Before Close is not Over last ...
conditions.bars[pIDX].close >= helper.lastVolumeBullish.after
//
;
//
// SIGNAL Bar ...
//
bool isSBarBullishStart =
//
(
//
// Check Direction ...
conditions.isSBarBullish &&
//
// Previous InDirectional Exists ...
helper.lastSignalBarBearish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.sBarCloseBuffer[cIDX] > helper.lastSignalBarBearish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.sBarCloseBuffer[pIDX] <= helper.lastSignalBarBearish.after
//
)
//
;
//
bool isSBarBearishStart =
//
(
//
// Check Direction ...
conditions.isSBarBearish &&
//
// Previous InDirectional Exists ...
helper.lastSignalBarBullish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.sBarCloseBuffer[cIDX] < helper.lastSignalBarBullish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.sBarCloseBuffer[pIDX] >= helper.lastSignalBarBullish.after
//
)
//
;
//
// HKSIGNAL Bar ...
//
bool isHKSBarBullishStart =
//
(
//
// Check Direction ...
conditions.isHKSBarBullish &&
//
// Previous InDirectional Exists ...
helper.lastHKSignalBarBearish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.hkSBarCloseBuffer[cIDX] > helper.lastHKSignalBarBearish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.hkSBarCloseBuffer[pIDX] <= helper.lastHKSignalBarBearish.after
//
)
//
;
//
bool isHKSBarBearishStart =
//
(
//
// Check Direction ...
conditions.isHKSBarBearish &&
//
// Previous InDirectional Exists ...
helper.lastHKSignalBarBullish.IsValid() &&
//
// Current Signal Bar close over prev ...
conditions.hkSBarCloseBuffer[cIDX] < helper.lastHKSignalBarBullish.after &&
//
// Prev Signal Bar not close over prev ...
conditions.hkSBarCloseBuffer[pIDX] >= helper.lastHKSignalBarBullish.after
//
)
//
;
//
// Check for Vale and Peak ...
//
bool isPeakOverLast =
//
(conditions.peakBuffer[cIDX] > conditions.peakBuffer[pIDX] &&
conditions.peakBuffer[pIDX] <= conditions.peakBuffer[p2IDX] &&
conditions.bars[cIDX].close > conditions.peakBuffer[pIDX])
//
||
//
(conditions.peakBuffer[pIDX] > conditions.peakBuffer[p2IDX] &&
conditions.peakBuffer[p2IDX] <= conditions.peakBuffer[p3IDX] &&
conditions.bars[pIDX].close > conditions.peakBuffer[p2IDX])
//
||
//
(conditions.peakBuffer[p2IDX] > conditions.peakBuffer[p3IDX] &&
conditions.peakBuffer[p3IDX] <= conditions.peakBuffer[p4IDX] &&
conditions.bars[p2IDX].close > conditions.peakBuffer[p3IDX])
//
;
//
bool isValeUnderLast =
//
(conditions.valeBuffer[cIDX] < conditions.valeBuffer[pIDX] &&
conditions.valeBuffer[pIDX] >= conditions.valeBuffer[p2IDX] &&
conditions.bars[cIDX].close < conditions.valeBuffer[pIDX])
//
||
//
(conditions.valeBuffer[pIDX] < conditions.valeBuffer[p2IDX] &&
conditions.valeBuffer[p2IDX] >= conditions.valeBuffer[p3IDX] &&
conditions.bars[pIDX].close < conditions.valeBuffer[p2IDX])
//
||
//
(conditions.valeBuffer[p2IDX] < conditions.valeBuffer[p3IDX] &&
conditions.valeBuffer[p3IDX] >= conditions.valeBuffer[p4IDX] &&
conditions.bars[p2IDX].close < conditions.valeBuffer[p3IDX])
//
;
//
// if (isValeUnderLast)
// {
// Print("SALAM");
// }
//
// Try to Summarize Conditions ...
//
bool isBullishPassed =
//
(isPeakOverLast &&
isDeltaBullishStart &&
isVolumeBullishStart &&
isBarBullishPressured)
//
;
//
bool isBearishPassed =
(isValeUnderLast &&
isDeltaBearishStart &&
isVolumeBearishStart &&
isBarBearishPressured)
//
;
//
// Try to Detect Trigger Block ...
bool hasTB = false;
int tbLoopback = 100;
X121XCatbInputs mInputs = helper.GetInputs();
for (int i = barIndex; i < barIndex + tbLoopback; i++)
{
//
// Update Helper ...
helper.Update(i);
//
// Check TB ...
hasTB = DetectTriggerBlock(
//
conditions.symbol,
conditions.period,
//
tb,
//
drawer,
barAnalyser,
//
// Required Buffers ...
helper.atrBuffer,
helper.rsiBuffer,
helper.adxBuffer,
helper.adxpBuffer,
helper.adxnBuffer,
helper.peakBuffer,
helper.valeBuffer,
helper.deltaBuffer,
helper.sarBuffer,
helper.sarStateBuffer,
helper.trendBuffer,
helper.trendStateBuffer,
helper.atrUpperBuffer,
helper.atrLowerBuffer,
helper.sBarOpenBuffer,
helper.sBarCloseBuffer,
helper.hkSBarOpenBuffer,
helper.hkSBarCloseBuffer,
helper.peakGoldenBuffer,
helper.valeGoldenBuffer,
helper.deltaSignalBuffer,
helper.bullishVolumeSignalBuffer,
helper.bearishVolumeSignalBuffer,
//
i + 1,
//
// Signalling ...
mInputs.signalR2R,
mInputs.slAtrMultiplier,
//
// Configs ...
mInputs.rsiOBLevel,
mInputs.rsiOSLevel,
mInputs.adxThreshold,
//
// Validators ...
mInputs.forceObBarType,
mInputs.forceOBFVGBarType,
mInputs.forceHasSwing,
mInputs.forceHasFLiquidity,
mInputs.forceHasRLiquidity,
mInputs.validateGapSequence,
mInputs.validateBlockEdgeBreakout,
//
// Filters ...
mInputs.filterBasedOnPV,
mInputs.filterBasedOnSar,
mInputs.filterBasedOnRSI,
mInputs.filterBasedOnADX,
mInputs.filterBasedOnATR,
mInputs.filterBasedOnTrend,
mInputs.filterBasedOnDelta,
mInputs.filterBasedOnVolume,
mInputs.filterBasedOnSignalBar,
mInputs.filterBasedOnHKSignalBar //
);
//
// Checking Trigger Block Validation ...
hasTB =
//
hasTB &&
//
(
//
(isBullishPassed &&
tb.IsBullish())
//
||
//
(isBearishPassed &&
tb.IsBearish())
//
);
if (hasTB)
{
//
break;
}
//
tb.Clean();
}
//
// isBullishPassed = false;
// isBearishPassed = false;
//
// Draw Line for Detect Conditions States on Chart ...
if (isBullishPassed ||
isBearishPassed)
if (hasTB && (isBullishPassed ||
isBearishPassed))
{
//
color iColor = isBullishPassed
@@ -607,6 +1371,18 @@ bool DetectTriggerBlock(
//
iObj.Color(iColor);
}
//
CArrayObj *tbObjects = new CArrayObj();
DrawTriggerBlock(
tb,
drawer,
tbObjects,
conditions.bars[0].time //
);
//
tb.Clean();
}
//
@@ -640,6 +1416,7 @@ bool DetectTriggerBlock(
//
XTriggerBlock &tb,
//
XCPOIDrawer *drawer,
XCBarAnalyser *barAnalyser,
//
// Required Buffers ...
@@ -1072,13 +1849,18 @@ bool DetectTriggerBlock(
double iP2ValeGolden = _valeGoldenBuffer[barIndex + 2];
//
// TODO: Fix this ...
has =
has &&
(isBullish
? (tb.trigger.lower <= iVale ||
tb.trigger.lower <= iValeGolden)
: (tb.trigger.upper >= iPeak ||
tb.trigger.upper >= iPeakGolden));
? (tb.trigger.lower <= iVale &&
tb.trigger.upper < iPeak
// || tb.trigger.lower <= iValeGolden
)
: (tb.trigger.upper >= iPeak &&
tb.trigger.lower > iVale
// || tb.trigger.upper >= iPeakGolden
));
}
//
@@ -1488,10 +2270,63 @@ bool DetectTriggerBlock(
: isHKSignalBarSwitchedToBearish);
}
//
// Valdating Directional Trending ...
bool _filterBasedOnDirection = false;
if (has &&
_filterBasedOnDirection)
{
//
iBar.Clean();
fromIDX = tb.FromIndex();
int loopbackForValidating = 30;
for (int i = fromIDX; i < fromIDX + loopbackForValidating; i++)
{
//
// Initialize iBar ...
iBar.Clean();
has = iBar.Init(
symbol,
period,
i //
);
//
has =
has &&
(isBullish
? iBar.high < tb.trigger.upper
: iBar.low > tb.trigger.lower);
if (!has)
{
break;
}
}
//
// Update Trigger Block ...
if (has)
{
tb.trigger.from = iBar.time;
}
//
iBar.Clean();
}
//
// Preparing Signal ...
if (has)
{
//
// CArrayObj *tbObjects = new CArrayObj();
// DrawTriggerBlock(
// tb,
// drawer,
// tbObjects,
// NULL //
// );
//
double targets[];
for (int i = 1; i <= _r2r; i++)
@@ -1504,7 +2339,12 @@ bool DetectTriggerBlock(
}
//
double iATR = _atrBuffer[barIndex];
double iATR = 0;
if (barIndex > 0 &&
barIndex < ArraySize(_atrBuffer))
{
iATR = _atrBuffer[barIndex];
}
double slAdditional = _slAtrMultiplier * iATR;
//