Files
MQL5Data/X121SMCEA/Libraries/x-121.smc.lib.mq5
T
2024-11-18 05:10:49 +03:30

1214 lines
21 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Common Library
// --------------------------------------
// Name: X121SMCLib
// Description: provide all commonly used functions ...
//
//
// 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
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.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"
//
// Definitions ...
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
{
//
string symbol;
ENUM_TIMEFRAMES period;
datetime time;
//
XPVPivot orderFlow[];
//
XPVConditions xpvConditions;
X3MAConditions x3maConditions;
X3VWAPConditions x3vwapConditions;
//
// D1 ...
//
XPOIState d1State;
ENUM_X_DIRECTION d1MarketDirection;
XCSupportZone *d1SupportZones[];
XCResistanceZone *d1ResistanceZones[];
//
XCSwing *d1SwingHigh;
XCSwing *d1SwingLow;
//
// H4 ...
//
XPOIState h4State;
ENUM_X_DIRECTION h4MarketDirection;
XCSupportZone *h4SupportZones[];
XCResistanceZone *h4ResistanceZones[];
//
XCSwing *h4SwingHigh;
XCSwing *h4SwingLow;
//
// H2 ...
//
XPOIState h2State;
ENUM_X_DIRECTION h2MarketDirection;
XCSupportZone *h2SupportZones[];
XCResistanceZone *h2ResistanceZones[];
//
XCSwing *h2SwingHigh;
XCSwing *h2SwingLow;
//
// H1 ...
//
XPOIState h1State;
ENUM_X_DIRECTION h1MarketDirection;
XCSupportZone *h1SupportZones[];
XCResistanceZone *h1ResistanceZones[];
//
XCSwing *h1SwingHigh;
XCSwing *h1SwingLow;
//
// M15 ...
//
XPOIState m15State;
ENUM_X_DIRECTION m15MarketDirection;
XCSupportZone *m15SupportZones[];
XCResistanceZone *m15ResistanceZones[];
//
XCSwing *m15SwingHigh;
XCSwing *m15SwingLow;
//
// M5 ...
//
XPOIState m5State;
ENUM_X_DIRECTION m5MarketDirection;
XCSupportZone *m5SupportZones[];
XCResistanceZone *m5ResistanceZones[];
//
XCSwing *m5SwingHigh;
XCSwing *m5SwingLow;
//
// M1 ...
//
XPOIState m1State;
ENUM_X_DIRECTION m1MarketDirection;
XCSupportZone *m1SupportZones[];
XCResistanceZone *m1ResistanceZones[];
//
XCSwing *m1SwingHigh;
XCSwing *m1SwingLow;
//
void X121SMCStrategyConditions()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
symbol = NULL;
period = NULL;
time = NULL;
//
xpvConditions.Clean();
x3maConditions.Clean();
x3vwapConditions.Clean();
//
Clean(orderFlow);
//
// D1 ...
//
d1State.Clean();
d1MarketDirection = X_DIRECTION_NONE;
Clean(d1SupportZones);
Clean(d1ResistanceZones);
//
d1SwingHigh = NULL;
d1SwingLow = NULL;
//
// H4 ...
//
h4State.Clean();
h4MarketDirection = X_DIRECTION_NONE;
Clean(h4SupportZones);
Clean(h4ResistanceZones);
//
h4SwingHigh = NULL;
h4SwingLow = NULL;
//
// H2 ...
//
h2State.Clean();
h2MarketDirection = X_DIRECTION_NONE;
Clean(h2SupportZones);
Clean(h2ResistanceZones);
//
h2SwingHigh = NULL;
h2SwingLow = NULL;
//
// H1 ...
//
h1State.Clean();
h1MarketDirection = X_DIRECTION_NONE;
Clean(h1SupportZones);
Clean(h1ResistanceZones);
//
h1SwingHigh = NULL;
h1SwingLow = NULL;
//
// M15 ...
//
m15State.Clean();
m15MarketDirection = X_DIRECTION_NONE;
Clean(m15SupportZones);
Clean(m15ResistanceZones);
//
m15SwingHigh = NULL;
m15SwingLow = NULL;
//
// M5 ...
//
m5State.Clean();
m5MarketDirection = X_DIRECTION_NONE;
Clean(m5SupportZones);
Clean(m5ResistanceZones);
//
m5SwingHigh = NULL;
m5SwingLow = NULL;
//
// M1 ...
//
m1State.Clean();
m1MarketDirection = X_DIRECTION_NONE;
Clean(m1SupportZones);
Clean(m1ResistanceZones);
//
m1SwingHigh = NULL;
m1SwingLow = NULL;
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = IsSpecifiedValid(symbol) &&
IsSpecifiedValid(period) &&
IsSpecifiedValid(time);
//
return result;
}
//
// Custom Tools ...
/**
* Check Conditions for Detect Market Structure ...
*
* @param structure: ENUM_X_DIRECTION member, Market Structure Direction reference ...
*
* @return ( bool )
*/
bool HasMarketStructure(
ENUM_X_DIRECTION &structure //
)
{
//
bool result = false;
//
structure = X_DIRECTION_NONE;
//
result = IsValid();
if (!result)
{
return result;
}
//
bool is1DBullish = IsBullish(d1MarketDirection);
bool is1DBearish = IsBearish(d1MarketDirection);
//
bool is4HBullish = IsBullish(h4MarketDirection);
bool is4HBearish = IsBearish(h4MarketDirection);
//
bool is2HBullish = IsBullish(h2MarketDirection);
bool is2HBearish = IsBearish(h2MarketDirection);
//
bool is1HBullish = IsBullish(h1MarketDirection);
bool is1HBearish = IsBearish(h1MarketDirection);
//
bool is15MBullish = IsBullish(m15MarketDirection);
bool is15MBearish = IsBearish(m15MarketDirection);
//
bool is5MBullish = IsBullish(m5MarketDirection);
bool is5MBearish = IsBearish(m5MarketDirection);
//
bool is1MBullish = IsBullish(m1MarketDirection);
bool is1MBearish = IsBearish(m1MarketDirection);
//
bool isStructuresBullish =
//
is1HBullish &&
is15MBullish &&
is5MBullish
//
;
//
bool isStructuresBearish =
//
is1HBearish &&
is15MBearish &&
is5MBearish
//
;
//
bool hasMarketStructure =
isStructuresBullish ||
isStructuresBearish;
result = hasMarketStructure;
if (!result)
{
return result;
}
//
structure =
isStructuresBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
return result;
}
//
// Reporter Functions ...
/**
* Generate Provided Scores ...
*
* @param bullishScore: Integer, reference ...
* @param bearishScore: Integer, referenceF ...
*/
void GenerateScore(
double &bullishScore,
double &bearishScore //
)
{
//
bullishScore = 0;
bearishScore = 0;
//
if (!IsValid())
{
return;
}
//
double bullScore = 0;
double bearScore = 0;
// //
// // XPV ...
// pvConditions.GenerateScore(
// bullScore,
// bearScore //
// );
// bullishScore += bullScore;
// bearishScore += bearScore;
}
/**
* Generate Summary ...
*
* @param onlyCommons: Boolean ...
* @param onlyConditions: Boolean ...
* @param includeScores: Boolean ...
* @param ignoreFalseConditions: Boolean ...
* @param separator: String ...
*
* @return ( string )
*/
string GenerateSummary(
bool onlyCommons = false,
bool onlyConditions = false,
bool includeScores = true,
bool ignoreFalseConditions = true,
string separator = "\n" //
)
{
//
string result = NULL;
//
double bullishScore = 0;
double bearishScore = 0;
GenerateScore(
bullishScore,
bearishScore //
);
//
string commonStr = GenerateSpecifiedCommonSummary(
this,
separator,
includeScores,
true //
);
// //
// // XPV ...
// string pvStr = pvConditions.GenerateSummary(
// false,
// true,
// false,
// ignoreFalseConditions //
// );
//
string conditionsStr =
//
// pvStr + separator +
""
//
;
//
result =
//
"[" + GetTag() + "]" + separator +
"----------" + separator +
(onlyConditions
? ""
: commonStr) +
" " + separator +
(onlyCommons
? ""
: conditionsStr) +
""
//
;
//
return result;
}
/**
* Get Unique Identifier ...
*
* @param forObject: Boolean ...
*
* @return ( string )
*/
string GetTag(
bool forObject = false //
)
{
//
string result = NULL;
//
if (!forObject)
{
result = X121SMCStrategyToken;
}
else
{
//
result = X121SMCStrategyToken + "_" +
symbol + "_" + ToString(period) + "_" +
ToMD5(time);
}
//
return result;
}
//
};
typedef void (*TOnX121SMCSignal)(
XSignal &signal,
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;
}
//