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
+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;
}
//