Complete Support and Resistance POI ...

This commit is contained in:
2024-11-12 21:51:07 +03:30
parent 43ee49b32f
commit 797917e30a
5 changed files with 998 additions and 56 deletions
+179
View File
@@ -730,6 +730,185 @@ class XCBarAnalyser : public XCBase
return result; return result;
} }
//
// Support and Resistance Zones ...
/**
* Check a Bar is Support Bar or not ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Specified Verifiation Range ...
*
* @return ( bool )
*/
bool IsSupport(
XOHCL &bar,
int range = 21 //
)
{
//
bool result = false;
//
if (range < 2)
{
range = 2;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
result = range > 0 &&
index >= range;
if (!result)
{
return result;
}
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
for (int i = 1; i <= range; i++)
{
//
int prevIDX = index + i;
int nextIDX = index - 1;
//
// Prev Bar ...
XOHCL iPrevBar;
result = iPrevBar.Init(
symbol,
period,
prevIDX //
);
if (!result)
{
break;
}
//
// Next Bar ...
XOHCL iNextBar;
result = iNextBar.Init(
symbol,
period,
nextIDX //
);
if (!result)
{
break;
}
//
result = bar.low <= iPrevBar.low &&
bar.low <= iNextBar.low;
if (!result)
{
break;
}
}
//
return result;
}
/**
* Check a Bar is Resistance Bar or not ...
*
* @param bar: XOHCL instance ...
* @param range: Integer, Specified Verifiation Range ...
*
* @return ( bool )
*/
bool IsResistance(
XOHCL &bar,
int range = 21 //
)
{
//
bool result = false;
//
if (range < 2)
{
range = 2;
}
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
result = range > 0 &&
index >= range;
if (!result)
{
return result;
}
//
string symbol = bar.symbol;
ENUM_TIMEFRAMES period = bar.period;
//
for (int i = 1; i <= range; i++)
{
//
int prevIDX = index + i;
int nextIDX = index - 1;
//
// Prev Bar ...
XOHCL iPrevBar;
result = iPrevBar.Init(
symbol,
period,
prevIDX //
);
if (!result)
{
break;
}
//
// Next Bar ...
XOHCL iNextBar;
result = iNextBar.Init(
symbol,
period,
nextIDX //
);
if (!result)
{
break;
}
//
result = bar.high >= iPrevBar.high &&
bar.high >= iNextBar.high;
if (!result)
{
break;
}
}
//
return result;
}
// //
protected: protected:
// //
+157 -4
View File
@@ -870,6 +870,7 @@ class XCZoneObject : public XCBaseObject
* @param name: String, Specified Object Identifier on Chart ... * @param name: String, Specified Object Identifier on Chart ...
* @param window: Integer, Specified Chart Window ID ... * @param window: Integer, Specified Chart Window ID ...
* @param zone: XCZone instance ... * @param zone: XCZone instance ...
* @param prefix: String ...
* *
* @return ( bool ) * @return ( bool )
*/ */
@@ -877,7 +878,8 @@ class XCZoneObject : public XCBaseObject
long chart_id, long chart_id,
string name, string name,
int window, int window,
XCZone &zone // XCZone &zone,
string prefix = NULL //
) )
{ {
// //
@@ -897,17 +899,28 @@ class XCZoneObject : public XCBaseObject
} }
// //
if (IsValid(prefix))
{
name = prefix + "_" + name;
}
//
datetime from = zone.From();
datetime to = NormalizeTime(zone.To()); datetime to = NormalizeTime(zone.To());
//
double upper = zone.Upper();
double lower = zone.Lower();
// //
result = mRect.Create( result = mRect.Create(
chart_id, chart_id,
name, name,
window, window,
zone.From(), from,
zone.Upper(), upper,
to, to,
zone.Lower() // lower //
); );
// //
@@ -973,6 +986,16 @@ class XCZoneObject : public XCBaseObject
mRect.Style(value); mRect.Style(value);
} }
/**
* Set Zone Fill ...
*
* @param value: Boolean ...
*/
void ZoneFill(bool value)
{
mRect.Fill(value);
}
// //
private: private:
// //
@@ -982,3 +1005,133 @@ class XCZoneObject : public XCBaseObject
}; };
// //
// Support Zone ...
class XCSupportZoneObject : public XCZoneObject
{
//
public:
//
/**
* Creator ...
*
* @param chart_id: Long, Specified Chart ID ...
* @param window: Integer, Specified Chart Window ID ...
* @param zone: XCSupportZone instance ...
* @param prefix: String ...
*
* @return ( bool )
*/
bool Create(
long chart_id,
int window,
XCSupportZone &zone,
string prefix = NULL //
)
{
//
bool result = false;
//
result = zone.IsValid();
if (!result)
{
return result;
}
//
string name = zone.GetTag();
//
result = CreateByZone(
chart_id,
name,
window,
zone,
prefix //
);
//
return result;
}
//
// Virtual ...
/**
* Retrieve Object Type ...
*
* @return ( ENUM_XCHARTOBJECTS )
*/
virtual ENUM_XCHARTOBJECTS Type()
{
return X_SUPPORT_ZONE_OBJ;
}
};
//
// Resistance Zone ...
class XCResistanceZoneObject : public XCZoneObject
{
//
public:
//
/**
* Creator ...
*
* @param chart_id: Long, Specified Chart ID ...
* @param window: Integer, Specified Chart Window ID ...
* @param zone: XCResistanceZone instance ...
* @param prefix: String ...
*
* @return ( bool )
*/
bool Create(
long chart_id,
int window,
XCResistanceZone &zone,
string prefix = NULL //
)
{
//
bool result = false;
//
result = zone.IsValid();
if (!result)
{
return result;
}
//
string name = zone.GetTag();
//
result = CreateByZone(
chart_id,
name,
window,
zone,
prefix //
);
//
return result;
}
//
// Virtual ...
/**
* Retrieve Object Type ...
*
* @return ( ENUM_XCHARTOBJECTS )
*/
virtual ENUM_XCHARTOBJECTS Type()
{
return X_RESISTANCE_ZONE_OBJ;
}
};
//
+444 -19
View File
@@ -317,6 +317,36 @@ class XCPOIDetector : public XCBaseAlert
mRejectionBarShadowPercent = value; mRejectionBarShadowPercent = value;
} }
//
// Support and Resistance Zone(s) ...
/**
* Get Support and Resistance Range for Verification ...
*
* @return ( int )
*/
int SupportAndResistanceRange()
{
return mSupportAndResistanceRange;
}
/**
* Set Support and Resistance Range for Verification ...
*
* @param value: Integer ...
*/
void SupportAndResistanceRange(int value)
{
//
if (value < 2)
{
value = 2;
}
//
mSupportAndResistanceRange = value;
}
// //
// Actions ... // Actions ...
@@ -574,6 +604,78 @@ class XCPOIDetector : public XCBaseAlert
); );
} }
//
// Support and Resistance Zones ...
int supResRange = SupportAndResistanceRange();
if (supResRange > 0)
{
//
XOHCL supResBar;
isInited = supResBar.Init(
symbol,
period,
zIndex + supResRange //
);
if (isInited)
{
//
// Support Zones ...
isDetected = DetectSupportZone(supResBar);
if (isDetected)
{
//
ENUM_XPOI_EVENTS event = X_SUPPORT_ZONE_DETECTED;
XCSupportZone *param;
bool hasItem = GetLastItem(
param,
mSupportZones //
);
if (hasItem)
{
//
NotifyEventListeners(
event,
param //
);
}
//
Add(
event,
state //
);
}
//
// Resistance Zones ...
isDetected = DetectResistanceZone(supResBar);
if (isDetected)
{
//
ENUM_XPOI_EVENTS event = X_RESISTANCE_ZONE_DETECTED;
XCResistanceZone *param;
bool hasItem = GetLastItem(
param,
mResistanceZones //
);
if (hasItem)
{
//
NotifyEventListeners(
event,
param //
);
}
//
Add(
event,
state //
);
}
}
}
// //
CleanupUnusedPOIs(); CleanupUnusedPOIs();
@@ -658,6 +760,10 @@ class XCPOIDetector : public XCBaseAlert
// //
Clean(mBullishRejectionBars); Clean(mBullishRejectionBars);
Clean(mBearishRejectionBars); Clean(mBearishRejectionBars);
//
Clean(mSupportZones);
Clean(mResistanceZones);
} }
/** /**
@@ -700,6 +806,9 @@ class XCPOIDetector : public XCBaseAlert
// //
RejectionBarExtendRange(0); RejectionBarExtendRange(0);
RejectionBarShadowPercent(55); RejectionBarShadowPercent(55);
//
SupportAndResistanceRange(7);
} }
// //
@@ -764,6 +873,10 @@ class XCPOIDetector : public XCBaseAlert
int bullishRejectionBarsCount = 0; int bullishRejectionBarsCount = 0;
int bearishRejectionBarsCount = 0; int bearishRejectionBarsCount = 0;
//
int supportZonesCount = 0;
int resistanceZonesCount = 0;
// //
bool canContinue = true; bool canContinue = true;
@@ -818,6 +931,22 @@ class XCPOIDetector : public XCBaseAlert
ArrayReverse(mBearishRejectionBars); ArrayReverse(mBearishRejectionBars);
} }
//
// Support Zone(s) ...
supportZonesCount = DetectRequiredSupportZones(barIndex);
if (supportZonesCount == requiredPOIs)
{
ArrayReverse(mSupportZones);
}
//
// Resistance Zone(s) ...
resistanceZonesCount = DetectRequiredResistanceZones(barIndex);
if (resistanceZonesCount == requiredPOIs)
{
ArrayReverse(mResistanceZones);
}
// //
canContinue = canContinue =
// //
@@ -849,6 +978,16 @@ class XCPOIDetector : public XCBaseAlert
// Bearish Rejection Bars ... // Bearish Rejection Bars ...
bearishRejectionBarsCount < requiredPOIs bearishRejectionBarsCount < requiredPOIs
// //
||
//
// Support Zones ...
supportZonesCount < requiredPOIs
//
||
//
// Resistance Zones ...
resistanceZonesCount < requiredPOIs
//
; ;
if (canContinue) if (canContinue)
{ {
@@ -1863,16 +2002,16 @@ class XCPOIDetector : public XCBaseAlert
mBullishRejectionBars // mBullishRejectionBars //
); );
// // //
XCBullishRejectionObject *iObj; // XCBullishRejectionObject *iObj;
bool isCreated = mDrawer.CreateBullishRejectionBar( // bool isCreated = mDrawer.CreateBullishRejectionBar(
rejectionBar, // rejectionBar,
iObj // // iObj //
); // );
if (isCreated) // if (isCreated)
{ // {
AddObjectIfNotExists(iObj); // AddObjectIfNotExists(iObj);
} // }
} }
} }
@@ -1995,15 +2134,15 @@ class XCPOIDetector : public XCBaseAlert
); );
// //
XCBearishRejectionObject *iObj; // XCBearishRejectionObject *iObj;
bool isCreated = mDrawer.CreateBearishRejectionBar( // bool isCreated = mDrawer.CreateBearishRejectionBar(
rejectionBar, // rejectionBar,
iObj // // iObj //
); // );
if (isCreated) // if (isCreated)
{ // {
AddObjectIfNotExists(iObj); // AddObjectIfNotExists(iObj);
} // }
} }
} }
@@ -2072,11 +2211,297 @@ class XCPOIDetector : public XCBaseAlert
return result; return result;
} }
//
// Support and Resistance Zone ...
int mSupportAndResistanceRange; // Support and Resistance Range for Verification ...
// //
// Support Zone(s) ... // Support Zone(s) ...
XCSupportZone *mSupportZones[]; // Holds Founded Support Zones ...
/**
* Detect Support Zone ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool DetectSupportZone(XOHCL &bar)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int range = SupportAndResistanceRange();
int barIndex = bar.Index();
result = range > 0 &&
barIndex >= range;
if (!result)
{
return result;
}
//
result = mBarAnalyser.IsSupport(
bar,
range //
);
if (result)
{
//
XCSupportZone *support;
support = new XCSupportZone();
result = support.Init(
bar,
range //
);
//
if (result)
{
//
datetime cTime = TimeCurrent();
support.To(cTime);
//
Add(
support,
mSupportZones //
);
// //
// XCSupportZoneObject *iObj;
// bool isCreated = mDrawer.CreateSupportZone(
// support,
// iObj //
// );
// if (isCreated)
// {
// AddObjectIfNotExists(iObj);
// }
}
}
//
return result;
}
/**
* Detect Required Support Zones ...
*
* @param barIndex: Integer Start bar index ...
* 0 is Default ...
*
* @return ( int )
*/
int DetectRequiredSupportZones(int barIndex = 0)
{
//
int result = 0;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int required = MaxNumberOfRequiredPOIs();
if (required <= 0)
{
return result;
}
//
int count = ArraySize(mSupportZones);
if (count >= required)
{
//
result = count;
return result;
}
//
int range = SupportAndResistanceRange();
if (range < 0 || barIndex < range)
{
return result;
}
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
XOHCL bar;
bool isInited = bar.Init(
symbol,
period,
barIndex //
);
if (!isInited)
{
return result;
}
//
DetectSupportZone(bar);
//
result = ArraySize(mSupportZones);
//
return result;
}
// //
// Resistance Zone(s) ... // Resistance Zone(s) ...
XCResistanceZone *mResistanceZones[]; // Holds Founded Resistance Zones ...
/**
* Detect Resistance Zone ...
*
* @param bar: XOHCL instance ...
*
* @return ( bool )
*/
bool DetectResistanceZone(XOHCL &bar)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int range = SupportAndResistanceRange();
int barIndex = bar.Index();
result = range > 0 &&
barIndex >= range;
if (!result)
{
return result;
}
//
result = mBarAnalyser.IsResistance(
bar,
range //
);
if (result)
{
//
XCResistanceZone *resistance;
resistance = new XCResistanceZone();
result = resistance.Init(
bar,
range //
);
//
if (result)
{
//
Add(
resistance,
mResistanceZones //
);
// //
// XCResistanceZoneObject *iObj;
// bool isCreated = mDrawer.CreateResistanceZone(
// resistance,
// iObj //
// );
// if (isCreated)
// {
// AddObjectIfNotExists(iObj);
// }
}
}
//
return result;
}
/**
* Detect Required Resistance Zones ...
*
* @param barIndex: Integer Start bar index ...
* 0 is Default ...
*
* @return ( int )
*/
int DetectRequiredResistanceZones(int barIndex = 0)
{
//
int result = 0;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
int required = MaxNumberOfRequiredPOIs();
if (required <= 0)
{
return result;
}
//
int count = ArraySize(mResistanceZones);
if (count >= required)
{
//
result = count;
return result;
}
//
int range = SupportAndResistanceRange();
if (range < 0 || barIndex < range)
{
return result;
}
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
XOHCL bar;
bool isInited = bar.Init(
symbol,
period,
barIndex //
);
if (!isInited)
{
return result;
}
//
DetectResistanceZone(bar);
//
result = ArraySize(mResistanceZones);
//
return result;
}
// //
// Supply Zone(s) ... // Supply Zone(s) ...
+131 -2
View File
@@ -1659,6 +1659,135 @@ class XCPOIDrawer : public XCBase
return result; return result;
} }
//
// Support and Resistance ...
/**
* Create Support Object ...
*
* @param zone: XCSupportZone instance ...
* @param object: XCSupportZoneObject pointer ...
*
* @return ( bool )
*/
bool CreateSupportZone(
XCSupportZone &zone,
XCSupportZoneObject *&object //
)
{
//
bool result = false;
//
object = NULL;
//
result =
zone.IsValid();
if (!result)
{
return result;
}
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
bool fill = SupportZoneFill();
int width = SupportZoneWidth();
color crl = SupportZoneColor();
ENUM_LINE_STYLE style = SupportZoneStyle();
//
object = new XCSupportZoneObject();
result = object.Create(
chartID,
window,
zone,
prefix //
);
//
if (!result)
{
return result;
}
//
object.ZoneFill(fill);
object.ZoneColor(crl);
object.ZoneWidth(width);
object.ZoneStyle(style);
//
return result;
}
/**
* Create Resistance Object ...
*
* @param zone: XCResistanceZone instance ...
* @param object: XCResistanceZoneObject pointer ...
*
* @return ( bool )
*/
bool CreateResistanceZone(
XCResistanceZone &zone,
XCResistanceZoneObject *&object //
)
{
//
bool result = false;
//
object = NULL;
//
result =
zone.IsValid();
if (!result)
{
return result;
}
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
bool fill = ResistanceZoneFill();
int width = ResistanceZoneWidth();
color crl = ResistanceZoneColor();
ENUM_LINE_STYLE style = ResistanceZoneStyle();
//
object = new XCResistanceZoneObject();
result = object.Create(
chartID,
window,
zone,
prefix //
);
//
if (!result)
{
return result;
}
//
object.ZoneFill(fill);
object.ZoneColor(crl);
object.ZoneWidth(width);
object.ZoneStyle(style);
//
return result;
}
// //
protected: protected:
// //
@@ -1705,13 +1834,13 @@ class XCPOIDrawer : public XCBase
BearishRejectionBarColor(clrMagenta); BearishRejectionBarColor(clrMagenta);
// //
SupportZoneFill(true); SupportZoneFill(false);
SupportZoneWidth(1); SupportZoneWidth(1);
SupportZoneStyle(STYLE_DOT); SupportZoneStyle(STYLE_DOT);
SupportZoneColor(clrLime); SupportZoneColor(clrLime);
// //
ResistanceZoneFill(true); ResistanceZoneFill(false);
ResistanceZoneWidth(1); ResistanceZoneWidth(1);
ResistanceZoneStyle(STYLE_DOT); ResistanceZoneStyle(STYLE_DOT);
ResistanceZoneColor(clrRed); ResistanceZoneColor(clrRed);
+87 -31
View File
@@ -319,7 +319,7 @@ class XCZone : public XCBasePOI
// //
mUpper > 0 && mUpper > 0 &&
mLower > 0 && mLower > 0 &&
mUpper > mLower mUpper >= mLower
// //
; ;
@@ -637,6 +637,12 @@ class XCBarZone : public XCZone
// //
result = IsValidBarZone(); result = IsValidBarZone();
if (result)
{
//
From(bar.time);
To(TimeCurrent());
}
// //
return result; return result;
@@ -674,6 +680,46 @@ class XCBarZone : public XCZone
return result; return result;
} }
/**
* Set From Date ...
*
* @param value: DateTime ...
*/
void From(datetime value)
{
//
if (!IsValidBarZone())
{
return;
}
//
value = NormalizeTime(value);
//
mFrom = value;
}
/**
* Set To Date ...
*
* @param value: DateTime ...
*/
void To(datetime value)
{
//
if (!IsValidBarZone())
{
return;
}
//
value = NormalizeTime(value);
//
mTo = value;
}
// //
// Overrides ... // Overrides ...
@@ -688,38 +734,12 @@ class XCBarZone : public XCZone
datetime From() override datetime From() override
{ {
// return mFrom;
datetime result = NULL;
//
if (!IsValidBarZone())
{
return result;
}
//
result = mBar.time;
//
return result;
} }
datetime To() override datetime To() override
{ {
// return mTo;
datetime result = NULL;
//
if (!IsValidBarZone())
{
return result;
}
//
result = TimeCurrent();
//
return result;
} }
string GetTag() override string GetTag() override
@@ -795,6 +815,8 @@ class XCBarZone : public XCZone
private: private:
// //
// Props ... // Props ...
datetime mFrom;
datetime mTo;
// //
}; };
@@ -1450,11 +1472,13 @@ class XCSupportZone : public XCBarZone
* Initialize POI ... * Initialize POI ...
* *
* @param bar: XOHCL instance ... * @param bar: XOHCL instance ...
* @param range: Integer, Detection Range ...
* *
* @return ( bool ) * @return ( bool )
*/ */
bool Init( bool Init(
XOHCL &bar // XOHCL &bar,
int range = 0 //
) )
{ {
// //
@@ -1481,6 +1505,21 @@ class XCSupportZone : public XCBarZone
// //
result = IsValid(); result = IsValid();
if (result &&
range > 0)
{
//
datetime time = bar.time;
int periodSeconds = PeriodSeconds(bar.period);
//
datetime from = (datetime)((int)time - (range * periodSeconds));
datetime to = (datetime)((int)time + (range * periodSeconds));
//
From(from);
To(to);
}
// //
return result; return result;
@@ -1543,11 +1582,13 @@ class XCResistanceZone : public XCBarZone
* Initialize POI ... * Initialize POI ...
* *
* @param bar: XOHCL instance ... * @param bar: XOHCL instance ...
* @param range: Integer, Detection Range ...
* *
* @return ( bool ) * @return ( bool )
*/ */
bool Init( bool Init(
XOHCL &bar // XOHCL &bar,
int range = 0 //
) )
{ {
// //
@@ -1574,6 +1615,21 @@ class XCResistanceZone : public XCBarZone
// //
result = IsValid(); result = IsValid();
if (result &&
range > 0)
{
//
datetime time = bar.time;
int periodSeconds = PeriodSeconds(bar.period);
//
datetime from = (datetime)((int)time - (range * periodSeconds));
datetime to = (datetime)((int)time + (range * periodSeconds));
//
From(from);
To(to);
}
// //
return result; return result;