Last Works ...

This commit is contained in:
2024-11-18 05:10:49 +03:30
parent 649e373163
commit 72c4446620
4 changed files with 1356 additions and 45 deletions
+70
View File
@@ -0,0 +1,70 @@
//
// Peaks ...
int peaksCount = ArraySize(conditions.peaks);
if (IsValidSize(peaksCount))
{
//
for (int i = 0; i < peaksCount; i++)
{
//
XPVPivot iPivot = conditions.peaks[i];
//
XCXPVPivotObject *iObj;
iObj = new XCXPVPivotObject();
//
bool isCreated = iObj.Create(
mPOIDrawer.ChartIdentification(),
mPOIDrawer.SubWindowIdentification(),
iPivot //
);
if (isCreated)
{
//
iObj.PivotWidth(1);
iObj.PivotFill(false);
iObj.PivotColor(clrAqua);
iObj.PivotStyle(STYLE_SOLID);
//
AddObjectIfNotExists(iObj);
}
}
}
//
// Vales ...
int valesCount = ArraySize(conditions.vales);
if (IsValidSize(valesCount))
{
//
for (int i = 0; i < valesCount; i++)
{
//
XPVPivot iPivot = conditions.vales[i];
//
XCXPVPivotObject *iObj;
iObj = new XCXPVPivotObject();
//
bool isCreated = iObj.Create(
mPOIDrawer.ChartIdentification(),
mPOIDrawer.SubWindowIdentification(),
iPivot //
);
if (isCreated)
{
//
iObj.PivotWidth(1);
iObj.PivotFill(false);
iObj.PivotStyle(STYLE_SOLID);
iObj.PivotColor(clrMagenta);
//
AddObjectIfNotExists(iObj);
}
}
}
@@ -0,0 +1,170 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XChartObjects
// Description: provides all require Chart Objects ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
#property strict
//
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
#include "../Libraries/x-121.smc.lib.mq5"
//
// Definitions ...
enum ENUM_X121SMC_CHARTOBJECTS
{
X_XPVPIVOT_OBJ, // XPVPivot Object ...
};
//
// Implementations ...
//
// XPVPivot Object ...
class XCXPVPivotObject : public XCBaseObject
{
//
public:
//
/**
* Creator ...
*
* @param chart_id: Long, Specified Chart ID ...
* @param window: Integer, Specified Chart Window ID ...
* @param pivot: XPVPivot instance ...
* @param prefix: String ...
*
* @return ( bool )
*/
bool Create(
long chart_id,
int window,
XPVPivot &pivot,
string prefix = NULL //
)
{
//
bool result = false;
//
result = pivot.IsValid();
if (!result)
{
return result;
}
//
string name = pivot.GetTag();
if (IsValid(prefix))
{
name = prefix + "_" + name;
}
//
result = mRect.Create(
chart_id,
name,
window,
pivot.from,
pivot.upper,
pivot.to,
pivot.lower //
);
//
if (result)
{
ObjName(name);
}
//
return result;
}
//
// Getter(s) / Setter(s) ...
/**
* Set Pivot Width ...
*
* @param value: Integer ...
*/
void PivotWidth(int value)
{
//
if (value < 1)
{
value = 1;
}
//
mRect.Width(value);
}
/**
* Set Pivot Color ...
*
* @param value: Color ...
*/
void PivotColor(color value)
{
mRect.Color(value);
}
/**
* Set Pivot Style ...
*
* @param value: ENUM_LINE_STYLE member ...
*/
void PivotStyle(ENUM_LINE_STYLE value)
{
mRect.Style(value);
}
/**
* Set Pivot Fill ...
*
* @param value: Boolean ...
*/
void PivotFill(bool value)
{
mRect.Fill(value);
}
//
// Virtual ...
/**
* Retrieve Object Type ...
*
* @return ( ENUM_X121SMC_CHARTOBJECTS )
*/
virtual ENUM_X121SMC_CHARTOBJECTS Type()
{
return X_XPVPIVOT_OBJ;
}
//
private:
//
//
// Props ...
CChartObjectRectangle mRect;
};
+693 -1
View File
@@ -22,9 +22,9 @@
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
#include "../../Helpers/x-saherelm.xpv.helper.mq5"
#include "../../Helpers/x-saherelm.x3ma.helper.mq5"
#include "../../Helpers/x-saherelm.x3vwap.helper.mq5"
#include "../../Helpers/x-saherelm.xpv.helper.mq5"
#include "../../Libraries/x-saherelm.common.lib.mq5"
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
#include "../../Libraries/x-saherelm.x-trade.lib.mq5"
@@ -34,6 +34,339 @@
const string X121SMCStrategyToken = "X121SMC";
enum ENUM_XPV_PIVOTS
{
XPV_NONE,
XPV_PEAK,
XPV_VALE,
};
struct XPVPivot
{
//
string symbol;
ENUM_TIMEFRAMES period;
//
double upper;
double lower;
//
datetime from;
datetime to;
//
int repetition;
//
ENUM_XPV_PIVOTS type;
//
XPVPivot()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
upper = 0;
lower = 0;
//
to = NULL;
from = NULL;
symbol = NULL;
period = NULL;
//
repetition = 0;
//
type = XPV_NONE;
}
/**
* Validation ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
IsValid(to) &&
IsValid(from) &&
IsValid(symbol) &&
IsValid(period) &&
repetition > 0 &&
type != XPV_NONE &&
(upper > 0 || lower > 0)
//
;
//
return result;
}
/**
* Check Pivot is Peak ...
*
* @return ( bool )
*/
bool IsPeak()
{
//
bool result = false;
//
result = IsValid() &&
type == XPV_PEAK;
//
return result;
}
/**
* Check Pivot is Vale ...
*
* @return ( bool )
*/
bool IsVale()
{
//
bool result = false;
//
result = IsValid() &&
type == XPV_VALE;
//
return result;
}
/**
* Calculate Lower for Peaks ...
*
* @return ( double )
*/
double CalculateLower()
{
//
double result = 0;
//
if (!IsValid() ||
!IsPeak())
{
return result;
}
//
int fromIndex = iBarShift(
symbol,
period,
from //
);
//
int toIndex = iBarShift(
symbol,
period,
to //
);
//
int count =
fromIndex - toIndex;
//
int llIDX = iLowest(
symbol,
period,
MODE_LOW,
count,
toIndex //
);
//
result =
iLow(
symbol,
period,
llIDX //
);
//
return result;
}
/**
* Calculate Upper for Vales ...
*
* @return ( double )
*/
double CalculateUpper()
{
//
double result = 0;
//
if (!IsValid() ||
!IsVale())
{
return result;
}
//
int fromIndex = iBarShift(
symbol,
period,
from //
);
//
int toIndex = iBarShift(
symbol,
period,
to //
);
//
int count =
fromIndex - toIndex;
//
int hhIDX = iHighest(
symbol,
period,
MODE_HIGH,
count,
toIndex //
);
//
result =
iHigh(
symbol,
period,
hhIDX //
);
//
return result;
}
/**
* Calculate Range of Pivot ...
*
* @return ( double )
*/
double CalculateRange()
{
//
double result = 0;
//
if (!IsValid() ||
upper <= 0 ||
lower <= 0)
{
return result;
}
//
result = upper - lower;
//
return result;
}
/**
* Calculate Middle of Pivot ...
* Used for
* @return ( double )
*/
double CalculateMid()
{
//
double result = 0;
//
double range = CalculateRange();
if (range <= 0)
{
return result;
}
//
result = lower + (range / 2);
//
return result;
}
//
/**
* Get Unique Identifier ...
*
* @return ( string )
*/
string GetTag()
{
//
string result = NULL;
//
if (!IsValid())
{
return result;
}
//
string hash = symbol + "_" +
ToString(period) + "_" +
ToString(upper) + "," +
ToString(lower) + "_" +
ToString(from) + "," +
ToString(to);
hash = ToMD5(hash);
//
string typeStr =
type == XPV_PEAK
? "Peak"
: "Vale";
//
result =
//
"XPV_" +
typeStr + "_" +
symbol + "_" +
ToString(period) +
"_" + hash
//
;
//
return result;
}
//
};
//
// Model Signalling Conditions ...
struct X121SMCStrategyConditions
@@ -43,6 +376,9 @@ struct X121SMCStrategyConditions
ENUM_TIMEFRAMES period;
datetime time;
//
XPVPivot orderFlow[];
//
XPVConditions xpvConditions;
X3MAConditions x3maConditions;
@@ -163,6 +499,9 @@ struct X121SMCStrategyConditions
x3maConditions.Clean();
x3vwapConditions.Clean();
//
Clean(orderFlow);
//
// D1 ...
@@ -519,4 +858,357 @@ typedef void (*TOnX121SMCSignal)(
X121SMCStrategyConditions &conditions //
);
//
// Extentions ...
/**
* Find Oldest Pivot Index ...
*
* @param pivots: XPVPivot instance ...
* @return ( int )
*/
int FindOldestPivotIndex(
XPVPivot &pivots[] //
)
{
//
int result = -1;
//
int count = ArraySize(pivots);
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
XPVPivot iPivot = pivots[i];
//
bool isOldest = true;
for (int j = 0; j < count; j++)
{
//
XPVPivot jPivot = pivots[j];
//
isOldest = iPivot.from <= jPivot.from;
if (!isOldest)
{
break;
}
}
//
if (isOldest)
{
//
result = i;
break;
}
}
//
return result;
}
/**
* Sort Pivots Based On From Date ...
*
* @param pivots: XPVPivot instance Collection reference ...
*/
void SortPivots(
XPVPivot &pivots[] //
)
{
//
XPVPivot tmp[];
Copy(
pivots,
tmp //
);
//
Clean(pivots);
//
while (ArraySize(tmp) > 0)
{
//
if (ArraySize(tmp) == 1)
{
//
AddRef(
tmp[0],
pivots //
);
//
ArrayRemove(
tmp,
0,
1);
}
else
{
//
int idx = FindOldestPivotIndex(tmp);
if (IsValidIndex(idx))
{
//
AddRef(
tmp[idx],
pivots //
);
//
ArrayRemove(
tmp,
idx,
1 //
);
}
}
}
//
Clean(tmp);
}
bool IsPivotBreaked(
XPVPivot &pivot,
XPVPivot &pivots[] //
)
{
//
bool result = false;
//
result = pivot.IsValid();
if (!result)
{
return result;
}
//
int count = ArraySize(pivots);
result = IsValidSize(pivots);
if (!result)
{
return result;
}
//
// For Peaks Highs Must not Broked ...
// For Vales Lows Must not Broked ...
bool isPeak = pivot.IsPeak();
//
for (int i = 0; i < count; i++)
{
//
XPVPivot iPivot = pivots[i];
//
result = isPeak
? iPivot.upper > pivot.upper
: iPivot.lower < pivot.lower;
if (result)
{
break;
}
}
//
return result;
}
/**
* Filter Broken Pivots for Detect Order Flow ...
*
* @param pivots: XPVPivot instance Collection reference ...
*/
void FilterBrokenPivots(
XPVPivot &pivots[] //
)
{
//
XPVPivot tmp[];
Copy(
pivots,
tmp //
);
//
Clean(pivots);
//
while (ArraySize(tmp) > 0)
{
//
if (ArraySize(tmp) == 1)
{
//
AddRef(
tmp[0],
pivots //
);
//
ArrayRemove(
tmp,
0,
1 //
);
}
else
{
//
XPVPivot pivot = tmp[0];
//
ArrayRemove(
tmp,
0,
1 //
);
//
bool isBreaked = IsPivotBreaked(
pivot,
tmp //
);
if (!isBreaked)
{
//
AddRef(
pivot,
pivots //
);
}
}
}
//
Clean(tmp);
}
/**
* Calculate Order Flow Direction ...
*
* @param orderFlow: XPVPivot instance Collection reference ...
* @param dir: ENUM_X_DIRECTION member reference, Hold's Calculated Direction ...
*
* @return ( bool )
*/
bool DetectPivotDirection(
XPVPivot &orderFlow[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
dir = X_DIRECTION_NONE;
//
int count = ArraySize(orderFlow);
result = IsValidSize(count);
if (!result)
{
return result;
}
//
// For Bullish Direction all Exists lowers must be Greater or Equal Prev ...
bool isBullish = false;
bool canLookupForBullish = true;
//
// For Bearish Direction all Exists uppers must be Lesser or Equal Prev ...
bool isBearish = false;
bool canLookupForBearish = true;
//
for (int i = 0; i < count; i++)
{
//
XPVPivot iPivot = orderFlow[i];
//
XPVPivot tmp[];
Copy(
orderFlow,
tmp //
);
ArrayRemove(
tmp,
0,
i + 1 //
);
//
int tmpCount = ArraySize(tmp);
if (IsValidSize(tmpCount))
{
//
for (int j = 0; j < tmpCount; j++)
{
//
XPVPivot jPivot = tmp[j];
//
// Check Bullish Direction ...
isBullish =
canLookupForBullish &&
jPivot.lower >= iPivot.lower;
if (!isBullish)
{
canLookupForBullish = false;
}
//
// Check Bearish Direction ...
isBearish =
canLookupForBearish &&
jPivot.upper <= iPivot.upper;
if (!isBearish)
{
canLookupForBearish = false;
}
//
if (!canLookupForBullish &&
!canLookupForBearish)
{
break;
}
}
}
Clean(tmp);
}
//
if (isBullish &&
!isBearish)
{
dir = X_DIRECTION_BULLISH;
}
else if (isBearish &&
!isBullish)
{
dir = X_DIRECTION_BEARISH;
}
//
result = dir != X_DIRECTION_NONE;
//
return result;
}
//
@@ -174,50 +174,6 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
return result;
}
//
conditions.symbol = _symbol;
conditions.period = _period;
conditions.time = TimeCurrent();
//
int conditionsLoopback = 7;
//
// XPV ...
result = xpvHelper.GetConditions(
conditions.xpvConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// X3MA ...
result = x3maHelper.GetConditions(
conditions.x3maConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// X3VWAP ...
result = x3vwapHelper.GetConditions(
conditions.x3vwapConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// Try to Implement SMC Based Conditions ...
result = DetectConditions(conditions);
@@ -371,6 +327,137 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
//
bool result = false;
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
conditions.symbol = symbol;
conditions.period = period;
conditions.time = TimeCurrent();
//
int conditionsLoopback = 7;
//
// XPV ...
result = xpvHelper.GetConditions(
conditions.xpvConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// X3MA ...
result = x3maHelper.GetConditions(
conditions.x3maConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// X3VWAP ...
result = x3vwapHelper.GetConditions(
conditions.x3vwapConditions,
cIndex,
conditionsLoopback //
);
if (!result)
{
return result;
}
//
// Detect Swing Highs and Lows Based On XPV ...
//
int samePivots = 40;
int requiredPivots = 10;
//
DetectPVPivots(
cIndex,
samePivots,
requiredPivots,
conditions.orderFlow //
);
//
int orderFlowCount = ArraySize(conditions.orderFlow);
if (IsValidSize(orderFlowCount))
{
//
for (int i = 0; i < orderFlowCount; i++)
{
//
XPVPivot iPivot = conditions.orderFlow[i];
//
XCXPVPivotObject *iObj;
iObj = new XCXPVPivotObject();
bool isCreated = iObj.Create(
mPOIDrawer.ChartIdentification(),
mPOIDrawer.SubWindowIdentification(),
iPivot //
);
if (isCreated)
{
//
if (iPivot.IsPeak())
{
//
iObj.PivotWidth(1);
iObj.PivotFill(false);
iObj.PivotColor(clrAqua);
iObj.PivotStyle(STYLE_SOLID);
}
//
if (iPivot.IsVale())
{
//
iObj.PivotWidth(1);
iObj.PivotFill(false);
iObj.PivotStyle(STYLE_SOLID);
iObj.PivotColor(clrMagenta);
}
//
AddObjectIfNotExists(iObj);
}
}
}
//
result = IsValidSize(ArraySize(conditions.orderFlow));
if (!result)
{
return result;
}
//
// Filter Peaks and Vales ...
if (result)
{
Print("Result: ", result);
}
return false;
//
// Detect Market Structures ...
@@ -820,6 +907,298 @@ class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
return result;
}
/**
* Detect XPV Based POI(s) ...
*
* @param barIndex: Start Bar Index ...
* @param minRepetition: minimum Repeate of POI for Validation ...
* @param requiredPivots: Number of Min Requirement POI(s) ...
* @param peaks: XPVPivot instance Array Reference ...
* @param vales: XPVPivot instance Array Reference ...
* @param maxAllowedLoopbackBars: Integer, Max Allowed Loopback Bars ...
*
* @return ( bool )
*/
bool DetectPVPivots(
int barIndex,
int minRepetition,
int requiredPivots,
XPVPivot &orderFlow[], // OrderFlows ...
int maxAllowedLoopbackBars = 576 //
)
{
//
bool result = false;
//
if (maxAllowedLoopbackBars <= 0)
{
maxAllowedLoopbackBars = 1000;
}
//
int start = barIndex;
int end = start + maxAllowedLoopbackBars;
//
Clean(orderFlow);
//
result = minRepetition > 0 &&
requiredPivots > 0;
if (!result)
{
return result;
}
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
double peak = 0;
XPVPivot peaks[];
int peakRepeate = 0;
int peakToBarIndex = 0;
int peakFromBarIndex = 0;
//
double vale = 0;
XPVPivot vales[];
int valeRepeate = 0;
int valeToBarIndex = 0;
int valeFromBarIndex = 0;
//
bool canLookupPeak = true;
bool canLookupVale = true;
bool canLookup = true;
while (canLookup)
{
//
// Check Peak ...
double iPeak = xpvHelper.GetPeak(barIndex);
if (iPeak != peak)
{
//
if (peak != 0 &&
peakRepeate >= minRepetition)
{
//
bool isExists = false;
int count = ArraySize(peaks);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XPVPivot iPivot = peaks[i];
//
if (iPivot.upper == iPeak)
{
//
isExists = true;
break;
}
}
}
if (!isExists)
{
//
XPVPivot iPivot;
//
iPivot.lower = 0;
iPivot.upper = peak;
iPivot.symbol = symbol;
iPivot.period = period;
iPivot.type = XPV_PEAK;
iPivot.repetition = peakRepeate;
iPivot.to = iTime(
symbol,
period,
peakToBarIndex //
);
iPivot.from = iTime(
symbol,
period,
peakFromBarIndex //
);
//
iPivot.lower = iPivot.CalculateLower();
//
bool isValid = iPivot.IsValid();
if (isValid)
{
//
AddRef(
iPivot,
peaks //
);
}
}
}
//
peak = iPeak;
peakRepeate = 0;
peakFromBarIndex = 0;
peakToBarIndex = barIndex;
}
else if (iPeak == peak)
{
//
peakRepeate++;
peakFromBarIndex = barIndex;
}
//
// Check Vale ...
double iVale = xpvHelper.GetVale(barIndex);
if (iVale != vale)
{
//
if (vale != 0 &&
valeRepeate >= minRepetition)
{
//
bool isExists = false;
int count = ArraySize(vales);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XPVPivot iPivot = vales[i];
//
if (iPivot.lower == iVale)
{
//
isExists = true;
break;
}
}
}
if (!isExists)
{
//
XPVPivot iPivot;
//
iPivot.upper = 0;
iPivot.lower = vale;
iPivot.symbol = symbol;
iPivot.period = period;
iPivot.type = XPV_VALE;
iPivot.repetition = valeRepeate;
iPivot.to = iTime(
symbol,
period,
valeToBarIndex //
);
iPivot.from = iTime(
symbol,
period,
valeFromBarIndex //
);
//
iPivot.upper = iPivot.CalculateUpper();
//
bool isValid = iPivot.IsValid();
if (isValid)
{
//
AddRef(
iPivot,
vales //
);
}
}
}
//
vale = iVale;
valeRepeate = 0;
valeFromBarIndex = 0;
valeToBarIndex = barIndex;
}
else if (iVale == vale)
{
//
valeRepeate++;
valeFromBarIndex = barIndex;
}
//
canLookupPeak = ArraySize(peaks) < requiredPivots;
canLookupVale = ArraySize(vales) < requiredPivots;
canLookup = barIndex < end &&
(canLookupPeak ||
canLookupVale);
if (canLookup)
{
barIndex++;
}
}
//
result = IsValidSize(ArraySize(peaks)) ||
IsValidSize(ArraySize(vales));
if (!result)
{
return result;
}
//
// Detect Order Flow ...
Copy(
peaks,
orderFlow,
false //
);
Copy(
vales,
orderFlow,
false //
);
int count = ArraySize(orderFlow);
result = IsValidSize(orderFlow);
if (!result)
{
return result;
}
//
// Sort Pivots ...
SortPivots(orderFlow);
//
// Filter Broken Order Flows ...
FilterBrokenPivots(orderFlow);
//
ENUM_X_DIRECTION orderFlowDirection;
result = DetectPivotDirection(
orderFlow,
orderFlowDirection //
);
if (!result)
{
return result;
}
//
return result;
}
/**
* Detect Specified States Market Structure ...
*