Files
MQL5Data/X121SMCEA/Classes/x-121.smc.market.cycle.helper.class.mq5
T

933 lines
22 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 ...
class XC121SMCCycleHelper : public XCBase
{
//
public:
//
// Props ...
//
// X121 ...
XCX121Helper *mX121Helper;
//
// POI Detector ...
XCPOIDetector *mPOIDetector;
//
// Constructor(s) ...
XC121SMCCycleHelper()
{
Default();
}
//
// Deconstructor ...
~XC121SMCCycleHelper()
{
DeInit();
}
//
// Getter/Setter(s) ...
/**
* Get Max llowed Changes to Save ...
*
* @return ( int )
*/
int MaxAllowedSavedChanges()
{
return mMaxAllowedSavedChanges;
}
/**
* Set Max llowed Changes to Save ...
*
* @param value: Integer ...
*/
void MaxAllowedSavedChanges(int value)
{
//
if (value < 10)
{
value = 10;
}
//
mMaxAllowedSavedChanges = value;
}
//
// 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 //
)
{
//
bool result = false;
//
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(0);
mPOIDetector.Init();
//
// Initialize Bar Analyser Class Instance ...
mBarAnalyser = new XCBarAnalyser();
//
// Set Chart Style ...
ApplyChartStyle();
//
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;
}
/**
* Retrieve Cycle Conditions ...
*
* @param conditions: X121SMCCycleConditions instance ...
* @param barIndex: Integer ...
* @param loopback: Integer ...
*
* @return ( bool )
*/
bool GetConditions(
X121SMCCycleConditions &conditions,
int barIndex = 0,
int loopback = 7 //
)
{
//
bool result = false;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (loopback < 5)
{
loopback = 5;
}
//
conditions.Clean();
//
result = mX121Helper.GetConditions(
conditions.x121Conditions,
barIndex,
loopback //
);
if (!result)
{
//
conditions.Clean();
return result;
}
//
conditions.symbol = conditions.x121Conditions.symbol;
conditions.period = conditions.x121Conditions.period;
conditions.time = TimeCurrent();
//
result = conditions.IsValid();
//
if (result)
{
//
Calculate(
barIndex,
conditions //
);
}
//
return result;
}
//
// Tools ...
/**
* Detect Nearest Supply/Demand Zones ...
*
* @param bar: XOHCL instance, Start Bar ...
*
* @return ( bool )
*/
bool DetectValisSupplyZone(
XOHCL &bar,
XCSupplyZone *&supplyZone,
XCDemandZone *&demandZone //
)
{
//
bool result = false;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
int index = bar.Index();
//
double bid = GetBid(bar.symbol);
double ask = GetAsk(bar.symbol);
//
// Retrieve X121 Cnditions ...
int conditionsLoopback = 10;
X121Conditions x121Conditions;
result = mX121Helper.GetConditions(
x121Conditions,
index,
conditionsLoopback //
);
if (!result)
{
return result;
}
int validPeaksCount = ArraySize(x121Conditions.validPeaksBuffer);
int validValesCount = ArraySize(x121Conditions.validValesBuffer);
//
XPOIState state;
ENUM_XPOI_EVENTS events[];
mPOIDetector.Update(events);
mPOIDetector.GetState(state);
result = state.IsValid() &&
state.HasChild();
if (!result)
{
return result;
}
//
// Supply Zones ...
XCSupplyZone *supplies[];
int suppliesCount = state.CountSupplyZones();
//
// Select Bar Validated Supply Zones ...
if (IsValidSize(suppliesCount))
{
//
for (int i = 0; i < suppliesCount; i++)
{
//
XCSupplyZone *iZone = state.supplyZones[i];
//
// Check Zone is Valid For Bar ...
bool isValid = bar.high < iZone.Lower() &&
ask < iZone.Lower() &&
bid < iZone.Lower();
if (isValid)
{
//
Add(
iZone,
supplies //
);
}
}
}
suppliesCount = ArraySize(supplies);
//
// Select Valid Peaks Filtered Supplies ...
if (IsValidSize(suppliesCount))
{
//
// Check Valid Peaks ...
XCSupplyZone *tmp[];
if (IsValidSize(validPeaksCount))
{
//
for (int i = 0; i < suppliesCount; i++)
{
//
XCSupplyZone *iZone = supplies[i];
//
for (int j = 0; j < validPeaksCount; j++)
{
//
double value = x121Conditions.validPeaksBuffer[j];
//
// Check Valid Peaks in Zone ...
bool isZoneContainsValidValue =
value >= iZone.Lower() &&
value <= iZone.Upper();
if (isZoneContainsValidValue)
{
//
Add(
iZone,
tmp //
);
}
}
}
}
//
Clean(supplies);
Copy(
tmp,
supplies //
);
}
suppliesCount = ArraySize(supplies);
//
// Select Nearest Supply Zone ...
if (IsValidSize(suppliesCount))
{
//
// Check Nearest Supplies ...
for (int i = 0; i < suppliesCount; i++)
{
//
XCSupplyZone *iZone = supplies[i];
if (supplyZone == NULL)
{
supplyZone = iZone;
}
else
{
//
bool canChange =
iZone.Lower() < supplyZone.Lower();
if (canChange)
{
supplyZone = iZone;
}
}
}
}
//
// Demand Zones ...
XCDemandZone *demands[];
int demandsCount = state.CountDemandZones();
//
// Select Bar Validated Demand Zones ...
if (IsValidSize(demandsCount))
{
//
for (int i = 0; i < demandsCount; i++)
{
//
XCDemandZone *iZone = state.demandZones[i];
//
// Check Zone is Valid For Bar ...
bool isValid = bar.low > iZone.Upper() &&
ask > iZone.Upper() &&
bid > iZone.Upper();
if (isValid)
{
//
Add(
iZone,
demands //
);
}
}
}
demandsCount = ArraySize(demands);
//
// Select Valid Vales Filtered Demands ...
if (IsValidSize(demandsCount))
{
//
// Check Valid Vales ...
XCDemandZone *tmp[];
if (IsValidSize(validValesCount))
{
//
for (int i = 0; i < demandsCount; i++)
{
//
XCDemandZone *iZone = demands[i];
//
for (int j = 0; j < validValesCount; j++)
{
//
double value = x121Conditions.validValesBuffer[j];
//
// Check Valid Peaks in Zone ...
bool isZoneContainsValidValue =
value >= iZone.Lower() &&
value <= iZone.Upper();
if (isZoneContainsValidValue)
{
//
Add(
iZone,
tmp //
);
}
}
}
}
//
Clean(demands);
Copy(
tmp,
demands //
);
}
demandsCount = ArraySize(demands);
//
// Select Nearest Demand Zone ...
if (IsValidSize(demandsCount))
{
//
// Check Nearest Demands ...
for (int i = 0; i < demandsCount; i++)
{
//
XCDemandZone *iZone = demands[i];
if (demandZone == NULL)
{
demandZone = iZone;
}
else
{
//
bool canChange =
iZone.Upper() > demandZone.Upper();
if (canChange)
{
demandZone = iZone;
}
}
}
}
//
// Validate Founded Zones ...
result = (supplyZone != NULL &&
supplyZone.IsValid()) &&
(demandZone != NULL &&
demandZone.IsValid());
//
return result;
}
//
// Virtuals ...
/**
* Set Default Properties Values ...
*/
virtual void Default()
{
//
MaxAllowedSavedChanges(50);
}
//
protected:
//
/**
* Calculate Requirements ...
*
* @param barIndex: Integer, Bar Index ...
* @param conditions: X121SMCCycleConditions instance ...
*/
void Calculate(
int barIndex,
X121SMCCycleConditions &conditions //
)
{
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
XOHCL changeBar;
int index =
barIndex <= 0
? 1
: barIndex;
bool isInited = GetBar(
changeBar,
index //
);
if (!isInited)
{
return;
}
//
// Detect Sar Change ...
bool isSarSwitchedToBullish = conditions.x121Conditions.isSarSwitchedToBullish;
bool isSarSwitchedToBearish = conditions.x121Conditions.isSarSwitchedToBearish;
bool isSarChanged = isSarSwitchedToBullish ||
isSarSwitchedToBearish;
//
if (period == PERIOD_M1)
{
//
if (isSarChanged)
{
//
XValueChange sarChanged;
//
datetime time = changeBar.time;
double after = conditions.x121Conditions.sarBuffer[1];
double before = conditions.x121Conditions.sarBuffer[2];
ENUM_X_DIRECTION dir =
isSarSwitchedToBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Initialize Model ...
isInited = sarChanged.Init(
before,
after,
dir,
time //
);
if (isInited)
{
//
isInited = AddSarChange(sarChanged);
if (isInited)
{
Print("Sar Switched ...");
}
}
}
}
//
// Detect Peak Changes ...
//
// Detect Vale Changes ...
}
//
private:
//
// Props ...
XCBarAnalyser *mBarAnalyser;
//
// Change Holders ...
int mMaxAllowedSavedChanges; // Max llowed Changes to Save ...
XValueChange mSarChanges[]; // Holds Parabolic Sar Direction Changes ...
//
// Actions ...
/**
* Release All Resources ...
*/
void DeInit()
{
//
delete mX121Helper;
//
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);
}
/**
* 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;
}
//
// Change Values Actions ...
/**
* Count Saved Parabolic Sar Changes ...
*
* @return ( int )
*/
int CountSarChanges()
{
return ArraySize(mSarChanges);
}
/**
* Add Specified Parabolic Sar Changed Item ...
*
* @param value: XValueChange instance Reference ...
*
* @return ( bool )
*/
bool AddSarChange(XValueChange &value)
{
//
bool result = false;
//
result = value.IsValid();
if (!result)
{
return result;
}
//
int beforeCount = CountSarChanges();
//
AddIfNotExists(
value,
mSarChanges //
);
//
int afterCount = CountSarChanges();
//
result = afterCount == beforeCount + 1;
if (result)
{
//
// Cleaning Up Unused Items ...
int maxAllowed = MaxAllowedSavedChanges();
CleanupArray(
mSarChanges,
maxAllowed //
);
}
//
return result;
}
//
};