780 lines
17 KiB
Plaintext
780 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) ...
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
//
|
|
// X121 ...
|
|
mX121Helper = new XCX121Helper();
|
|
result = mX121Helper.Init(
|
|
symbol,
|
|
period,
|
|
x121Inputs //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mPOIDetector = new XCPOIDetector(
|
|
symbol,
|
|
period //
|
|
);
|
|
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()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
result = mX121Helper.GetSymbol();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve TimeFrame (Period) ...
|
|
*
|
|
* @return ( ENUM_TIMEFRAMES )
|
|
*/
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
//
|
|
ENUM_TIMEFRAMES result = NULL;
|
|
|
|
//
|
|
result = mX121Helper.GetPeriod();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Detect Market Structure Method 2 ...
|
|
*
|
|
* @param model: XMarketStructure instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectMarketStructure(
|
|
ENUM_X_DIRECTION &dir,
|
|
int pivotsCount = 3 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int barIndex = 0;
|
|
|
|
//
|
|
if (pivotsCount < 3)
|
|
{
|
|
pivotsCount = 3;
|
|
}
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
int hpIndex = -1;
|
|
int hpIndexes[];
|
|
double hpValues[];
|
|
|
|
//
|
|
int lvIndex = -1;
|
|
int lvIndexes[];
|
|
double lvValues[];
|
|
|
|
//
|
|
for (int i = 0; i < pivotsCount; i++)
|
|
{
|
|
//
|
|
hpIndex = barIndex;
|
|
lvIndex = barIndex;
|
|
|
|
//
|
|
double lastHP = 0;
|
|
double lastLV = 0;
|
|
|
|
//
|
|
int hpCount = ArraySize(hpIndexes);
|
|
int lvCount = ArraySize(lvIndexes);
|
|
|
|
//
|
|
if (IsValidSize(hpCount))
|
|
{
|
|
//
|
|
lastHP = hpValues[hpCount - 1];
|
|
hpIndex = hpIndexes[hpCount - 1];
|
|
}
|
|
|
|
//
|
|
if (IsValidSize(lvCount))
|
|
{
|
|
//
|
|
lastLV = lvValues[lvCount - 1];
|
|
lvIndex = lvIndexes[lvCount - 1];
|
|
}
|
|
|
|
//
|
|
if (lastHP == 0)
|
|
{
|
|
//
|
|
lastHP = mX121Helper
|
|
.xpvHelper
|
|
.GetPeak(hpIndex);
|
|
}
|
|
|
|
//
|
|
if (lastLV == 0)
|
|
{
|
|
//
|
|
lastLV = mX121Helper
|
|
.xpvHelper
|
|
.GetVale(lvIndex);
|
|
}
|
|
|
|
//
|
|
int highestPeakIndex = -1;
|
|
double highesrPeak =
|
|
mX121Helper
|
|
.xpvHelper
|
|
.GetHigherPeak(
|
|
highestPeakIndex,
|
|
lastHP,
|
|
hpIndex //
|
|
);
|
|
if (IsValidIndex(highestPeakIndex))
|
|
{
|
|
//
|
|
Add(
|
|
highestPeakIndex,
|
|
hpIndexes //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
highesrPeak,
|
|
hpValues //
|
|
);
|
|
}
|
|
|
|
//
|
|
int lowestValeIndex = -1;
|
|
double lowestVale =
|
|
mX121Helper
|
|
.xpvHelper
|
|
.GetLowerVale(
|
|
lowestValeIndex,
|
|
lastLV,
|
|
lvIndex //
|
|
);
|
|
if (IsValidIndex(lowestValeIndex))
|
|
{
|
|
//
|
|
Add(
|
|
lowestValeIndex,
|
|
lvIndexes //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
lowestVale,
|
|
lvValues //
|
|
);
|
|
}
|
|
|
|
//
|
|
bool canBreak = ArraySize(hpIndexes) >= pivotsCount ||
|
|
ArraySize(lvIndexes) >= pivotsCount;
|
|
if (canBreak)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
ArrayReverse(hpValues);
|
|
ArrayReverse(hpIndexes);
|
|
int countHPs = ArraySize(hpIndexes);
|
|
|
|
//
|
|
ArrayReverse(lvValues);
|
|
ArrayReverse(lvIndexes);
|
|
int countLVs = ArraySize(lvIndexes);
|
|
|
|
//
|
|
bool isValidHPs = countHPs >= pivotsCount;
|
|
bool isValidLVs = countLVs >= pivotsCount;
|
|
|
|
//
|
|
result = isValidHPs ||
|
|
isValidLVs;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (isValidHPs && isValidLVs)
|
|
{
|
|
//
|
|
hpIndex = hpIndexes[countHPs - 1];
|
|
lvIndex = lvIndexes[countLVs - 1];
|
|
}
|
|
|
|
//
|
|
dir =
|
|
!isValidHPs && isValidLVs
|
|
? X_DIRECTION_BULLISH
|
|
: !isValidLVs && isValidHPs
|
|
? X_DIRECTION_BEARISH
|
|
: hpIndex < lvIndex
|
|
? X_DIRECTION_BEARISH
|
|
: lvIndex < hpIndex
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_ALL;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Order Blocks ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
bool DetectOrderBlocks(
|
|
XCOrderBlock *&bullishOrderBlocks[],
|
|
XCOrderBlock *&bearishOrderBlocks[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(bullishOrderBlocks);
|
|
Clean(bearishOrderBlocks);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int bullOBsCount = DetectDirectionOrderBlocks(
|
|
X_DIRECTION_BULLISH,
|
|
state,
|
|
bullishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
int bearOBsCount = DetectDirectionOrderBlocks(
|
|
X_DIRECTION_BEARISH,
|
|
state,
|
|
bearishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(bullOBsCount +
|
|
bearOBsCount);
|
|
|
|
//
|
|
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 = conditions.x121Conditions.symbol;
|
|
conditions.period = conditions.x121Conditions.period;
|
|
conditions.time = TimeCurrent();
|
|
|
|
//
|
|
result = conditions.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
//
|
|
// Virtuals ...
|
|
|
|
/**
|
|
* Set Default Properties Values ...
|
|
*/
|
|
virtual void Default()
|
|
{
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
//
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Release All Resources ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
delete mX121Helper;
|
|
delete mPOIDetector;
|
|
delete mBarAnalyser;
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
//
|
|
};
|