Last Works ...
This commit is contained in:
@@ -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;
|
||||
};
|
||||
@@ -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 ...
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user