This commit is contained in:
2025-06-16 01:43:17 +03:30
parent 4cb5e47616
commit 80b452fff4
3 changed files with 479 additions and 162 deletions
+54 -70
View File
@@ -48,17 +48,18 @@ enum ENUM_XCHARTOBJECTS
enum ENUM_X_CHART_IDS enum ENUM_X_CHART_IDS
{ {
X_TO, X_AT, // AT
X_FROM, X_TO, // TO
X_UPPER, X_FROM, // FROM
X_LOWER, X_UPPER, // UPPER
X_ENTRY, X_LOWER, // LOWER
X_TARGET, X_ENTRY, // ENTRY
X_SL, X_TARGET, // TARGET
X_TP, X_SL, // SL
X_BAR_H_SHW, X_TP, // TP
X_BAR_BDY, X_BAR_H_SHW, // HSHW
X_BAR_L_SHW, X_BAR_BDY, // BODY
X_BAR_L_SHW, // LSHW
}; };
string ToString(ENUM_X_CHART_IDS value) string ToString(ENUM_X_CHART_IDS value)
@@ -67,65 +68,7 @@ string ToString(ENUM_X_CHART_IDS value)
string result = NULL; string result = NULL;
// //
switch (value) result = EnumToString(value);
{
//
case X_TO:
result = "TO";
break;
//
case X_FROM:
result = "FROM";
break;
//
case X_UPPER:
result = "UPPER";
break;
//
case X_LOWER:
result = "LOWER";
break;
//
case X_ENTRY:
result = "ENTRY";
break;
//
case X_TARGET:
result = "TARGET";
break;
//
case X_SL:
result = "SL";
break;
//
case X_TP:
result = "TP";
break;
//
case X_BAR_H_SHW:
result = "HSHW";
break;
//
case X_BAR_BDY:
result = "BODY";
break;
//
case X_BAR_L_SHW:
result = "LSHW";
break;
//
}
// //
return result; return result;
@@ -436,6 +379,8 @@ class XCBaseObject : public CChartObject
// //
}; };
//
// Bar Arrow Object ...
class XCBarArrowObject : public XCBaseObject class XCBarArrowObject : public XCBaseObject
{ {
// //
@@ -990,6 +935,8 @@ class XCRRObject : public XCSignalObject
} }
}; };
//
// OHCL, Bar Object ...
class XCOHCLObject : public XCBaseObject class XCOHCLObject : public XCBaseObject
{ {
// //
@@ -1304,6 +1251,8 @@ class XCOHCLObject : public XCBaseObject
CChartObjectRectangle mLowShadowRect; CChartObjectRectangle mLowShadowRect;
}; };
//
// Box Object ...k
class XCBoxObject : public XCBaseObject class XCBoxObject : public XCBaseObject
{ {
// //
@@ -1328,6 +1277,7 @@ class XCBoxObject : public XCBaseObject
double lower, double lower,
datetime from, datetime from,
datetime to, datetime to,
datetime at,
string prefix = NULL // string prefix = NULL //
) )
{ {
@@ -1370,6 +1320,34 @@ class XCBoxObject : public XCBaseObject
return result; return result;
} }
//
if (result)
{
//
if (IsValid(at))
{
//
result = mAt.Create(
chart_id,
name + ToString(X_AT),
window,
at //
);
}
//
if (!result)
{
//
mAt.Detach();
mAt.Delete();
//
mRect.Detach();
mRect.Delete();
}
}
// //
if (result) if (result)
{ {
@@ -1397,6 +1375,7 @@ class XCBoxObject : public XCBaseObject
} }
// //
mAt.Width(value);
mRect.Width(value); mRect.Width(value);
} }
@@ -1407,6 +1386,8 @@ class XCBoxObject : public XCBaseObject
*/ */
void BoxColor(color value) void BoxColor(color value)
{ {
//
mAt.Color(value);
mRect.Color(value); mRect.Color(value);
} }
@@ -1417,6 +1398,8 @@ class XCBoxObject : public XCBaseObject
*/ */
void BoxStyle(ENUM_LINE_STYLE value) void BoxStyle(ENUM_LINE_STYLE value)
{ {
//
mAt.Style(value);
mRect.Style(value); mRect.Style(value);
} }
@@ -1449,6 +1432,7 @@ class XCBoxObject : public XCBaseObject
// //
// Props ... // Props ...
CChartObjectVLine mAt;
CChartObjectRectangle mRect; CChartObjectRectangle mRect;
}; };
+12 -1
View File
@@ -602,6 +602,7 @@ class XCPOIDrawer : public XCBase
double lower, double lower,
datetime from, datetime from,
datetime to, datetime to,
datetime at,
color clr = clrYellowGreen, color clr = clrYellowGreen,
int width = 1, int width = 1,
bool fill = false, bool fill = false,
@@ -658,6 +659,7 @@ class XCPOIDrawer : public XCBase
lower, lower,
from, from,
to, to,
at,
prefix // prefix //
); );
@@ -690,7 +692,8 @@ class XCPOIDrawer : public XCBase
*/ */
bool DrawBox( bool DrawBox(
XBoxZone &box, XBoxZone &box,
XCBoxObject *&object // XCBoxObject *&object,
bool ignoreAt = true //
) )
{ {
// //
@@ -706,6 +709,12 @@ class XCPOIDrawer : public XCBase
return result; return result;
} }
//
if (ignoreAt)
{
box.at = NULL;
}
// //
int width = 1; int width = 1;
bool fill = false; bool fill = false;
@@ -724,6 +733,7 @@ class XCPOIDrawer : public XCBase
box.lower, box.lower,
box.from, box.from,
box.to, box.to,
box.at,
clr, clr,
width, width,
fill, fill,
@@ -800,6 +810,7 @@ class XCPOIDrawer : public XCBase
box.lower, box.lower,
box.from, box.from,
box.to, box.to,
box.at,
clr, clr,
width, width,
fill, fill,
+413 -91
View File
@@ -642,10 +642,22 @@ XCPOIDrawer *mDrawer;
XCBarAnalyser *mBarAnalyser; XCBarAnalyser *mBarAnalyser;
// //
XBoxZone mBullishBreakes[]; int mSamePeakCount = 0;
XBoxZone mBearishBreakes[]; int mSameValeCount = 0;
//
double mSamePeakGolden = 0;
double mSameValeGolden = 0;
//
bool mDetectLiquidities = false;
bool mDetectRangeBreakes = true;
//
XBoxZone mBullishLiquidities[]; XBoxZone mBullishLiquidities[];
XBoxZone mBearishLiquidities[]; XBoxZone mBearishLiquidities[];
XBoxZone mBullishRangeBreakes[];
XBoxZone mBearishRangeBreakes[];
// //
// Event Handlers ... // Event Handlers ...
@@ -910,6 +922,14 @@ int OnCalculate(
return prev_calculated; return prev_calculated;
} }
//
if (prev_calculated == 0)
{
//
string message = "History Started ...";
Print(message);
}
// //
// Main Loop ... // Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--) for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
@@ -3218,6 +3238,11 @@ void DoProcess(
isBearishTriggerBar isBearishTriggerBar
// //
; ;
//
isTriggerBar = false;
isBullishTriggerBar = false;
isBearishTriggerBar = false;
} }
// //
@@ -3408,6 +3433,14 @@ void DetectPOIs(
? barIndex == startCalculationForLastBars ? barIndex == startCalculationForLastBars
: barIndex == firstBarIndex; : barIndex == firstBarIndex;
//
// Handle Minimum Required Bars ...
bool isPassedRequiredBars = barIndex < maxBarIndex - 3;
if (!isPassedRequiredBars)
{
return;
}
// //
// Recieve Bar ... // Recieve Bar ...
XOHCL iBar; XOHCL iBar;
@@ -3427,124 +3460,317 @@ void DetectPOIs(
} }
// //
bool isBullish = false;
bool isBearish = false;
int maxAllowedPOIs = 50; int maxAllowedPOIs = 50;
// //
ENUM_X_DIRECTION iDir; ENUM_X_DIRECTION iDir;
// //
// Detecting Liquidity ... // Detecting Liquidity ...
bool isLiquidity = if (mDetectLiquidities)
mBarAnalyser
.IsRejected(
iBar,
iDir,
true,
true //
);
bool isBullishLiquiditySweeped =
isLiquidity &&
IsBullish(iDir);
bool isBearishLiquiditySweeped =
isLiquidity &&
IsBearish(iDir);
if (isLiquidity)
{ {
// //
XBoxZone iLiq; bool isLiquidity =
mBarAnalyser
// .IsRejected(
iLiq.dir = iDir; iBar,
iLiq.type = "XLIQ"; iDir,
iLiq.upper = true,
isBullishLiquiditySweeped true //
? iBar.GetDown() );
: iBar.high; bool isBullishLiquiditySweeped =
iLiq.lower = isLiquidity &&
isBullishLiquiditySweeped IsBullish(iDir);
? iBar.low bool isBearishLiquiditySweeped =
: iBar.GetUp(); isLiquidity &&
iLiq.from = iBar.time; IsBearish(iDir);
iLiq.symbol = _Symbol; if (isLiquidity)
iLiq.period = _Period;
iLiq.to = ((datetime)((int)iBar.time + (PeriodSeconds(_Period))));
//
if (iLiq.IsValid())
{ {
// //
if (isBullishLiquiditySweeped) XBoxZone iLiq;
{
//
has = AddBoxIfNotExists(
iLiq,
mBullishLiquidities //
);
if (has)
{
//
SortBoxes(
mBullishLiquidities,
maxAllowedPOIs //
);
}
}
else
{
//
has = AddBoxIfNotExists(
iLiq,
mBearishLiquidities //
);
if (has)
{
//
SortBoxes(
mBearishLiquidities,
maxAllowedPOIs //
);
}
}
}
// //
iLiq.Clean(); iLiq.dir = iDir;
iLiq.type = "XLIQ";
iLiq.upper =
isBullishLiquiditySweeped
? iBar.GetDown()
: iBar.high;
iLiq.lower =
isBullishLiquiditySweeped
? iBar.low
: iBar.GetUp();
iLiq.at = iBar.time;
iLiq.from = iBar.time;
iLiq.symbol = _Symbol;
iLiq.period = _Period;
iLiq.to = ((datetime)((int)iBar.time + (PeriodSeconds(_Period))));
//
if (iLiq.IsValid())
{
//
if (isBullishLiquiditySweeped)
{
//
has = AddBoxIfNotExists(
iLiq,
mBullishLiquidities //
);
if (has)
{
//
SortBoxes(
mBullishLiquidities,
maxAllowedPOIs //
);
}
}
else
{
//
has = AddBoxIfNotExists(
iLiq,
mBearishLiquidities //
);
if (has)
{
//
SortBoxes(
mBearishLiquidities,
maxAllowedPOIs //
);
}
}
}
//
iLiq.Clean();
}
} }
// //
// Detecting Bullish and Bearish Breakes ... // Detecting Bullish and Bearish Breakes ...
//
bool isPeakSame = false;
bool isPPeakSame = false;
// //
bool isPeakOverLast = false; bool isPeakSame = peakBuffer[barIndex] == peakBuffer[barIndex + 1];
bool isPPeakOverLast = false; bool isPPeakSame = peakBuffer[barIndex + 1] == peakBuffer[barIndex + 2];
// //
bool isPeakUnderLast = false; bool isPeakOverLast = peakBuffer[barIndex] > peakBuffer[barIndex + 1];
bool isPPeakUnderLast = false; bool isPPeakOverLast = peakBuffer[barIndex + 1] > peakBuffer[barIndex + 2];
// //
bool isSamePeakOverLast = false; bool isPeakUnderLast = peakBuffer[barIndex] < peakBuffer[barIndex + 1];
bool isSamePeakUnderLast = false; bool isPPeakUnderLast = peakBuffer[barIndex + 1] < peakBuffer[barIndex + 2];
// //
bool isValeSame = false; bool isSamePeakOverLast =
bool isPValeSame = false; isPPeakSame &&
isPeakOverLast;
bool isSamePeakUnderLast =
isPPeakSame &&
isPeakUnderLast;
// //
bool isValeOverLast = false; bool isValeSame = valeBuffer[barIndex] == valeBuffer[barIndex + 1];
bool isPValeOverLast = false; bool isPValeSame = valeBuffer[barIndex + 1] == valeBuffer[barIndex + 2];
// //
bool isValeUnderLast = false; bool isValeOverLast = valeBuffer[barIndex] > valeBuffer[barIndex + 1];
bool isPValeUnderLast = false; bool isPValeOverLast = valeBuffer[barIndex + 1] > valeBuffer[barIndex + 2];
// //
bool isSameValeOverLast = false; bool isValeUnderLast = valeBuffer[barIndex] < valeBuffer[barIndex + 1];
bool isSameValeUnderLast = false; bool isPValeUnderLast = valeBuffer[barIndex + 1] < valeBuffer[barIndex + 2];
//
bool isSameValeOverLast =
isPValeSame &&
isValeOverLast;
bool isSameValeUnderLast =
isPValeSame &&
isValeUnderLast;
//
// Detecting Range Breakes ...
if (mDetectRangeBreakes)
{
//
isBullish = isSamePeakOverLast
// || isSameValeOverLast
;
isBearish =
isSameValeUnderLast
// || isSamePeakUnderLast
;
//
bool basedOnPeak =
isSamePeakOverLast
// || isSamePeakUnderLast
;
//
bool basedOnVale =
isSameValeUnderLast
// isSameValeOverLast ||
;
//
has = isBullish ||
isBearish;
//
if (has)
{
//
XBoxZone iRNGBreak;
//
iDir =
isBullish
? X_DIRECTION_BULLISH
: isBearish
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
iRNGBreak.dir = iDir;
iRNGBreak.at = iBar.time;
iRNGBreak.type = "XRNGB";
iRNGBreak.to = iBar.time;
iRNGBreak.symbol = _Symbol;
iRNGBreak.period = _Period;
//
int fromIDX =
iBar.Index() +
(basedOnPeak
? mSamePeakCount
: basedOnVale
? mSameValeCount
: 0);
datetime from = GetBarTime(
_Symbol,
_Period,
fromIDX //
);
iRNGBreak.from = from;
//
double upper =
isBullish
? basedOnPeak
? peakBuffer[barIndex]
: basedOnVale
? mSameValeGolden
: 0
: isBearish
? basedOnPeak
? peakBuffer[barIndex]
: basedOnVale
? mSameValeGolden
: 0
: 0;
//
double lower =
isBullish
? basedOnPeak
? mSamePeakGolden
: basedOnVale
? valeBuffer[barIndex]
: 0
: isBearish
? basedOnPeak
? mSamePeakGolden
: basedOnVale
? valeBuffer[barIndex]
: 0
: 0;
//
iRNGBreak.upper = upper;
iRNGBreak.lower = lower;
//
// Adding POI ...
has = iRNGBreak.IsValid();
if (has)
{
//
if (isBullish)
{
//
has = AddBoxIfNotExists(
iRNGBreak,
mBullishRangeBreakes //
);
if (has)
{
//
SortBoxes(
mBullishRangeBreakes,
maxAllowedPOIs //
);
}
}
else if (isBearish)
{
//
has = AddBoxIfNotExists(
iRNGBreak,
mBearishRangeBreakes //
);
if (has)
{
//
SortBoxes(
mBearishRangeBreakes,
maxAllowedPOIs //
);
}
}
}
}
}
//
if (isPeakSame)
{
//
mSamePeakGolden =
mSamePeakGolden == 0
? iBar.GetUp()
: MathMax(mSamePeakGolden, iBar.GetUp());
mSamePeakCount++;
}
else
{
//
mSamePeakCount = 0;
mSamePeakGolden = 0;
}
//
if (isValeSame)
{
//
mSameValeGolden =
mSameValeGolden == 0
? iBar.GetDown()
: MathMin(mSameValeGolden, iBar.GetDown());
mSameValeCount++;
}
else
{
//
mSameValeCount = 0;
mSameValeGolden = 0;
}
// //
// Cleanup Resources ... // Cleanup Resources ...
@@ -3606,6 +3832,39 @@ void ValidatePOIs(
barsLength // barsLength //
); );
} }
//
// Range Breaks ...
//
// Bullish ...
count = ArraySize(mBullishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
ValidateBoxes(
mBullishRangeBreakes,
barIndex,
barsLength //
);
}
//
// Bearish ...
count = ArraySize(mBearishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
ValidateBoxes(
mBearishRangeBreakes,
barIndex,
barsLength //
);
}
//
} }
// //
@@ -3688,6 +3947,69 @@ void DrawPOIs(
iBox.Clean(); iBox.Clean();
} }
} }
//
// Range Breaks ...
//
// Bullish ...
count = ArraySize(mBullishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
iBox = mBullishRangeBreakes[i];
iBox.to = to;
//
XCBoxObject *iObj;
has = mDrawer.DrawBox(
iBox,
iObj //
);
if (has)
{
mObjects.Add(iObj);
}
//
iBox.Clean();
}
}
//
// Bearish ...
count = ArraySize(mBearishRangeBreakes);
has = IsValidSize(count);
if (has)
{
//
for (int i = 0; i < count; i++)
{
//
iBox = mBearishRangeBreakes[i];
iBox.to = to;
//
XCBoxObject *iObj;
has = mDrawer.DrawBox(
iBox,
iObj //
);
if (has)
{
mObjects.Add(iObj);
}
//
iBox.Clean();
}
}
//
} }
// //