Files
MQL5Data/X121SMCEA/Strategy/x-121.smc.test.strategy.class.mq5
T
2024-11-16 02:12:45 +03:30

1135 lines
28 KiB
Plaintext

///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCX121SMCTestStrategy
// Description: provides all based classes for use ...
//
//
// 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 "../../Helpers/x-saherelm.x3ma.helper.mq5"
#include "../../Helpers/x-saherelm.x3vwap.helper.mq5"
#include "../../Helpers/x-saherelm.xpv.helper.mq5"
#include "../Classes/x-121.smc.base.strategy.class.mq5"
//
// Helper(s) ...
//
// XStrategy Class Implementation(s) ...
class XCX121SMCTestStrategy : public XCX121SMCBaseStrategy
{
//
// Public ...
public:
//
//
// Constructor(s) ...
void XCX121SMCTestStrategy(
//
// Base ...
string _symbol, // Trading Symbol
ENUM_TIMEFRAMES _period // Trading TimeFrame
)
: XCX121SMCBaseStrategy(_symbol, _period)
{
InitialHelpers();
}
//
// Deconstructur ...
void ~XCX121SMCTestStrategy()
{
}
//
// Overrides Actions ...
/**
* Destroy All Class Implementations ...
*/
void Destroy() override
{
//
delete xpvHelper;
delete x3maHelper;
delete x3vwapHelper;
}
/**
* Check Conditions For Signal ...
*/
bool HasSignal(
XSignal &signal,
X121SMCStrategyConditions &conditions //
) override
{
//
bool result = false;
//
signal.Clean();
conditions.Clean();
//
int pushers = 0;
//
double sl = 0;
double tp = 0;
double risk = 0;
double entry = 0;
double reward = 0;
double r2r = R2R();
double volume = Volume();
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
//
bool hasLong = false;
bool hasShort = false;
//
// Start Calculations ...
//
string _symbol = GetSymbol();
ENUM_TIMEFRAMES _period = GetPeriod();
//
double points = GetPoints(_symbol);
double pip = GetPipPrice(_symbol);
double pip2 = 2 * pip;
//
int zIndex = 0;
int cIndex = zIndex + 1;
int pIndex = cIndex + 1;
int ppIndex = pIndex + 1;
//
// Retrieve Bars ...
//
// Zero Bar ...
XOHCL zBar;
result = zBar.Init(
_symbol,
_period,
zIndex //
);
if (!result)
{
return result;
}
//
// Last Bar ...
XOHCL cBar;
result = cBar.Init(
_symbol,
_period,
cIndex //
);
if (!result)
{
return result;
}
//
// Previous Bar ...
XOHCL pBar;
result = pBar.Init(
_symbol,
_period,
pIndex //
);
if (!result)
{
return result;
}
//
bool isSpreadPassed = IsSpreadPass();
result = isSpreadPassed;
if (!result)
{
return result;
}
//
// Try to Implement SMC Based Conditions ...
result = DetectConditions();
if (!result)
{
return result;
}
//
result = hasLong ||
hasShort;
//
// Rmove Signal Condition ...
if (result)
{
//
// TYPE ...
type =
hasLong
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
ENUM_X_POSITION_TYPES xType =
hasLong
? X_POSITION_TYPE_LONG
: X_POSITION_TYPE_SHORT;
//
entry = GetEntry(
conditions.symbol,
type //
);
//
double candidates[];
DetectSLCandidates(
candidates,
entry,
conditions,
xType //
);
double selectedSL =
hasLong
? GetMax(candidates)
: GetMin(candidates);
sl =
hasLong
? selectedSL - pip2
: selectedSL + pip2;
//
// RISK Reward ...
risk =
hasLong
? entry - sl
: sl - entry;
reward = risk * r2r;
tp =
hasLong
? entry + reward
: entry - reward;
//
ClearDraws();
//
signal.sl = sl;
signal.tp = tp;
signal.type = type;
signal.mode = mode;
signal.entry = entry;
signal.volume = volume;
signal.symbol = _symbol;
signal.pushers = pushers;
signal.provider = GetTag();
signal.time = TimeCurrent();
signal.period = _5MState.period;
//
result = PrepareSignal(signal);
//
hasLong = false;
hasShort = false;
}
//
return result;
}
/**
* Detect SL Candidates based on Strategy and Conditions ...
*
* @param result: Double array reference ...
* @param entry: Double, Position Entry Price ...
* @param conditions: X121SMCStrategyConditions instance, Provides Configurations ...
* @param type: ENUM_X_POSITION_TYPES member, Specified Position Type ...
*/
void DetectSLCandidates(
double &result[],
double entry,
X121SMCStrategyConditions &conditions,
ENUM_X_POSITION_TYPES type //
) override
{
}
/**
* Customize Strategy Identifier ...
*/
string GetTag() override
{
return X121SMCStrategyToken;
}
//
// Protected ...
protected:
//
//
// Props ...
//
// XPV ...
XPVInputs xpvInputs;
XCXPVHelper *xpvHelper;
//
// X3MA ...
X3MAInputs x3maInputs;
XCX3MAHelper *x3maHelper;
//
// X3VWAP ...
X3VWAPInputs x3vwapInputs;
XCX3VWAPHelper *x3vwapHelper;
//
// Actions ...
/**
* Detect and Parse Market Conditions ...
*
* @return ( bool )
*/
bool DetectConditions()
{
//
bool result = false;
//
mConditions.Clean();
mConditions.symbol = GetSymbol();
mConditions.period = GetPeriod();
mConditions.time = TimeCurrent();
//
// Detect Market Structures ...
//
// 1D ...
mConditions.d1State = _1DState;
result = DetectMarketStructure(
mConditions.d1MarketDirection,
mConditions.d1SupportZones,
mConditions.d1ResistanceZones,
_1DState //
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// 4H ...
mConditions.h4State = _4HState;
result = DetectMarketStructure(
mConditions.h4MarketDirection,
mConditions.h4SupportZones,
mConditions.h4ResistanceZones,
_4HState //
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// 2H ...
mConditions.h2State = _2HState;
result = DetectMarketStructure(
mConditions.h2MarketDirection,
mConditions.h2SupportZones,
mConditions.h2ResistanceZones,
_2HState //
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// 1H ...
mConditions.h1State = _1HState;
result = DetectMarketStructure(
mConditions.h1MarketDirection,
mConditions.h1SupportZones,
mConditions.h1ResistanceZones,
_1HState //
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// 15M ...
mConditions.m15State = _15MState;
result = DetectMarketStructure(
mConditions.m15MarketDirection,
mConditions.m15SupportZones,
mConditions.m15ResistanceZones,
_15MState //
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// 5M ...
mConditions.m5State = _5MState;
result = DetectMarketStructure(
mConditions.m5MarketDirection,
mConditions.m5SupportZones,
mConditions.m5ResistanceZones,
_5MState //
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// 1M ...
mConditions.m1State = _1MState;
result = DetectMarketStructure(
mConditions.m1MarketDirection,
mConditions.m1SupportZones,
mConditions.m1ResistanceZones,
_1MState //
);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// 1H-15M-5M ...
ENUM_X_DIRECTION marketStructure = X_DIRECTION_NONE;
result = mConditions.HasMarketStructure(marketStructure);
if (!result)
{
//
mConditions.Clean();
return result;
}
//
// Detect Swing High and Swing Low ...
// 1H-15M-5M ...
int count = 0;
//
// 1H ...
//
XCSwing *h1SwingLows[];
XCSwing *h1SwingHighs[];
XCSupportZone *h1SupportZone = NULL;
XCResistanceZone *h1ResistanceZone = NULL;
//
count = ArraySize(mConditions.h1SupportZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSupportZone *item = mConditions.h1SupportZones[i];
//
bool canSelect =
h1SupportZone == NULL ||
h1SupportZone.Lower() < item.Lower();
if (canSelect)
{
h1SupportZone = item;
}
}
}
if (h1SupportZone != NULL)
{
//
// Detect Swings ...
count = ArraySize(mConditions.h1State.swingLows);
if (IsValidSize(count))
{
//
double upper = h1SupportZone.Upper();
double lower = h1SupportZone.Lower();
//
for (int i = 0; i < count; i++)
{
//
XCSwing *item = mConditions.h1State.swingLows[i];
//
XOHCL iBar;
bool isFilled = item.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool canSelect = (iBar.high <= upper &&
iBar.low >= lower) ||
(iBar.high >= upper &&
iBar.low <= lower);
if (canSelect)
{
//
Add(
item,
h1SwingLows //
);
//
// Draw ...
XCSwingLowObject *iObj;
bool isCreated = mPOIDrawer.CreateSwingLow(
item,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
}
}
//
// Draw ...
XCSupportZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateSupportZone(
h1SupportZone,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
//
count = ArraySize(mConditions.h1ResistanceZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *item = mConditions.h1ResistanceZones[i];
//
bool canSelect =
h1ResistanceZone == NULL ||
h1ResistanceZone.Upper() > item.Upper();
if (canSelect)
{
h1ResistanceZone = item;
}
}
}
if (h1ResistanceZone != NULL)
{
//
// Detect Swings ...
count = ArraySize(mConditions.h1State.swingHighs);
if (IsValidSize(count))
{
//
double upper = h1ResistanceZone.Upper();
double lower = h1ResistanceZone.Lower();
//
for (int i = 0; i < count; i++)
{
//
XCSwing *item = mConditions.h1State.swingHighs[i];
//
XOHCL iBar;
bool isFilled = item.FillBar(iBar);
if (!isFilled)
{
continue;
}
//
bool canSelect = (iBar.high <= upper &&
iBar.low >= lower) ||
(iBar.high >= upper &&
iBar.low <= lower);
if (canSelect)
{
//
Add(
item,
h1SwingHighs //
);
//
// Draw ...
XCSwingHighObject *iObj;
bool isCreated = mPOIDrawer.CreateSwingHigh(
item,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
}
}
//
// Draw ...
XCResistanceZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateResistanceZone(
h1ResistanceZone,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
//
// 15M ...
//
XCSupportZone *m15SupportZone = NULL;
count = ArraySize(mConditions.m15SupportZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSupportZone *item = mConditions.m15SupportZones[i];
//
bool canSelect =
m15SupportZone == NULL ||
m15SupportZone.Lower() < item.Lower();
if (canSelect)
{
m15SupportZone = item;
}
}
}
if (m15SupportZone != NULL)
{
//
XCSupportZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateSupportZone(
m15SupportZone,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
//
XCResistanceZone *m15ResistanceZone = NULL;
count = ArraySize(mConditions.m15ResistanceZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *item = mConditions.m15ResistanceZones[i];
//
bool canSelect =
m15ResistanceZone == NULL ||
m15ResistanceZone.Upper() > item.Upper();
if (canSelect)
{
m15ResistanceZone = item;
}
}
}
if (m15ResistanceZone != NULL)
{
//
XCResistanceZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateResistanceZone(
m15ResistanceZone,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
//
// 5M ...
//
XCSupportZone *m5SupportZone = NULL;
count = ArraySize(mConditions.m5SupportZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSupportZone *item = mConditions.m5SupportZones[i];
//
bool canSelect =
m5SupportZone == NULL ||
m5SupportZone.Lower() < item.Lower();
if (canSelect)
{
m5SupportZone = item;
}
}
}
if (m5SupportZone != NULL)
{
//
XCSupportZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateSupportZone(
m5SupportZone,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
//
XCResistanceZone *m5ResistanceZone = NULL;
count = ArraySize(mConditions.m5ResistanceZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *item = mConditions.m5ResistanceZones[i];
//
bool canSelect =
m5ResistanceZone == NULL ||
m5ResistanceZone.Upper() > item.Upper();
if (canSelect)
{
m5ResistanceZone = item;
}
}
}
if (m5ResistanceZone != NULL)
{
//
XCResistanceZoneObject *iObj;
bool isCreated = mPOIDrawer.CreateResistanceZone(
m5ResistanceZone,
iObj //
);
if (isCreated)
{
AddObjectIfNotExists(iObj);
}
}
//
// DrawState(_5MState);
//
return result;
}
/**
* Detect Specified States Market Structure ...
*
* @param dir: ENUM_X_DIRECTION member, Refrence ...
* @param state: XPOIState instance ...
*
* @return ( bool )
*/
bool DetectMarketStructure(
ENUM_X_DIRECTION &dir,
XCSupportZone *&supportZones[],
XCResistanceZone *&resistanceZones[],
XPOIState &state //
)
{
//
bool result = false;
//
int count = 0;
//
// Filter Untouched Supports ...
Clean(supportZones);
int untouchedSupportsCount = 0;
count = ArraySize(state.supportZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCSupportZone *item = state.supportZones[i];
//
// Find Breakout Bar
XOHCL iBar;
bool isFilled = item.FillBar(iBar);
if (!isFilled)
{
break;
}
//
int iBarIndex = iBar.Index();
int iBarUnTouchedCount = 0;
for (int j = 0; j < iBarIndex; j++)
{
//
XOHCL jBar;
bool isInited = jBar.Init(
iBar.symbol,
iBar.period,
j //
);
if (!isInited)
{
break;
}
//
bool isUntouched =
jBar.low > item.Upper();
if (isUntouched)
{
iBarUnTouchedCount++;
}
else
{
iBarUnTouchedCount--;
}
}
//
if (iBarUnTouchedCount > 0)
{
//
Add(
item,
supportZones //
);
}
}
//
untouchedSupportsCount = ArraySize(supportZones);
if (IsValidSize(untouchedSupportsCount))
{
//
// Draw ...
// for (int i = 0; i < untouchedSupportsCount; i++)
// {
// //
// XCSupportZone *item = supportZones[i];
// //
// XCSupportZoneObject *iObj;
// bool isCreated = mPOIDrawer.CreateSupportZone(
// item,
// iObj //
// );
// if (isCreated)
// {
// AddObjectIfNotExists(iObj);
// }
// }
}
}
//
// Filter Untouched Resistances ...
Clean(resistanceZones);
int untouchedResistancesCount = 0;
count = ArraySize(state.resistanceZones);
if (IsValidSize(count))
{
//
for (int i = 0; i < count; i++)
{
//
XCResistanceZone *item = state.resistanceZones[i];
//
// Find Breakout Bar
XOHCL iBar;
bool isFilled = item.FillBar(iBar);
if (!isFilled)
{
break;
}
//
int iBarIndex = iBar.Index();
int iBarUnTouchedCount = 0;
for (int j = 0; j < iBarIndex; j++)
{
//
XOHCL jBar;
bool isInited = jBar.Init(
iBar.symbol,
iBar.period,
j //
);
if (!isInited)
{
break;
}
//
bool isUntouched =
jBar.high < item.Lower();
if (isUntouched)
{
iBarUnTouchedCount++;
}
else
{
iBarUnTouchedCount--;
}
}
//
if (iBarUnTouchedCount > 0)
{
//
Add(
item,
resistanceZones //
);
}
}
//
untouchedResistancesCount = ArraySize(resistanceZones);
if (IsValidSize(untouchedResistancesCount))
{
//
// Draw ...
// for (int i = 0; i < untouchedResistancesCount; i++)
// {
// //
// XCResistanceZone *item = resistanceZones[i];
// //
// XCResistanceZoneObject *iObj;
// bool isCreated = mPOIDrawer.CreateResistanceZone(
// item,
// iObj //
// );
// if (isCreated)
// {
// AddObjectIfNotExists(iObj);
// }
// }
}
}
//
bool hasBullishStructure =
IsValidSize(untouchedSupportsCount) &&
untouchedSupportsCount > untouchedResistancesCount;
bool hasBearishStructure =
IsValidSize(untouchedResistancesCount) &&
untouchedResistancesCount > untouchedSupportsCount;
//
result = (hasBullishStructure &&
!hasBearishStructure) ||
(hasBearishStructure &&
!hasBullishStructure);
//
if (result)
{
//
dir =
hasBullishStructure
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
}
//
return result;
}
//
// Private ...
private:
//
// Props ...
/**
* Initial Required Indicators Helper ...
*/
void InitialHelpers()
{
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
// Short ...
ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES scPeriod = NULL; // Time Period
//
// Medium ...
ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period
//
// Long ...
ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period
//
// Hind ...
ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period
ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period
//
// XPV ...
//
xpvInputs.Default();
//
xpvInputs.scMethod = scMethod;
xpvInputs.scPeriod = scPeriod;
xpvInputs.mcMethod = mcMethod;
xpvInputs.mcPeriod = mcPeriod;
xpvInputs.lcMethod = lcMethod;
xpvInputs.lcPeriod = lcPeriod;
xpvInputs.hcMethod = hcMethod;
xpvInputs.hcPeriod = hcPeriod;
//
xpvInputs.showPeaksAndVales = true;
xpvInputs.showLevels = false;
xpvInputs.showConsolidations = false;
xpvInputs.showFibo1Levels = false;
xpvInputs.showFibo2Levels = false;
xpvInputs.showFibo3Levels = false;
xpvInputs.showFibo4Levels = false;
xpvInputs.showFibo5Levels = false;
//
xpvHelper = new XCXPVHelper();
xpvHelper.Init(
symbol,
period,
xpvInputs //
);
//
// X3MA ...
//
x3maInputs.Default();
//
x3maInputs.showFast = false;
x3maInputs.showMid = false;
x3maInputs.showSlow = false;
//
x3maHelper = new XCX3MAHelper();
x3maHelper.Init(
symbol,
period,
x3maInputs //
);
//
// X3VWAP ...
//
x3vwapInputs.Default();
//
x3vwapInputs.showFast = false;
x3vwapInputs.showMid = false;
x3vwapInputs.showSlow = false;
//
x3vwapHelper = new XCX3VWAPHelper();
x3vwapHelper.Init(
symbol,
period,
x3vwapInputs //
);
}
//
};
//