801 lines
17 KiB
Plaintext
801 lines
17 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XC121SMCCycleHelper
|
|
// 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 "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
|
#include "../../Classes/x-saherelm.x-poi.class.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Implementations ...
|
|
|
|
enum ENUM_X_CYCLES
|
|
{
|
|
X_CYCLE_NONE,
|
|
X_CYCLE_TRIGGER,
|
|
X_CYCLE_DECISION,
|
|
X_CYCLE_ANALYSE,
|
|
X_CYCLE_VERIFICATION,
|
|
X_CYCLE_CONSOLIDATION,
|
|
X_CYCLE_VISION,
|
|
};
|
|
|
|
string ToString(ENUM_X_CYCLES value)
|
|
{
|
|
//
|
|
string result = EnumToString(value);
|
|
|
|
//
|
|
StringReplace(result, "X_CYCLE_", "");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
enum ENUM_X_CYCLE_EVENTS
|
|
{
|
|
SAR_CHANGE_DETECTED,
|
|
NEW_PEAK_DETECTED,
|
|
NEW_VALE_DETECTED,
|
|
PIVOT_POINT_DETECTED,
|
|
VWAP_ORDER_CHANGE_ETECTED,
|
|
VWAP_STATE_CHANGE_DETCTED,
|
|
CONSOLIDATION_BREAKED_DETECTED,
|
|
PEAK_PIVOT_STARTED,
|
|
PEAK_PIVOT_ENDED,
|
|
VALE_PIVOT_STARTED,
|
|
VALE_PIVOT_ENDED,
|
|
};
|
|
|
|
class XC121SMCCycleHelper : public XCBase
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// X121 ...
|
|
XCX121Helper *mX121Helper;
|
|
|
|
//
|
|
// POI Detector ...
|
|
XCPOIDrawer *mPOIDrawer;
|
|
XCPOIDetector *mPOIDetector;
|
|
|
|
//
|
|
// Bar Analyser
|
|
XCBarAnalyser *mBarAnalyser;
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XC121SMCCycleHelper()
|
|
{
|
|
Default();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XC121SMCCycleHelper()
|
|
{
|
|
DeInit();
|
|
}
|
|
|
|
//
|
|
// Getter/Setter(s) ...
|
|
|
|
//
|
|
int CountConsolidationZones()
|
|
{
|
|
return ArraySize(mConsolidationZones);
|
|
}
|
|
|
|
//
|
|
bool HasConsolidationZones()
|
|
{
|
|
return HasChild(mConsolidationZones);
|
|
}
|
|
|
|
//
|
|
bool GetConsolidationZone(
|
|
int idx,
|
|
XConsolidationZone &zone //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
zone.Clean();
|
|
|
|
//
|
|
result = HasConsolidationZones();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = CountConsolidationZones();
|
|
result = idx >= 0 &&
|
|
idx < count;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
zone = mConsolidationZones[idx];
|
|
result = zone.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool GetLastDirectionalConsolidationZone(
|
|
ENUM_X_DIRECTION forDir,
|
|
XConsolidationZone &zone //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
zone.Clean();
|
|
|
|
//
|
|
result = HasDirection(forDir);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool hasZones = HasConsolidationZones();
|
|
int zonesCount = CountConsolidationZones();
|
|
result = hasZones;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = zonesCount - 1; i >= 0; i--)
|
|
{
|
|
//
|
|
XConsolidationZone iZone = mConsolidationZones[i];
|
|
|
|
//
|
|
if (!iZone.IsBreaked())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
if (!HasDirection(iZone.breakDir))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
if (iZone.breakDir != forDir)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
zone = iZone;
|
|
break;
|
|
}
|
|
|
|
//
|
|
result = zone.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
bool GetActiveConsolidationZone(
|
|
XConsolidationZone &zone //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
zone = mActiveConsolidationZone;
|
|
result = zone.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int FillConsolidationZones(
|
|
ENUM_X_DIRECTION forDir,
|
|
XConsolidationZone &zones[] //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
Clean(zones);
|
|
|
|
//
|
|
bool hasZones = HasConsolidationZones();
|
|
if (!hasZones)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int count = CountConsolidationZones();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
//
|
|
XConsolidationZone iZone = mConsolidationZones[i];
|
|
|
|
//
|
|
bool isDirPassed =
|
|
(forDir == X_DIRECTION_ALL ||
|
|
forDir == X_DIRECTION_NONE)
|
|
? true
|
|
: forDir == iZone.breakDir;
|
|
if (isDirPassed)
|
|
{
|
|
//
|
|
AddRef(
|
|
iZone,
|
|
zones //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(zones);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Initialize ...
|
|
*
|
|
* @param symbol: String ...
|
|
* @param period: ENUM_TIMEFRAMES member ...
|
|
* @param x121Inputs: X121Inputs instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Init(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period,
|
|
X121Inputs &x121Inputs,
|
|
int requiredPOIS = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (requiredPOIS < 10)
|
|
{
|
|
requiredPOIS = 10;
|
|
}
|
|
|
|
//
|
|
result = IsValid(symbol) &&
|
|
IsValid(period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mSymbol = symbol;
|
|
mPeriod = period;
|
|
|
|
//
|
|
// X121 ...
|
|
mX121Helper = new XCX121Helper();
|
|
result = mX121Helper.Init(
|
|
symbol,
|
|
period,
|
|
x121Inputs //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mPOIDetector = new XCPOIDetector(
|
|
symbol,
|
|
period //
|
|
);
|
|
mPOIDetector.MaxNumberOfPOIs(requiredPOIS);
|
|
mPOIDetector.MaxNumberOfRequiredPOIs(requiredPOIS);
|
|
mPOIDetector.Init();
|
|
|
|
//
|
|
// Initialize Bar Analyser Class Instance ...
|
|
mBarAnalyser = new XCBarAnalyser();
|
|
|
|
//
|
|
// Initial and Configure POI Drawer if Required ...
|
|
mPOIDrawer = new XCPOIDrawer();
|
|
mPOIDrawer.ChartIdentification(0);
|
|
mPOIDrawer.SubWindowIdentification(0);
|
|
|
|
//
|
|
mPOIDrawer.DemandZoneFill(false);
|
|
mPOIDrawer.SupplyZoneFill(false);
|
|
mPOIDrawer.BullishFVGFill(false);
|
|
mPOIDrawer.BearishFVGFill(false);
|
|
mPOIDrawer.SupportZoneFill(false);
|
|
mPOIDrawer.ResistanceZoneFill(false);
|
|
mPOIDrawer.BullishOrderBlockFill(false);
|
|
mPOIDrawer.BearishOrderBlockFill(false);
|
|
|
|
//
|
|
// Set Chart Style ...
|
|
ApplyChartStyle();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Symbol ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetSymbol()
|
|
{
|
|
return mSymbol;
|
|
}
|
|
|
|
/**
|
|
* Retrieve TimeFrame (Period) ...
|
|
*
|
|
* @return ( ENUM_TIMEFRAMES )
|
|
*/
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
return mPeriod;
|
|
}
|
|
|
|
/**
|
|
* Get Specified Bar ...
|
|
*
|
|
* @param source: XOHCL instance, Source Bar ...
|
|
* @param bar: XOHCL instance, Dest Bar ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &source,
|
|
XOHCL &bar //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result =
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
source.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int index = iBarShift(
|
|
symbol,
|
|
period,
|
|
source.time //
|
|
);
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
index //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param index: Integer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &bar,
|
|
int index = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
if (index < 0)
|
|
{
|
|
index = 0;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param time: Datetime ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &bar,
|
|
datetime time = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int index = GetBarIndex(time);
|
|
result = GetBar(bar,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Time Bar Index ...
|
|
*
|
|
* @param time: DateTime ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetBarIndex(datetime time = NULL)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
time = NormalizeTime(time);
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result = iBarShift(
|
|
symbol,
|
|
period,
|
|
time //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Cycle Conditions ...
|
|
*
|
|
* @param events: ENUM_X_CYCLE_EVENTS member, Array ...
|
|
* @param conditions: X121SMCCycleConditions instance ...
|
|
* @param barIndex: Integer ...
|
|
* @param loopback: Integer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetConditions(
|
|
ENUM_X_CYCLE_EVENTS &events[],
|
|
ENUM_XPOI_EVENTS &poiEvents[],
|
|
X121SMCCycleConditions &conditions,
|
|
int barIndex = 0,
|
|
int loopback = 7 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
if (loopback < 5)
|
|
{
|
|
loopback = 5;
|
|
}
|
|
|
|
//
|
|
Clean(events);
|
|
Clean(poiEvents);
|
|
conditions.Clean();
|
|
|
|
//
|
|
result = mX121Helper.GetConditions(
|
|
conditions.x121Conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
conditions.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mPOIDetector.Update(poiEvents);
|
|
mPOIDetector.GetState(conditions.state);
|
|
|
|
//
|
|
conditions.symbol = GetSymbol();
|
|
conditions.period = GetPeriod();
|
|
conditions.time = TimeCurrent();
|
|
|
|
//
|
|
Update();
|
|
|
|
//
|
|
result = conditions.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
void Update()
|
|
{
|
|
//
|
|
int czLoopback = 5;
|
|
int maxAllowed = 20;
|
|
bool isActiveConsolidationZoneBreaked = false;
|
|
bool hasActiveConsolidationZone = mActiveConsolidationZone.IsValid();
|
|
|
|
//
|
|
if (hasActiveConsolidationZone)
|
|
{
|
|
//
|
|
isActiveConsolidationZoneBreaked = mActiveConsolidationZone.IsBreaked();
|
|
|
|
//
|
|
if (isActiveConsolidationZoneBreaked)
|
|
{
|
|
//
|
|
AddRef(
|
|
mActiveConsolidationZone,
|
|
mConsolidationZones //
|
|
);
|
|
|
|
//
|
|
CleanupArray(
|
|
mConsolidationZones,
|
|
maxAllowed //
|
|
);
|
|
|
|
//
|
|
mActiveConsolidationZone.Clean();
|
|
}
|
|
else
|
|
{
|
|
mActiveConsolidationZone.Update();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
XOHCL mBar;
|
|
bool hasBar = GetBar(
|
|
mBar,
|
|
0 //
|
|
);
|
|
if (hasBar)
|
|
{
|
|
//
|
|
double upper = 0;
|
|
double lower = 0;
|
|
bool hasConsolidationZone =
|
|
mBarAnalyser.IsConsolidate(
|
|
mBar,
|
|
upper,
|
|
lower,
|
|
czLoopback //
|
|
);
|
|
|
|
//
|
|
if (hasConsolidationZone)
|
|
{
|
|
//
|
|
mActiveConsolidationZone.Init(
|
|
GetSymbol(),
|
|
GetPeriod(),
|
|
upper,
|
|
lower,
|
|
czLoopback //
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
mBar.Clean();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Virtuals ...
|
|
|
|
/**
|
|
* Set Default Properties Values ...
|
|
*/
|
|
virtual void Default()
|
|
{
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
//
|
|
private:
|
|
//
|
|
// Props ...
|
|
string mSymbol;
|
|
ENUM_TIMEFRAMES mPeriod;
|
|
|
|
//
|
|
// CArrayObj mConsolidationObjects;
|
|
XConsolidationZone mActiveConsolidationZone;
|
|
XConsolidationZone mConsolidationZones[];
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Release All Resources ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
ZeroMemory(mX121Helper);
|
|
ZeroMemory(mPOIDetector);
|
|
ZeroMemory(mBarAnalyser);
|
|
|
|
//
|
|
delete mX121Helper;
|
|
delete mPOIDetector;
|
|
delete mBarAnalyser;
|
|
|
|
//
|
|
Clean(mConsolidationZones);
|
|
mActiveConsolidationZone.Clean();
|
|
}
|
|
|
|
/**
|
|
* Apply Chart Style ...
|
|
*/
|
|
void ApplyChartStyle()
|
|
{
|
|
//
|
|
// Retrieve Current Chart ID ...
|
|
long chartId = ChartID();
|
|
|
|
//
|
|
ENUM_CHART_MODE mMode = CHART_CANDLES; // chart's mMode
|
|
bool mShowBidLine = true; // show bid line
|
|
bool mShowAskLine = true; // show ask line
|
|
bool mShowGrid = false; // show grids on chart
|
|
bool mShowVolumes = false; // show volumes
|
|
bool mShowTradeLevels = true; // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders)
|
|
bool mAutoScroll = true; // chart autoscroll
|
|
bool mQuickNavigation = true; // chart quick navigation state
|
|
color mForeGroundColor = clrWhite; // chart's foreground color
|
|
color mBackGroundColor = clrBlack; // chart's background color
|
|
color mUpColor = clrGreen; // Up Color
|
|
color mDownColor = clrRed; // Down Color
|
|
color mBullishColor = clrGreen; // Bullish color
|
|
color mBearishColor = clrRed; // Bearish color
|
|
color mGridColor = clrGray; // grid color
|
|
color mBidLineColor = clrGray; // bid line color
|
|
color mAskLineColor = clrRed; // ask line color
|
|
color mLineColor = clrLime; // line mMode and doji candlestick color
|
|
color mStopColor = clrGold; // Color of stop order levels (Stop Loss and Take Profit)
|
|
color mVolumesColor = clrGreen; // volumes color
|
|
|
|
//
|
|
ChartSetInteger(chartId, CHART_MODE, mMode);
|
|
ChartSetInteger(chartId, CHART_SHOW_BID_LINE, mShowBidLine);
|
|
ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, mShowAskLine);
|
|
ChartSetInteger(chartId, CHART_SHOW_GRID, mShowGrid);
|
|
ChartSetInteger(chartId, CHART_SHOW_VOLUMES, mShowVolumes);
|
|
ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels);
|
|
ChartSetInteger(chartId, CHART_AUTOSCROLL, mAutoScroll);
|
|
ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, mQuickNavigation);
|
|
ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, mForeGroundColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, mBackGroundColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_UP, mUpColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, mDownColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, mBullishColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, mBearishColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_GRID, mGridColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_BID, mBidLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_ASK, mAskLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, mStopColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, mLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_VOLUME, mVolumesColor);
|
|
}
|
|
|
|
//
|
|
};
|