last backup ...

This commit is contained in:
2026-01-08 11:39:42 +03:30
parent afafeca00a
commit 963e045e65
249 changed files with 328192 additions and 0 deletions
@@ -0,0 +1,101 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XBaseClass
// 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
//
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// XBase Class ...
class XCBase
{
//
// Public ...
public:
//
// Protected ...
//
// Represent Basic Unique Tag ...
virtual string GetTag() {
return NULL;
}
//
// Retrieve Class Token ...
virtual string GetToken() {
return NULL;
}
//
// Protected
protected:
//
// Private ...
private:
};
//
template <typename T>
string GenerateSpecifiedCommonSummary(
T &mItem,
string separator = "\n",
bool includeScores = true,
bool setLabel = false //
)
{
//
string result = NULL;
//
double bullishScore = 0;
double bearishScore = 0;
mItem.GenerateScore(
bullishScore,
bearishScore //
);
//
result =
//
(!setLabel
? ""
: "Commons:" + separator) +
"---------------" + separator +
"Symbol: " + mItem.symbol + separator +
"Period: " + ToXString(mItem.period) + separator +
"Time: " + ToXString(mItem.time) + separator +
(includeScores
? "---------------" + separator +
"Scores:" + separator +
"---------------" + separator +
"Bullish: " + ToXString(bullishScore) + separator +
"Bearish: " + ToXString(bearishScore) + separator +
"---------------" + separator
: "") +
""
//
;
//
return result;
}
//
@@ -0,0 +1,408 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCAccount
// Description: provides all Account requirements ...
//
//
// 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
//
// START Definitions ...
//
//
// END Definitions ...
//
//
// START Import and Inclused requirements ...
//
//
// Includes ...
#include "../Classes/x-saherelm.base.class.mq5"
#include <Trade/AccountInfo.mqh>
//
// END Import and Inclused requirements ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Class for Manage Account ...
class XCAccount : public XCBase
{
//
// Public ...
public:
//
// Constructor ...
XCAccount()
{
//
mAccountInfo = new CAccountInfo();
}
//
// Deconstructor ...
~XCAccount()
{
}
//
// START Provided Functions ...
//
//
// User Account ...
long GetUserAccount()
{
return mAccountInfo.Login();
}
//
// Account Leverage ...
long GetLeverage()
{
return mAccountInfo.Leverage();
}
//
// Get Trade Expert State ...
bool CanExpertTrade()
{
return mAccountInfo.TradeExpert();
}
//
// User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ...
// --------------------------
// ACCOUNT_TRADE_MODE_DEMO
// ACCOUNT_TRADE_MODE_CONTEST
// ACCOUNT_TRADE_MODE_REAL
ENUM_ACCOUNT_TRADE_MODE GetTradeMode()
{
return mAccountInfo.TradeMode();
}
//
// Get Account Balance ...
double GetBalance()
{
return mAccountInfo.Balance();
}
//
// Get the amount of give Credit ...
double GetCredit()
{
return mAccountInfo.Credit();
}
//
// Get the amount of current Profit on account ...
double GetProfit()
{
return mAccountInfo.Profit();
}
//
// Get the amount of current Equity on account ...
double GetEquity()
{
return mAccountInfo.Equity();
}
//
// Get the amount of reserved Margin ...
double GetMargin()
{
return mAccountInfo.Margin();
}
//
// Get the amount of free Margin ...
double GetFreeMargin()
{
return mAccountInfo.FreeMargin();
}
//
// Get the Level of Margin ...
double GetMarginLevel()
{
return mAccountInfo.MarginLevel();
}
//
// Get the Level Of Margin for a Deposit ...
double GetMarginCall()
{
return mAccountInfo.MarginCall();
}
//
// Get the Level of Margin for Stop out ...
double GetMarginStopOut()
{
return mAccountInfo.MarginStopOut();
}
//
// Get the Client Name ...
string GetName()
{
return mAccountInfo.Name();
}
//
// Get the Trade Server Name ...
string GetServerName()
{
return mAccountInfo.Server();
}
//
// Get deposit Currency Name ...
string GetCurrency()
{
return mAccountInfo.Currency();
}
//
// Get the Company Name that serves an Account ...
string GetCompany()
{
return mAccountInfo.Company();
}
//
// Calculate Profits for the current account based on passed parameters ...
double CalculateTradeProfit(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry, // open price
double exit // close price
)
{
//
double result = mAccountInfo.OrderProfitCheck(
symbol,
type,
volume,
entry,
exit);
//
return result;
}
//
// Calculate amount of margin which required for trade operation ...
double CalculateMarging(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry // open price
)
{
//
double result = mAccountInfo.MarginCheck(
symbol,
type,
volume,
entry);
//
return result;
}
//
// Calculate amount of free margin left after trade operation ...
double CalculateFreeMarging(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double volume, // volume
double entry // open price
)
{
//
double result = mAccountInfo.FreeMarginCheck(
symbol,
type,
volume,
entry);
//
return result;
}
//
// Calculate the Maximum possible volume of trade operation ...
double CalculateMaxVolume(
const string symbol, // trading symbol
ENUM_ORDER_TYPE type, // order type
double entry, // open price
double percent = 100 // percent of available margin
)
{
//
double result = mAccountInfo.MaxLotCheck(
symbol,
type,
entry,
percent);
//
return result;
}
//
// Calculate Point Value for Given Symbol based on Account ...
double GetPointValue(
string symbol // trading symbol
)
{
//
double result = 0;
//
double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
//
double ticksPerPoint = tickSize / point;
//
result = tickValue / ticksPerPoint;
//
return result;
}
//
// Calculate Risk Amount based on account Currency by Providing:
// Points and Volume ...
double CalculateRiskAmount(
string symbol, // trading symbol
double points, // amount of Risk Points
double volume // position Volume
)
{
//
double result = 0;
//
double pointValue = GetPointValue(symbol);
//
result = pointValue * volume * points;
//
return result;
}
//
// Calculate Risk Points based on account Currency by Providing:
// Volume and Amount ...
double CalculateRiskPoints(
string symbol, // trading symbol
double volume, // position Volume
double amount // amount of Risk based on Account Currency
)
{
//
double result = 0;
//
double pointValue = GetPointValue(symbol);
//
result = amount / (pointValue * volume);
//
return result;
}
//
// Calculate Volume based on account Currency by Providing:
// Amount and Risk Points ...
double CalculateVolume(
string symbol, // trading symbol
double amount, // amount of Risk based on Account Currency
double points // amount of Risk Points
)
{
//
double result = 0;
//
points =
points <= 0
? 10
: points;
//
double pointValue = GetPointValue(symbol);
//
result = amount / (pointValue * points);
//
return result;
}
/**
* Retrieve Specified Message for Report Balance ...
*
* @return ( string )
*/
string GetBalanceReportMessage()
{
return "Balance: " + ToXString(GetBalance()) + " " + GetCurrency();
}
//
// END Provided Functions ...
//
//
// Protected ...
protected:
//
// Private ...
private:
//
// Account Info ...
CAccountInfo mAccountInfo;
};
//
// START Usefull Functions ...
//
//
// END Usefull Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,278 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCPanel
// 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 <Controls/Dialog.mqh>
//
#include "../Classes/x-saherelm.base.class.mq5"
//
// Extentions ...
/**
* Check a Qery Contains in a Content or not ...
*
* @param mQuery: String ...
* @param mContent: String ...
* @param ignoreCase: Boolean ...
*
* @return ( bool )
*/
bool XContains(
string mQuery, // Search String
string mContent, // Search Content
bool ignoreCase = true // Ignore Case
)
{
return Contains(
mQuery,
mContent,
ignoreCase //
);
}
//
// Implementation ...
//
// a Base App Dialog Class ...
class XCAppDialog : public CAppDialog
{
public:
//
// Action ...
//
// Virual ...
/**
* Override Close Button Click Action ...
*/
void OnClickButtonClose()
{
//
bool isClosed = ConfirmDialog("Close EA ?");
//
if (isClosed)
{
Destroy();
}
}
//
// Configuration Actions ...
/**
* Show or Hide Minimize Button ...
*
* @param show: boolean
*/
void MinimizeButton(bool show)
{
//
int controlIDX = ControlFind("MinMax");
if (!IsValidIndex(controlIDX))
{
return;
}
//
if (show)
{
Control(controlIDX).Show();
}
else
{
Control(controlIDX).Hide();
}
}
/**
* Show or Hide Close Button ...
*
* @param show: boolean
*/
void CloseButton(bool show)
{
//
int controlIDX = ControlFind("Close");
if (!IsValidIndex(controlIDX))
{
return;
}
//
if (show)
{
Control(controlIDX).Show();
}
else
{
Control(controlIDX).Hide();
}
}
/**
* Minimize Functionality Implementation ...
*/
void Minimize()
{
//
m_minimized = true;
Rebound(m_min_rect);
ClientAreaVisible(false);
}
/**
* Set Background Color ...
*
* @param clr: Color ...
*/
void BackgroundColor(color clr)
{
//
int controlIDX = ControlFind("Client");
if (!IsValidIndex(controlIDX))
{
return;
}
//
CWnd *obj = Control(controlIDX);
CWndClient *wndclient = (CWndClient *)obj;
//
wndclient.ColorBackground(clr);
}
//
// Overrides ...
//
protected:
//
/**
* Find Specific Control in Dialog ...
*
* @param name: String to Search
*
* @return ( int )
*/
int ControlFind(string name)
{
//
int result = -1;
//
if (!IsValid(name))
{
return result;
}
//
int count = ControlsTotal();
if (!IsValidSize(count))
{
return result;
}
//
for (int i = 0; i < count; i++)
{
//
string iName = Control(i).Name();
//
bool isContains = XContains(
name,
iName,
true // Ignore Case ...
);
if (isContains)
{
//
result = i;
break;
}
}
//
return result;
}
/**
* Create and Run Confirm Dialog ...
*
* @param message: message for Message Box ...
*
* @return ( bool )
*/
bool ConfirmDialog(string message = NULL)
{
//
bool result = false;
//
if (!IsValid(message))
{
message = "Confirm ?";
}
//
int dialogResult = MessageBox(message, NULL, MB_YESNO);
//
// use 'switch' or 'if' as needed
switch (dialogResult)
{
//
// Yes ...
case IDYES:
result = true;
break;
//
// No ...
case IDNO:
result = false;
break;
//
// Cancel ...
case IDCANCEL:
result = false;
break;
}
//
return result;
}
//
private:
//
//
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,872 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCChartHelper
// Description: Chart Helper Tools ...
//
// 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"
//
// Implementation ...
class XCChartHelper : public XCBase
{
//
// Public ...
public:
//
//
// Constructor ...
XCChartHelper(
ulong _chartId = 0,
string _symbol = NULL,
ENUM_TIMEFRAMES _period = NULL)
{
//
bool canSetSymbolPeriod =
IsSpecifiedValid(_symbol) &&
IsSpecifiedValid(_period);
//
// Normalize ...
if (!canSetSymbolPeriod)
{
//
mChartID = NormalizeChartId(_chartId);
mSymbol = NormalizeSymbol(_symbol);
mPeriod = NormalizePeriod(_period);
}
else
{
//
SetSymbolPeriod(mSymbol, mPeriod);
}
}
//
// Desconstructor ...
~XCChartHelper()
{
}
//
// Actioins ...
/**
* Redraw Specified Chart ...
*/
void Redraw()
{
ChartRedraw(mChartID);
}
/**
* Chart Navigation ...
*
* @param position: ENUM_CHART_POSITION
* @param shift: int
*
* @return ( bool )
*/
bool Navigate(
ENUM_CHART_POSITION position,
int shift //
)
{
return (ChartNavigate(mChartID, position, shift));
}
/**
* Apply a Template to Chart ...
*
* @param filename: string file path ...
*
* @return ( bool )
*/
bool ApplyTemplate(string filename)
{
return (ChartApplyTemplate(mChartID, filename));
}
/**
* Add Specified Indicator to Chart ...
*
* @param subWindow: int ...
* @param handle: int ...
*
* @return ( bool )
*/
bool IndicatorAdd(int subWindow, int handle)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (ChartIndicatorAdd(mChartID, subWindow, handle));
}
/**
* Delete Specified Indicator from Chart ...
*
* @param subWindow: int ...
* @param name: string ...
*
* @return ( bool )
*/
bool IndicatorDelete(int subWindow, string name)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (ChartIndicatorDelete(mChartID, subWindow, name));
}
/**
* Count all Charts Indicator ...
*
* @param subWindow: int ...
*
* @return ( int )
*/
int IndicatorsTotal(int subWindow)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (ChartIndicatorsTotal(mChartID, subWindow));
}
/**
* Get Specified Indexed Indicator's Name ...
*
* @param subWindow: int ...
* @param index: int ...
*
* @return ( string )
*/
string IndicatorName(int subWindow, int index)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (ChartIndicatorName(mChartID, subWindow, index));
}
/**
* Set Chart Symbol, Period ...
*
* @param symbol: string ...
* @param period: ENUM_TIMEFRAMES ...
*
* @return ( bool )
*/
bool SetSymbolPeriod(
string symbol,
ENUM_TIMEFRAMES period //
)
{
bool result = (ChartSetSymbolPeriod(mChartID, symbol, period));
if (result)
{
//
mSymbol = symbol;
mPeriod = period;
}
//
return result;
}
/**
* Take an Screenshot of Chart ...
*
* @param filename: string file path ...
* @param width: int ...
* @param height: int ...
* @param align_mode: ENUM_ALIGN_MODE ...
*
* @return ( bool )
*/
bool ScreenShot(
const string filename,
const int width,
const int height,
const ENUM_ALIGN_MODE align_mode //
) const
{
return (ChartScreenShot(mChartID, filename, width, height, align_mode));
}
/**
* Writing parameters of chart to file ...
**/
bool Save(const int file_handle)
{
//
string work_str;
int work_int;
//
bool has = false;
//
// Validate ...
if (file_handle == INVALID_HANDLE || mChartID == -1)
{
return has;
}
//
// Write start marker - 0xFFFFFFFFFFFFFFFF ...
has = FileWriteLong(file_handle, -1) == sizeof(long);
if (!has)
{
return has;
}
//
// Write chart type ...
has = FileWriteInteger(file_handle, Type(), INT_VALUE) == INT_VALUE;
if (!has)
{
return has;
}
//
// Write chart symbol ...
work_str = Symbol();
work_int = StringLen(work_str);
has = FileWriteInteger(file_handle, work_int, INT_VALUE) == INT_VALUE;
if (!has)
{
return has;
}
if (work_int != 0)
{
//
has = FileWriteString(file_handle, work_str, work_int) == work_int;
if (!has)
{
return has;
}
}
//
// Write Period of chart ...
has = FileWriteInteger(file_handle, Period(), INT_VALUE) == sizeof(int);
if (!has)
{
return has;
}
//
// Write value of the "Mode" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_MODE), INT_VALUE) == sizeof(int);
if (!has)
{
return has;
}
//
// Write value of the "Foreground" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_FOREGROUND), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "Shift" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHIFT), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ShiftSize" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHIFT), INT_VALUE) == sizeof(int);
if (!has)
{
return has;
}
//
// Write value of the "AutoScroll" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_AUTOSCROLL), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "Scale" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALE), INT_VALUE) == sizeof(int);
if (!has)
{
return has;
}
//
// Write value of the "ScaleFix" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALEFIX), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ScaleFix_11" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALEFIX_11), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "FixedMax" property ...
has = FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_FIXED_MAX)) == sizeof(double);
if (!has)
{
return has;
}
//
// Write value of the "FixedMin" property ...
has = FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_FIXED_MIN)) == sizeof(double);
if (!has)
{
return has;
}
//
// Write the "ScalePPB" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SCALE_PT_PER_BAR), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "PointsPerBar" property ...
has = FileWriteDouble(file_handle, ChartGetDouble(mChartID, CHART_POINTS_PER_BAR)) == sizeof(double);
if (!has)
{
return has;
}
//
// Write value of the "ShowOHLC" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_OHLC), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ShowLineBid" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_BID_LINE), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ShowLineAsk" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_ASK_LINE), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ShowLastLine" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_LAST_LINE), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ShowPeriodSep" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_PERIOD_SEP), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ShowGrid" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_GRID), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
// Write value of the "ShowVolumes" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_VOLUMES), INT_VALUE) == sizeof(int);
if (!has)
{
return has;
}
//
// Write value of the "ShowObjectDescr" property ...
has = FileWriteInteger(file_handle, (int)ChartGetInteger(mChartID, CHART_SHOW_OBJECT_DESCR), CHAR_VALUE) == sizeof(char);
if (!has)
{
return has;
}
//
return has;
}
/**
* Load Specified Chart File ...
*
* @param file_handle: int ...
*
* @return ( bool )
*/
bool Load(const int file_handle)
{
//
string work_str;
int work_int;
//
bool has = false;
//
// Validate ...
if (file_handle == INVALID_HANDLE || mChartID == -1)
{
return has;
}
//
// Read and checking start marker - 0xFFFFFFFFFFFFFFFF ...
if (FileReadLong(file_handle) != -1)
return has;
//
// Read and checking chart type ...
if (FileReadInteger(file_handle, INT_VALUE) != Type())
return has;
//
// Read chart symbol ...
work_int = FileReadInteger(file_handle);
if (work_int != 0)
{
work_str = FileReadString(file_handle, work_int);
}
else
{
work_str = "";
}
//
// Read chart period ...
work_int = FileReadInteger(file_handle);
SetSymbolPeriod(work_str, (ENUM_TIMEFRAMES)work_int);
//
// Read value of the "Mode" property ...
has = ChartSetInteger(mChartID, CHART_MODE, FileReadInteger(file_handle, INT_VALUE));
if (!has)
{
return has;
}
//
// Read value of the "Foreground" property ...
has = ChartSetInteger(mChartID, CHART_FOREGROUND, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Read value of the "Shift" property ...
has = ChartSetInteger(mChartID, CHART_SHIFT, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Read value of the "ShiftSize" property ...
has = ChartSetInteger(mChartID, CHART_SHIFT, FileReadInteger(file_handle, INT_VALUE));
if (!has)
{
return has;
}
//
// Read value of the "AutoScroll" property ...
has = ChartSetInteger(mChartID, CHART_AUTOSCROLL, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Read value of the "Scale" property ...
has = ChartSetInteger(mChartID, CHART_SCALE, FileReadInteger(file_handle, INT_VALUE));
if (!has)
{
return has;
}
//
// Read value of the "ScaleFix" property ...
has = ChartSetInteger(mChartID, CHART_SCALEFIX, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Read value of the "ScaleFix_11" property ...
has = ChartSetInteger(mChartID, CHART_SCALEFIX_11, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "FixedMax" property ...
has = ChartSetDouble(mChartID, CHART_FIXED_MAX, FileReadDatetime(file_handle));
if (!has)
{
return has;
}
//
// Rread value of the "FixedMin" property ...
has = ChartSetDouble(mChartID, CHART_FIXED_MIN, FileReadDatetime(file_handle));
if (!has)
{
return has;
}
//
// Rread value of the "ScalePPB" property ...
has = ChartSetInteger(mChartID, CHART_SCALE_PT_PER_BAR, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "PointsPerBar" property ...
has = ChartSetDouble(mChartID, CHART_POINTS_PER_BAR, FileReadDatetime(file_handle));
if (!has)
{
return has;
}
//
// Rread value of the "ShowOHLC" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_OHLC, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "ShowLineBid" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_BID_LINE, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "ShowLineAsk" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_ASK_LINE, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "ShowLastLine" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_LAST_LINE, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "ShowPeriodSep" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_PERIOD_SEP, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "ShowGrid" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_GRID, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "ShowVolumes" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_VOLUMES, FileReadInteger(file_handle, INT_VALUE));
if (!has)
{
return has;
}
//
// Rread value of the "ShowObjectDescr" property ...
has = ChartSetInteger(mChartID, CHART_SHOW_OBJECT_DESCR, FileReadInteger(file_handle, CHAR_VALUE));
if (!has)
{
return has;
}
//
return has;
}
ulong Open()
{
//
mChartID = ChartOpen(mSymbol, mPeriod);
return (mChartID);
}
void Close()
{
//
if (mChartID != -1 && mChartID != 0)
{
ChartClose(mChartID);
mChartID = 0;
}
}
//
// Properties ...
/**
* Get Chart ID ...
*
* @return ( ulong )
*/
ulong ChartId()
{
return mChartID;
}
/**
* Get Object Type ...
*
* @return ( int )
**/
int Type() const
{
return (0x1111);
}
/**
* Get Chart Mode ...
*
* @return ( ENUM_CHART_MODE )
**/
ENUM_CHART_MODE Mode()
{
return ((ENUM_CHART_MODE)ChartGetInteger(mChartID, CHART_MODE));
}
/**
* Get Chart Symbol ...
*
* @return ( string )
*/
string Symbol()
{
return (ChartSymbol(mChartID));
}
/**
* Get Chart Period ...
*
* @return ( ENUM_TIMEFRAMES )
*/
ENUM_TIMEFRAMES Period()
{
return (ChartPeriod(mChartID));
}
/**
* Count Chart Visible Bars ...
*
* @return ( int )
*/
int VisibleBars()
{
return ((int)ChartGetInteger(mChartID, CHART_WIDTH_IN_BARS));
}
/**
* Get Chart First Visible Bars Index ...
*
* @return ( int )
*/
int FirstVisibleBar()
{
return ((int)ChartGetInteger(mChartID, CHART_FIRST_VISIBLE_BAR));
}
/**
* Get Chart Last Visible Bars Index ...
*
* @return ( int )
*/
int LastVisibleBar()
{
//
int first = FirstVisibleBar();
int count = VisibleBars();
int result = first + count;
return result;
}
/**
* Get Chart's Specified SubWindows Minimum Price ...
*
* @param subWindow: int
* @return ( double )
*/
double PriceMin(int subWindow = 0)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (ChartGetDouble(mChartID, CHART_PRICE_MIN, subWindow));
}
/**
* Get Chart's Specified SubWindows Maximum Price ...
*
* @param subWindow: int
* @return ( double )
*/
double PriceMax(int subWindow = 0)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (ChartGetDouble(mChartID, CHART_PRICE_MAX, subWindow));
}
/**
* Get Chart Width in Pixel ...
*
* @param subWindow: int ...
*
* @return ( int )
*/
int Width(int subWindow = 0)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (int)ChartGetInteger(mChartID, CHART_WIDTH_IN_PIXELS, subWindow);
}
/**
* Get Chart Height in Pixel ...
*
* @param subWindow: int ...
*
* @return ( int )
*/
int Height(int subWindow = 0)
{
//
// Normalize Subwindow ...
if (subWindow <= 0)
{
subWindow = 0;
}
//
return (int)ChartGetInteger(mChartID, CHART_HEIGHT_IN_PIXELS, subWindow);
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
//
ulong mChartID; // Chart ID ...
string mSymbol; // Chart Symbol ...
ENUM_TIMEFRAMES mPeriod; // Chart Period ...
};
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,362 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XCDataCollector ...
// Description: Class for Handling Data Read or Write ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm Class for Handling Data Read or Write"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.base.class.mq5"
//
// Definitions ...
//
// Implementation ...
class XCDataCollector : public XCBase
{
//
// Public ...
public:
//
// Constructors ...
XCDataCollector()
{
mPath = "XDataCollector";
}
//
// Deconstructor ...
~XCDataCollector()
{
}
//
// Properties ...
//
string Path()
{
return mPath;
}
//
void Path(string value)
{
mPath = value;
}
//
// Tools ...
//
string GetFilePath(string fileName)
{
//
string result = "";
//
result =
//
(IsValid(mPath) ? mPath + "\\" : "") + fileName + ".x121.log"
//
;
//
return result;
}
//
int GetFileHandlerForWrite(string filePath)
{
//
int result = INVALID_HANDLE;
//
if (!IsValid(filePath))
{
return result;
}
//
result = FileOpen(
filePath,
FILE_READ | FILE_WRITE | FILE_TXT //
);
//
return result;
}
//
int GetFileHandlerForRead(string filePath)
{
//
int result = INVALID_HANDLE;
//
if (!IsValid(filePath))
{
return result;
}
//
result = FileOpen(
filePath,
FILE_READ | FILE_TXT | FILE_ANSI //
);
//
return result;
}
/**
* Save Specified Content into Specified File Name ...
*
* @param fileName: string, file name ...
* @param content: string, content ...
*
* @return ( bool )
*/
bool Save(
string fileName,
string content //
)
{
//
bool result = false;
//
result = IsValid(fileName) &&
IsValid(content);
if (!result)
{
return result;
}
//
int mHandler = GetFileHandlerForWrite(fileName);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
FileWrite(mHandler, content);
FileFlush(mHandler);
FileClose(mHandler);
//
return result;
}
/**
* Append Specified Content into Specified File Name ...
*
* @param fileName: string, file name ...
* @param content: string, content ...
*
* @return ( bool )
*/
bool Append(
string fileName,
string content //
)
{
//
bool result = false;
//
result = IsValid(fileName) &&
IsValid(content);
if (!result)
{
return result;
}
//
int mHandler = GetFileHandlerForWrite(fileName);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
FileSeek(mHandler, 0, SEEK_END);
FileWrite(mHandler, content);
FileFlush(mHandler);
FileClose(mHandler);
//
return result;
}
/**
* Read Specified File Content ...
*
* @param fileName: string, file name ...
* @param content: string reference, hold's reading content ...
*
* @return ( bool )
*/
bool Read(
string fileName,
string &content //
)
{
//
bool result = false;
//
// Normalize Args ...
content = NULL;
//
// Validate Args ...
result = IsValid(fileName);
if (!result)
{
return result;
}
//
int mHandler = GetFileHandlerForRead(fileName);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
// Reading File ...
while (!FileIsEnding(mHandler))
{
//
string iLine = FileReadString(mHandler);
content += iLine;
}
//
// Close File ...
FileClose(mHandler);
//
return result;
}
/**
* Read Specified File Content ...
*
* @param fileName: string, file name ...
* @param content: string reference collection, hold's reading content lines ...
*
* @return ( bool )
*/
bool Read(
string fileName,
string &content[] //
)
{
//
bool result = false;
//
// Normalize Args ...
Clean(content);
//
// Validate Args ...
result = IsValid(fileName);
if (!result)
{
return result;
}
//
int mHandler = GetFileHandlerForRead(fileName);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
// Reading File ...
while (!FileIsEnding(mHandler))
{
//
string iLine = FileReadString(mHandler);
Add(
iLine,
content //
);
}
//
// Close File ...
FileClose(mHandler);
//
return result;
}
/**
* Check Specified File Exists or not ...
*
* @param fileName: string, Full Path of File to Check ...
*
* @return ( bool )
*/
bool IsExists(string fileName)
{
//
bool result = false;
//
// Validate Args ...
result = IsValid(fileName);
if (!result)
{
return result;
}
//
// Check File Exists or not ...
int mHandler = GetFileHandlerForRead(fileName);
result = mHandler != INVALID_HANDLE;
FileClose(mHandler);
//
return result;
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
//
string mPath; // Base Collector Path ...
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,671 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCBaseHelper
// Description: provides all Base Indicator
// Helper requirements ...
//
//
// 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
//
// Includes ...
#include "../Classes/x-saherelm.base.class.mq5"
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
//
// Definitions ...
//
// a Class for Handle base requirements ...
// for indicators ...
class XCBaseHelper : public XCBase
{
//
// Public ...
public:
//
// Constructor ...
XCBaseHelper(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period // Trading Time Frame
)
{
//
mSymbol = symbol;
mPeriod = period;
}
//
// Deconstructor ...
~XCBaseHelper()
{
//
IndicatorRelease(mHandler);
}
//
// Setter(s) / Getter(s) ...
//
// Symbol ...
string GetSymbol()
{
return mSymbol;
}
//
// Period ...
ENUM_TIMEFRAMES GetPeriod()
{
return mPeriod;
}
//
// Retrieve Bars ...
int CountBars()
{
//
int result =
Bars(
mSymbol,
mPeriod
//
);
//
return result;
}
//
// Retrieve Indicator Calculated Bars ...
int CountCalculatedBars()
{
return BarsCalculated(mHandler);
}
//
virtual void Free()
{
}
//
// Generate Tag ...
virtual string GetTag()
{
//
string result = NULL;
//
result =
//
GetToken() +
"[" +
GetSymbol() + "|" +
ToXString(GetPeriod()) +
"]"
//
;
//
return result;
}
//
// Functions ...
/**
* Validate Handler Exists ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = IsXValid(mSymbol) &&
IsXValid(mPeriod) &&
mHandler != INVALID_HANDLE;
//
return result;
}
/**
* Extract Validated Zones ...
*
* @param zones: XBoxZone, collection reference to holds results ...
* @param barIndex: int, Specified Bar Index ...
* @param requiredNumberOFZones: int, required Number of Zones ...
* @param breakValidLength: int, Breake Validation Length of Zones ...
* @param validateFakeBreakes: bool, Validation Fake Breaked Zones ...
* @param shadowMultiplier: double a Shadow Multiplier for Validation ...
* @param validationStrength: double, Minimum Strngth Multiplier in Point to Validate ...
* @param validationLength: int, Validation Length of Zones ...
* @param maxAllowedLoopbackLength: int, max Allowed Loopback Length ...
*
* @return ( int )
*/
int ExtractBarZones(
XBoxZone &zones[],
int barIndex = 0,
int requiredNumberOFZones = 50,
int breakValidLength = 3,
bool validateFakeBreakes = true,
double shadowMultiplier = 3,
double validationStrength = 1,
int validationLength = 21,
int maxAllowedLoopbackLength = 1500 //
)
{
//
int result = 0;
//
// Prepare ...
SpecifiedClean(zones);
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
validationLength = NormalizeInt(validationLength, 7);
shadowMultiplier = NormalizeDouble(shadowMultiplier, 1);
validationStrength = NormalizeDouble(validationStrength, 1);
requiredNumberOFZones = NormalizeInt(requiredNumberOFZones, 5);
maxAllowedLoopbackLength = NormalizeInt(maxAllowedLoopbackLength, 100);
//
// Reading Values ...
//
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
double minAllowedStrength = (validationStrength * GetPoints(symbol));
//
XOHCL bar;
bool has = false;
//
// Initialized Start Bar ...
has = bar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
return result;
}
//
XOHCL iBar;
XBoxZone zone;
int start = barIndex;
bool isBullish = false;
bool isBearish = false;
bool lowShadowPassed = false;
bool highShadowPassed = false;
ENUM_X_DIRECTION dir = X_DIRECTION_NONE;
int end = start + maxAllowedLoopbackLength;
for (int i = start; i < end; i++)
{
//
// Cleanup ...
iBar.Clean();
zone.Clean();
dir = X_DIRECTION_NONE;
//
// Reading HK Buffesr ...
has = bar.BarAt(i, iBar);
if (!has)
{
continue;
}
//
// Check Direction ...
isBullish = iBar.open < iBar.close;
isBearish = iBar.open > iBar.close;
dir =
(isBullish && !isBearish)
? X_DIRECTION_BULLISH
: (isBearish && !isBullish)
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
has = HasDirection(dir);
if (!has)
{
continue;
}
//
// Low Shadow ...
lowShadowPassed = iBar.GetLowShadow() >= (shadowMultiplier * iBar.GetHighShadow());
//
// High Shadow ...
highShadowPassed = iBar.GetHighShadow() >= (shadowMultiplier * iBar.GetLowShadow());
//
has = (lowShadowPassed && !highShadowPassed) ||
(highShadowPassed && !lowShadowPassed);
if (!has)
{
continue;
}
//
// Filling Zone ...
//
zone.symbol = symbol;
zone.period = period;
zone.from = GetBarTime(
zone.symbol,
zone.period,
i //
);
zone.dir = lowShadowPassed
? X_DIRECTION_BULLISH
: highShadowPassed
? X_DIRECTION_BEARISH
: X_DIRECTION_NONE;
//
zone.upper =
IsXBullish(zone.dir)
? iBar.GetDown()
: IsXBearish(zone.dir)
? iBar.high
: EMPTY_VALUE;
//
zone.lower =
IsXBullish(zone.dir)
? iBar.low
: IsXBearish(zone.dir)
? iBar.GetUp()
: EMPTY_VALUE;
//
zone.to = bar.time;
zone.type = "XBar_" + (IsXBullish(zone.dir) ? "Support" : IsXBearish(zone.dir) ? "Resistance"
: "") +
"_" + ToXString(TimeToSeconds(zone.from));
//
// Validate ...
has =
zone.IsValid() &&
HasDirection(zone.dir) &&
NotEmptyZero(zone.upper) &&
NotEmptyZero(zone.lower) &&
(zone.IsBullish()
? bar.low > zone.upper
: bar.high < zone.lower) &&
(zone.upper - zone.lower) >= minAllowedStrength &&
ValidateBarZone(zone, validationLength, breakValidLength, validateFakeBreakes);
if (has)
{
//
AddIfNotExists(
zone,
zones //
);
}
//
// Cleanup Resources ...
zone.Clean();
//
// Validating ...
result = ArraySize(zones);
has = IsValidSize(result) &&
result >= requiredNumberOFZones;
if (has)
{
break;
}
}
//
// Cleanup Resources ...
bar.Clean();
iBar.Clean();
zone.Clean();
//
return result;
}
/**
* Validate Bar Zone ...
*
* @param zone: XBoxZone, reference to Specified Zone ...
* @param validationLength: int, Validation Length of Zones ...
* @param breakValidLength: int, Break Validation Length of Zones ...
* @param validateFakeBreakes: bool, Validation Fake Breaked Zones ...
*
* @return ( bool )
*/
bool ValidateBarZone(
XBoxZone &zone,
int validationLength = 1,
int breakValidLength = 3,
bool validateFakeBreakes = true //
)
{
//
bool result = false;
//
// Normalize ...
validationLength = NormalizeInt(validationLength, 1);
breakValidLength = NormalizeInt(breakValidLength, 2);
//
// Validate ...
result = zone.IsValid();
if (!result)
{
return result;
}
//
// Requirements ...
XOHCL iBar;
int count = 0;
string symbol = GetSymbol();
ENUM_TIMEFRAMES period = GetPeriod();
//
int start = zone.FromIndex() + 1;
int end = start + validationLength;
//
// Validate Before ...
for (int i = start; i < end; i++)
{
//
// Initialize Indexed Bar ...
iBar.Clean();
result = iBar.Init(
symbol,
period,
i //
);
if (!result)
{
break;
}
//
result = zone.IsBullish()
? iBar.low > zone.lower
: iBar.high < zone.upper;
if (!result)
{
break;
}
}
//
// Validating After ...
if (result)
{
//
start = zone.ToIndex() + 1;
count = zone.FromIndex() - start;
end = start + count;
for (int i = start; i < end; i++)
{
//
// Initialized Indexed Bar ...
iBar.Clean();
result = iBar.Init(
symbol,
period,
i //
);
if (!result)
{
break;
}
//
result = zone.IsBullish()
? iBar.low > zone.lower
: iBar.high < zone.upper;
if (!result)
{
//
// Check For Fake Breake ...
if (validateFakeBreakes && breakValidLength > 0)
{
//
result = i - 1 >= 0;
if (result)
{
//
for (int j = i - 1; j >= zone.ToIndex(); j--)
{
//
// Initialized Indexed Bar ...
iBar.Clean();
result = iBar.Init(
symbol,
period,
j //
);
if (!result)
{
break;
}
//
result = zone.IsBullish()
? iBar.close > zone.upper
: iBar.close < zone.lower;
if (result)
{
//
result = MathAbs(j - i) <= breakValidLength;
if (result)
{
break;
}
}
}
}
}
//
if (!result)
{
break;
}
}
}
}
//
// Cleanup Resource ...
iBar.Clean();
//
return result;
}
/**
* Normalizing Bar Index ...
*
* @param barIndex: int, Provided Bar Index ...
*
* @return ( int )
*/
int NormalizeBarIndex(int barIndex)
{
//
int result = barIndex;
//
if (!IsValid())
{
return result;
}
//
int count = CountBars() - 1;
result = NormalizeInt(result, 0, count - 1);
//
return result;
}
//
// Protected ...
protected:
//
// Props ...
//
// Symbol ...
string mSymbol;
//
// Period ...
ENUM_TIMEFRAMES mPeriod;
//
// Indicator Handler ...
int mHandler;
/**
* Read Value of Specified Buffer ...
*
* @param bufferIndex: int, which handler buffer to read value ...
* @param barIndex: int, Specified Bar Index ...
*
* @return ( double )
*/
double ReadValue(
int bufferIndex,
int barIndex = 0 //
)
{
//
double result = EMPTY_VALUE;
//
// Normalize ...
int barsTotal = CountBars();
barIndex = NormalizeInt(barIndex, 0, barsTotal - 1);
bufferIndex = NormalizeInt(bufferIndex, 0);
//
// Validate ...
if (!IsValid())
{
return result;
}
//
double tmp[];
int count = CopyBuffer(
mHandler,
bufferIndex,
barIndex,
1,
tmp //
);
result = tmp[0];
//
return result;
}
/**
* Read Values of Specified Buffer ...
*
* @param buffer: double, reference collection to holds result ...
* @param bufferIndex: int, which handler buffer to read value ...
* @param barIndex: int, Specified Bar Index ...
* @param count: int, number of items to read, 0 for WHOLE_ARRAY ...
* @param asSeries: bool, set As Series Buffer or not ...
*
* @return ( int )
*/
int ReadValues(
double &buffer[],
int bufferIndex,
int barIndex = 0,
int count = 0,
bool asSeries = true //
)
{
//
int result = 0;
//
// Prepare ...
XClean(buffer);
//
// Normalize ...
int barsTotal = CountBars();
count = NormalizeInt(count, 0);
bufferIndex = NormalizeInt(bufferIndex, 0);
barIndex = NormalizeInt(barIndex, 0, barsTotal - 1);
//
// Validate ...
if (!IsValid())
{
return result;
}
//
result = CopyBuffer(
mHandler,
bufferIndex,
barIndex,
count,
buffer //
);
//
// Set As Series Flag ...
ArraySetAsSeries(buffer, asSeries);
//
result = ArraySize(buffer);
//
return result;
}
//
// Private ...
private:
//
};
//
// Tools ....
@@ -0,0 +1,373 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCHttp
// Description: provides all HTTP requirements ...
//
//
// 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
//
// Definitions ...
//
enum X_HTTP_METHOD
{
X_HTTP_GET,
X_HTTP_POST
};
//
// Imports ...
//
// Includes ...
#include "../Classes/x-saherelm.base.class.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// a Class for Manage Account ...
class XCHttp : public XCBase
{
//
// Public ...
public:
//
// Constructor ...
XCHttp()
{
XCHttp("", 10000);
}
XCHttp(
string path, // Base Folder to Store Data
int timeout // base timeout for Requests
)
{
//
Path(path);
Timeout(timeout);
}
//
// Deconstructor ...
~XCHttp()
{
}
//
// Properties Getter(s) / Setter(s) ...
//
// Path ...
void Path(string value)
{
//
mPath = value;
//
if (!IsValid(mPath))
{
mPath = GetTag();
}
}
string Path()
{
return mPath;
}
//
// Timeout ...
void Timeout(int value)
{
mTimeout = value;
}
//
int Timeout()
{
return mTimeout;
}
//
// Error ...
int Error()
{
return mError;
}
//
// Response ...
string Response()
{
return mResponse;
}
//
// Overrides ...
string GetTag() override
{
return GetSpecificToken(this);
}
//
// Tools ...
//
// Send Global Request ...
int SendRequest(
X_HTTP_METHOD method, // Httm Request Method
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
)
{
//
int result = -1;
//
string strMethod = ToString(method);
if (StringLen(strMethod) == 0)
{
return result;
}
//
// Reset State ...
ResetState();
//
result = WebRequest(
strMethod,
url,
headers,
timeout,
payload,
response,
responseHeaders);
//
if (result < 0)
{
mError = GetLastError();
}
else
{
mResponse = CharArrayToString(response);
}
//
return result;
}
//
// Get Request ...
int GetRequest(
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
)
{
//
int result = SendRequest(
X_HTTP_GET,
url,
headers,
payload,
response,
responseHeaders,
timeout);
//
return result;
}
//
// Post Request ...
int PostRequest(
const string url, // Server Address
const string headers, // Headers providing
const char &payload[], // the Data which needs to Send
char &response[], // Response of request
string responseHeaders, // Response Headers
int timeout = 500 // Timeout for response default is 500
)
{
//
int result = SendRequest(
X_HTTP_POST,
url,
headers,
payload,
response,
responseHeaders,
timeout);
//
return result;
}
//
// Handle Download Specific URL Content to Specific Path and File Name ...
bool Download(
string url, // the URL address which going to download
string fileName // Specify Destination file name to Store Response
)
{
//
bool result = false;
//
string filePath = GetFilePath(fileName);
string cookie = NULL;
string referer = NULL;
int timeout = Timeout();
//
char payload[];
string headers;
char response[];
string responseHeaders;
//
// Send Request ...
int requestResult = GetRequest(
url,
headers,
payload,
response,
responseHeaders,
timeout);
//
// Define File Handler ...
int mFileHandler = FileOpen(
filePath,
FILE_WRITE | FILE_BIN);
if (mFileHandler == INVALID_HANDLE)
{
//
mError = GetLastError();
return result;
}
//
// Write Response to File ...
uint writed = FileWriteArray(
mFileHandler,
response,
0,
ArraySize(response));
FileFlush(mFileHandler);
FileClose(mFileHandler);
//
result = writed > 0;
//
return result;
}
//
// END Provided Functions ...
//
//
// Protected ...
protected:
//
// Destintion Folder Path ...
string mPath;
//
// WEB Request Timeout Value ...
int mTimeout;
//
// WEB Request's Response ...
string mResponse;
//
// Error Value ...
int mError;
//
// Private ...
private:
//
// Reset Errors State ...
void ResetState()
{
//
// Reset Errors ...
mError = -1;
mResponse = "";
ResetLastError();
}
//
// Generate Full File Path ...
string GetFilePath(string fileName)
{
//
string result = "";
//
result =
//
Path() + "\\" + fileName
//
;
//
return result;
}
};
//
// Tools ...
//
// Convert enum to String ...
string ToString(X_HTTP_METHOD method)
{
//
string result = "";
//
switch (method)
{
//
case X_HTTP_GET:
result = "GET";
break;
//
case X_HTTP_POST:
result = "POST";
break;
}
//
return result;
}
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,445 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCMD5
// Description: Provides MD5 Hashing Requirements ...
//
//
// 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
//
// START Definitions ...
//
//
static uchar _md5_PADDING[64] =
{
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//
#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define _md5_H(x, y, z) ((x) ^ (y) ^ (z))
#define _md5_I(x, y, z) ((y) ^ ((x) | (~z)))
#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
//
#define _md5_FF(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_GG(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_HH(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_II(a, b, c, d, x, s, ac) \
{ \
(a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \
(a) = _md5_ROTATE_LEFT((a), (s)); \
(a) += (b); \
}
//
#define _md5_INIT_STATE_0 0x67452301
#define _md5_INIT_STATE_1 0xefcdab89
#define _md5_INIT_STATE_2 0x98badcfe
#define _md5_INIT_STATE_3 0x10325476
//
#define _md5_S11 7
#define _md5_S12 12
#define _md5_S13 17
#define _md5_S14 22
//
#define _md5_S21 5
#define _md5_S22 9
#define _md5_S23 14
#define _md5_S24 20
//
#define _md5_S31 4
#define _md5_S32 11
#define _md5_S33 16
#define _md5_S34 23
//
#define _md5_S41 6
#define _md5_S42 10
#define _md5_S43 15
#define _md5_S44 21
//
// END Definitions ...
//
//
// XCMD5 a library for Hashing ...
class XCMD5
{
//
// Public Provides ...
public:
//
// Protected Provides ...
//
// Constructor ...
XCMD5(void)
{
}
//
// Deconstructor ...
~XCMD5(void)
{
}
//
// Hash Specified Char Array ...
string Hash(
uchar &mSource[], // Specify Char Array to Hash
int mLength = 0 // Specify Length of Char Array which required to hash
)
{
//
string result = "";
//
int sourceCount = ArraySize(mSource);
//
// Validate Args ...
if (
sourceCount <= 0 ||
(sourceCount > 0 && mLength > sourceCount))
{
return result;
}
//
// Normalize Args ...
if (mLength == 0)
{
mLength = sourceCount;
}
//
// Init MD5 ...
MD5Init();
//
// Update Buffer ...
MD5Update(mSource, mLength);
//
// Calculate Result ...
result = MD5Final();
//
return result;
}
//
// Hash Specified String ...
string Hash(
string mSource // Specified String
)
{
//
string result = "";
//
// Converts String to Char Array ...
uchar bytes[];
StringToCharArray(
mSource,
bytes,
0,
StringLen(mSource));
//
result = Hash(
bytes,
ArraySize(bytes));
//
return result;
}
protected:
//
// Private Provides ...
private:
//
uint m_lMD5[4];
uint m_nCount[2];
uchar m_lpszBuffer[64];
//
// Convert Byte to DWord ...
void ByteToDWord(int &out[], uint &in[], uint len)
{
//
uint i = 0;
uint j = 0;
//
for (; j < len; i++, j += 4)
{
out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24;
}
}
//
// Convert DWord to Byte ...
void DWordToByte(uchar &out[], uint &in[], uint len)
{
//
uint i = 0;
uint j = 0;
//
for (; j < len; i++, j += 4)
{
//
out[j] = (uchar)(in[i] & 0xff);
out[j + 1] = (uchar)((in[i] >> 8) & 0xff);
out[j + 2] = (uchar)((in[i] >> 16) & 0xff);
out[j + 3] = (uchar)((in[i] >> 24) & 0xff);
}
}
//
// Init MD5 Array ...
void MD5Init()
{
//
ArrayInitialize(m_lpszBuffer, 64);
//
m_nCount[0] = m_nCount[1] = 0;
m_lMD5[0] = _md5_INIT_STATE_0;
m_lMD5[1] = _md5_INIT_STATE_1;
m_lMD5[2] = _md5_INIT_STATE_2;
m_lMD5[3] = _md5_INIT_STATE_3;
}
//
// Update MD5 ...
void MD5Update(uchar &inBuf[], uint inLen)
{
//
int i, ii;
int mdi;
//
uint in[16];
int i0 = 0;
//
mdi = (int)((m_nCount[0] >> 3) & 0x3F);
//
if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0])
{
m_nCount[1]++;
}
//
m_nCount[0] += ((uint)inLen << 3);
m_nCount[1] += ((uint)inLen >> 29);
//
while ((inLen--) > 0)
{
//
m_lpszBuffer[mdi++] = inBuf[i0++];
if (mdi == 0x40)
{
//
for (i = 0, ii = 0; i < 16; i++, ii += 4)
{
in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]);
}
//
Transform(m_lMD5, in);
//
mdi = 0;
}
}
}
//
// Finalize an MD5 Expression ...
string MD5Final()
{
//
uchar bits[8];
int nIndex;
uint nPadLen;
const int nMD5Size = 16;
uchar lpszMD5[16];
string temp;
string out = "";
int i;
//
DWordToByte(bits, m_nCount, 8);
nIndex = (int)((m_nCount[0] >> 3) & 0x3f);
nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);
MD5Update(_md5_PADDING, nPadLen);
MD5Update(bits, 8);
DWordToByte(lpszMD5, m_lMD5, nMD5Size);
//
for (i = 0; i < nMD5Size; i++)
{
//
if (lpszMD5[i] == 0)
{
temp = "00";
}
else if (lpszMD5[i] <= 15)
{
temp = StringFormat("0%x", lpszMD5[i]);
}
else
{
temp = StringFormat("%x", lpszMD5[i]);
}
//
out += temp;
}
//
lpszMD5[0] = '\0';
//
return (out);
}
//
// Transform Buffers ...
void Transform(uint &buf[], uint &in[])
{
//
uint a = buf[0], b = buf[1], c = buf[2], d = buf[3];
//
_md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478);
_md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756);
_md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB);
_md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE);
_md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF);
_md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A);
_md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613);
_md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501);
_md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8);
_md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF);
_md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1);
_md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE);
_md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122);
_md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193);
_md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E);
_md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821);
//
_md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562);
_md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340);
_md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51);
_md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA);
_md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D);
_md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453);
_md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681);
_md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8);
_md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6);
_md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6);
_md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87);
_md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED);
_md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905);
_md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8);
_md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9);
_md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A);
//
_md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942);
_md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681);
_md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122);
_md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C);
_md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44);
_md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9);
_md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60);
_md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70);
_md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6);
_md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA);
_md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085);
_md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05);
_md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039);
_md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5);
_md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8);
_md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665);
//
_md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244);
_md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97);
_md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7);
_md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039);
_md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3);
_md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92);
_md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D);
_md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1);
_md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F);
_md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0);
_md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314);
_md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1);
_md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82);
_md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235);
_md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB);
_md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391);
//
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,482 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCPositionDrawer
// Description: Provides Position
// Drawing Tools ...
//
// 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 "../Classes/x-saherelm.x-cobject.class.mq5"
#include "../Classes/x-saherelm.x-trade.class.mq5"
#include "../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
//
// Definitions ...
//
// Implementation ...
class XCPositionDrawer : public XCBase
{
//
// Public ...
public:
//
// Props ...
int window; // Window ID of Chart ...
ulong chartID; // Chart ID ...
XCTrade *trader; // XCTrade Instance ...
XPOIStyle riskStyle; // Risk Box Style ...
color inProfitColor; // In Profit Price Box Color ...
color inDrawdownColor; // In Drawdown Price Box Color ...
ENUM_LINE_STYLE priceStyle; // Price Box Style ...
XPOIStyle rewardStyle; // Reward Box Style ...
CArrayObj positionObjects; // Drawn Positions Object Instances Collection ...
CArrayObj finalizedObjects; // Finalized Drawn Positions Object Instances Collection ...
//
// Constructor ...
XCPositionDrawer(
XCTrade *_trader,
ulong _chartID = 0,
int _window = 0 //
) : XCBase()
{
//
Init(
_trader,
_chartID,
_window //
);
}
//
// Deconstructor ...
~XCPositionDrawer()
{
Destroy();
}
//
// Tools ...
/**
* Initialize Class Instance ...
*
* @param _trader: XCTrade, reference Pointer to Trader Instance Class ...
* @param _chartID: ulong, Specified Chart ID ...
* @param _window: int, Specified Chart Window ID ...
*/
void Init(
XCTrade *_trader,
ulong _chartID = 0,
int _window = 0 //
)
{
//
// Validate ...
bool has =
_window >= 0 &&
_chartID >= 0 &&
_trader != NULL;
if (!has)
{
return;
}
//
trader = _trader;
window = _window;
chartID = _chartID;
//
// Prepare Default Styles ...
//
// Risk Style ...
riskStyle.width = 1;
riskStyle.fill = false;
riskStyle.clr = clrRed;
riskStyle.style = STYLE_DASH;
//
// Reward Style ...
rewardStyle.width = 1;
rewardStyle.fill = false;
rewardStyle.clr = clrLime;
rewardStyle.style = STYLE_DASH;
//
// Price Style ...
priceStyle = STYLE_SOLID;
inProfitColor = clrAqua; // ApplyAlpha(clrAqua, 100);
inDrawdownColor = clrMagenta; // ApplyAlpha(clrMagenta, 100);
}
/**
* Destroy Instance ...
*/
void Destroy()
{
//
riskStyle.Clean();
rewardStyle.Clean();
// positionObjects
// finalizedObjects
}
/**
* Validate Instance ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
trader != NULL;
//
return result;
}
/**
* Update Positions ...
*
* @param barIndex: int, Specified Bar Index ...
*/
void Update(int barIndex = 0)
{
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return;
}
//
// Update Exists Positions ...
XPosition positions[];
int positionsCount = trader.GetPositions(positions);
has = IsValidSize(positionsCount);
if (has)
{
//
int drawingsCount = positionObjects.Total();
has = IsValidSize(drawingsCount);
if (has)
{
//
for (int i = 0; i < positionsCount; i++)
{
//
for (int j = 0; j < drawingsCount; j++)
{
//
// Check Object is Belong to Position ...
has = ((XCPositionObject *)positionObjects.At(j)).IsBelong(positions[i]);
if (has)
{
//
// Update Position Object ...
has = ((XCPositionObject *)positionObjects.At(j)).Update(positions[i]);
}
}
}
}
}
//
// Update Test Positions ...
positionsCount = positionObjects.Total();
has =
!HasChild(positions) &&
IsValidSize(positionsCount);
if (has)
{
//
XPosition iPosition;
for (int i = 0; i < positionsCount; i++)
{
//
// Retrieve Position from Object ...
has = ((XCPositionObject *)positionObjects.At(i)).GetPosition(iPosition);
if (has)
{
//
// Manully Update Position ...
has = ((XCPositionObject *)positionObjects.At(i)).Update(barIndex);
}
}
//
iPosition.Clean();
}
}
//
// Trade Event Handlers ...
/**
* Add Executed Signal ...
*
* @param signal: XSignal, reference to Executed Signal ...
*/
void AddExecutedSignal(XSignal &signal)
{
//
// Validate ...
bool has =
signal.IsValid() &&
signal.IsExecuted();
if (!has)
{
return;
}
//
XPosition iPosition;
//
// Check Position Exists ...
has = trader.GetPosition(
signal.positionId,
iPosition //
);
//
// Initial by Testing Position ...
if (!has)
{
//
has = ToXPosition(
signal,
iPosition,
trader.GetMagicNumber(),
signal.positionId //
);
}
//
// Validate result ...
if (has)
{
//
XCPositionObject *iObj = new XCPositionObject();
has = iObj.Create(
chartID,
window,
iPosition //
);
if (has)
{
//
// Set Stylers to Position ...
iObj.riskStyle = riskStyle;
iObj.priceStyle = priceStyle;
iObj.rewardStyle = rewardStyle;
iObj.inProfitColor = inProfitColor;
iObj.inDrawdownColor = inDrawdownColor;
//
// Add to Collection ...
positionObjects.Add(iObj);
}
}
//
// Cleanup Resources ...
iPosition.Clean();
}
/**
* Handle Stop Loss Event Triggered ...
*
* @param deal: XDeal instance refrence, provides Triggered Deal info ...
*/
void HandleStopLossTriggered(const XDeal &deal)
{
//
Finalize(deal.positionId);
}
/**
* Handle Take Profit Event Triggered ...
*
* @param deal: XDeal instance refrence, provides Triggered Deal info ...
*/
void HandleOnTakeProfitTriggered(const XDeal &deal)
{
Finalize(deal.positionId);
}
/**
* Handle Position Force Closed Event ...
*
* @param ticket: ulong, triggered Positions ticket ...
* @param position: XPosition instance refrence, Triggered Position ...
* @param comment: string, Comment ...
*/
void HandleOnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
Finalize(ticket);
}
/**
* Handle Position Modified Event ...
*
* @param ticket: ulong, triggered Positions ticket ...
* @param profit: double, Position Profit ...
* @param comment: string, Comment ...
*/
void HandleOnPositionModified(
const ulong ticket,
const double profit,
const string comment //
)
{
//
// Detect Position Index ...
int index = FindIndex(ticket);
bool has = IsValidIndex(index);
if (!has)
{
return;
}
//
// Get Position of Objects ...
XPosition _position;
has = ((XCPositionObject *)positionObjects.At(index)).GetPosition(_position);
if (has)
{
//
// Get Position of Trader Instance ...
has = trader.GetPosition(
ticket,
_position //
);
if (has)
{
//
// Update Position ...
((XCPositionObject *)positionObjects.At(index)).Update(_position);
}
}
//
// Cleanup Resources ...
_position.Clean();
}
//
// Protected ...
protected:
//
/**
* Finalize Specified Position ...
* Remove it From Position Objects and add it to Finalized Objects Cllection ...
*
* @param ticket: ulong, Specified Position Ticket ...
*/
void Finalize(ulong ticket)
{
//
int index = FindIndex(ticket);
bool has = IsValidIndex(index);
if (!has)
{
return;
}
//
// XCPositionObject *iObj = positionObjects.At(index);
// positionObjects.Delete(index);
// finalizedObjects.Add(iObj);
}
/**
* Find Specified Position Index ...
*
* @param ticket: ulong, Specified Position Ticket ...
*
* @return ( int )
*/
int FindIndex(ulong ticket)
{
//
int result = -1;
//
// Validate ...
int count =
NotEmptyZero(ticket) &&
positionObjects.Total();
bool has = IsValidSize(count);
if (!has)
{
return result;
}
//
XPosition iPosition;
for (int i = 0; i < count; i++)
{
//
has = ((XCPositionObject *)positionObjects.At(i)).GetPosition(iPosition);
has = has &&
iPosition.ticket == ticket;
if (has)
{
//
result = i;
break;
}
}
//
// Cleanup Resources ...
iPosition.Clean();
//
return result;
}
//
// Private ...
private:
//
//
};
//
@@ -0,0 +1,84 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCRestrictions
// Description: provides all Requirements for Apply Restrictions ...
//
//
// 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"
//
// Definitions ...
//
// All awailable Restrictions Period ...
enum ENUM_X_TRADE_RESTRICTIONS_PERIOD
{
X_TRADE_RESTRICATION_NONE, // None
X_TRADE_RESTRICATION_HOURLY, // Per Hour
X_TRADE_RESTRICATION_DAILY, // Per Day
X_TRADE_RESTRICATION_WEEKLY, // Per Week
X_TRADE_RESTRICATION_MONTHLY, // Per Month
};
//
// Converts to String ...
string ToXString(ENUM_X_TRADE_RESTRICTIONS_PERIOD value)
{
//
string result = NULL;
//
result = EnumToString(value);
//
return result;
}
//
// Check Has Restrictions or not ...
bool HasRestrictions(ENUM_X_TRADE_RESTRICTIONS_PERIOD value)
{
//
bool result = false;
//
result = value != X_TRADE_RESTRICATION_NONE;
//
return result;
}
//
// Implementation ...
class XCRestrictions : public XCBase
{
//
// Public ...
public:
//
// Protected ...
protected:
//
// Private ...
private:
//
};
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,742 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class
// -------------------------------------------------
// Name: XCBaseSignaller ...
// Description: Base Signaller Class ...
//
// - Create an Instance based on this ...
// - Attach Required Helpers for Indicator Usages ...
// - Override Virtual Methdos:
// - [] ProcessTick: Processing All Ticks
// - [] ProcessNewBar: Processing All New Bars
// - [] CheckForGuard: Check For Guards
// - [] NormalizeSignal: Normalizing Prepared Signal ...
// - [] CheckAdditionslSignallerValidations: Additional Class Validations
//
// - Dont Forget to Call OnSignal Event in Process Methods when
// a signal Appears ...
//
// - also Whenever you want you can call PrepareSignal Action to
// provide a Signal based on Current Market State ...
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm Base Signaller Class"
#property strict
//
// Imports ...
#include "../Classes/x-saherelm.base.class.mq5"
#include "../Classes/x-saherelm.x-market.pattern.class.mq5"
#include "../Libraries/x-saherelm.x-trade.lib.mq5"
//
// Definitions ...
//
// Implementations ...
class XCBaseSignaller : public XCBase
{
//
// Public ...
public:
//
// Props ...
string name; // Name ...
string symbol; // Symbol ...
ENUM_TIMEFRAMES period; // Period ...
//
bool ignoreTargets; // Ignore Signal Targets ...
double slAdditionDistance; // SL Addition Distance ...
double maxAllowedRiskDistance; // Max Allowed Risk In Points ...
//
// Restrictions ...
datetime restUntil; // Resting Time ...
int restingSignals; // Resting Signals ...
datetime lastSignalAt; // Holding Last Signal's Time ...
int restingDelay; // Resting Bars After Last Signal ...
int loosingTrades; // Loosing Trades ...
//
TCanAnalyse canAnalyseEventListener;
//
XCMarketPatternDetector *patternDetector;
//
// Constructor ...
XCBaseSignaller(
string _name, // Name ...
string _symbol, // Symbol ...
ENUM_TIMEFRAMES _period, // Period ...
bool _processAllTicks = false, // Process All Ticks ...
double _defaultSignalR2R = 1.5, // Default Signal Risk To Reward Ratio ...
double _defaultSignalRiskInPoint = 50, // Default Signal Risk In Point ...
double _defaultSignalVolume = 0.01 // Default Signal Volume ...
)
{
//
// Assign Properties ...
name = _name;
symbol = _symbol;
period = _period;
//
ignoreTargets = false;
slAdditionDistance = 0;
maxAllowedRiskDistance = 0;
//
processAllTicks = _processAllTicks;
defaultSignalR2R = _defaultSignalR2R;
defaultSignalVolume = _defaultSignalVolume;
defaultSignalRiskInPoint = _defaultSignalRiskInPoint;
//
// Normalize ...
defaultSignalR2R = NormalizeDouble(defaultSignalR2R, 1, 10);
defaultSignalVolume = NormalizeDouble(defaultSignalVolume, 0.01);
defaultSignalVolume = NormalizeVolume(defaultSignalVolume, symbol, 2);
defaultSignalRiskInPoint = NormalizeDouble(defaultSignalRiskInPoint, 10);
//
// Set Dfault Values ...
mProcessedTicksCount = 0;
mLastCheckedBarTime = NULL;
//
patternDetector = new XCMarketPatternDetector();
}
//
// Deconstructor ...
~XCBaseSignaller()
{
//
// Cleanup Event Listeners ...
SpecifiedClean(onSignalEventListeners);
//
delete patternDetector;
ZeroMemory(patternDetector);
}
//
// Event Listeners ...
/**
* Add On Signal Event Listener ...
*
* @param listener: TOnSignal instance ...
*/
void AddOnSignalEventHandler(TOnSignal listener)
{
//
// Validate ...
if (listener == NULL)
{
return;
}
//
Add(
listener,
onSignalEventListeners //
);
}
//
// Actions ...
/**
* Check Signaller Validation ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
//
IsSpecifiedValid(name) &&
IsSpecifiedValid(symbol) &&
IsSpecifiedValid(period) &&
//
patternDetector != NULL &&
//
CheckAdditionslSignallerValidations()
//
;
//
return result;
}
/**
* Handling On Tick Event ...
*
* @param barIndex: int, Specified Bar Index ...
*/
void OnTick(int barIndex = 0)
{
//
// Normalize Bar Index ...
if (barIndex < 0)
{
barIndex = 0;
}
//
// Define Requirements ...
XOHCL iBar;
bool has = false;
bool isNewBar = false;
//
// Get Current Bar Time ...
datetime cBarTime = GetBarTime(
symbol,
period,
barIndex //
);
//
// Validate Bar Time ...
has = IsSpecifiedValid(cBarTime);
if (!has)
{
return;
}
//
// Check Rest Until ...
has = !IsXValid(restUntil) || (IsXValid(restUntil) && cBarTime > restUntil);
if (!has)
{
return;
}
//
// Check Process Permissions ...
has = CanAnalyseMarket(cBarTime);
if (!has)
{
return;
}
//
// Check if new Bar, Reset Processed Ticks Count ...
isNewBar = cBarTime > mLastCheckedBarTime;
if (isNewBar)
{
//
mProcessedTicksCount = 0;
ProcessNewBar(barIndex);
return;
}
//
// Check Allow Process ...
// Process All Ticks ...
// Process New Bars ...
has = processAllTicks ||
(!processAllTicks && isNewBar);
if (!has)
{
return;
}
//
// Set Last Works ...
mProcessedTicksCount++;
mLastCheckedBarTime = cBarTime;
//
ProcessTick(barIndex);
}
//
// Virtuals ...
/**
* Processing Tick ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessTick(int barIndex = 0)
{
}
/**
* Processing New Bar ...
*
* @param barIndex: int, Specified Bar Index ...
*/
virtual void ProcessNewBar(int barIndex = 0)
{
}
/**
* Check Guards Based on MarketConditions ...
*
* @param guards: XGuard, reference collection to holds result ...
* @param positions: XPosition, reference collection to provides positions ...
* @param barIndex: int
*
* @return ( int )
*/
int virtual CheckForGuard(
XGuard &guards[],
XPosition &positions[],
int barIndex = 0 //
)
{
//
int result = 0;
//
SpecifiedClean(guards);
//
result = ArraySize(guards);
//
return result;
}
/**
* Check Additional Validations on Childs Instances ...
*
* @return ( bool virtual )
*/
bool virtual CheckAdditionslSignallerValidations()
{
return true;
}
/**
* Normalizing Signal by Signaller Custom Props ...
*
* @param signal: XSignal ...
*/
void virtual NormalizeSignal(XSignal &signal)
{
}
/**
* Prepare Restrictions Update For Losing Trades ...
*/
void LoseTrade()
{
//
restingSignals++;
loosingTrades++;
}
/**
* Prepare Restrictions For Winning Trades ...
*/
void WinTrade()
{
//
if (loosingTrades > 0)
{
loosingTrades--;
}
//
if (restingSignals > 0)
{
restingSignals--;
}
}
//
// Protected ...
protected:
//
// Props ...
//
bool processAllTicks; // Specified Processing All Ticks or not ...
//
int mProcessedTicksCount; // Prcoessed Ticks Count ...
datetime mLastCheckedBarTime; // Last Checked Bar Time ...
//
double defaultSignalR2R; // Default Signal Risk To Reward Ratio ...
double defaultSignalVolume; // Default Signal Volume ...
double defaultSignalRiskInPoint; // Default Signal Risk In Point ...
//
// Event Notifiers ...
/**
* Notify OnSignal Event Listeners ...
*
* @param signal: XSignal, Specified Signal to Notify ...
*/
void NotifySignalEventListeners(XSignal &signal)
{
//
int count = ArraySize(onSignalEventListeners);
//
// Validate ...
if (!IsValidSize(count) || !signal.IsValid())
{
return;
}
//
// Check Restrictions ...
if (HasRestrictions())
{
//
bool ignore = HandleRestrictions(signal);
if (ignore)
{
return;
}
}
//
// Do Notify ...
for (int i = 0; i < count; i++)
{
onSignalEventListeners[i](signal);
}
//
lastSignalAt = signal.time;
}
/**
* Calling Can Analyse Event Listeners ...
* Check Can Analayse Market or not ...
*
* @param time: datetime, Specified Time for Checking ...
*
* @return ( bool )
*/
bool CanAnalyseMarket(datetime time = NULL)
{
//
bool result = false;
//
// Normalize ...
time = NormalizeTime(time);
//
// Validation ...
result = IsValid();
if (!result)
{
return result;
}
//
result = canAnalyseEventListener == NULL;
if (result)
{
return result;
}
//
// Calling Can Analyse Event Listener ...
result = canAnalyseEventListener(
symbol,
period,
time //
);
//
return result;
}
/**
* Preparing Default Signal ...
*
* @param signal: XSignal, holding result Signal ...
* @param forDir: ENUM_X_DIRECTION
* @param targets: XTarget Array, Provides Signal Targets (Price) ...
* @param r2r: double, Provides Signal (r2r), if not Provided uses Default R2R ...
* @param slPrice: double, Provides Signal SL Price, if not Provided uses riskInPoint ...
* @param riskInPoint: double, Provides Signal Risk Amount which Multiplied to Points, if not Provided uses DefaultRiskInPoint ...
*
* @return ( bool )
*/
bool PrepareSignal(
XSignal &signal,
ENUM_X_DIRECTION forDir,
XTarget &targets[], //
double r2r = 0,
double slPrice = 0,
double riskInPoint = 0 //
)
{
//
bool result = false;
//
// Prepare ...
signal.Clean();
//
// Normalize ...
//
// Validate ...
result = IsValid() &&
HasDirection(forDir);
if (!result)
{
return result;
}
//
bool isBullish = IsSpecifiedBullish(forDir);
//
double point = GetPoints(symbol);
double spread = GetSpread(symbol);
double volume = defaultSignalVolume;
double entry = GetEntry(symbol, forDir);
//
riskInPoint = riskInPoint > 0 && slPrice <= 0
? riskInPoint
: defaultSignalRiskInPoint;
double risk = (riskInPoint * point);
risk = slPrice > 0
? MathAbs(entry - slPrice)
: risk;
//
r2r = r2r > 0
? r2r
: defaultSignalR2R;
double reward = (risk * r2r) + spread;
//
double tp =
isBullish
? entry + reward
: entry - reward;
//
double sl =
isBullish
? entry - risk
: entry + risk;
//
// Filling Values ...
signal.tp = tp;
signal.sl = sl;
signal.entry = entry;
signal.provider = name;
signal.symbol = symbol;
signal.period = period;
signal.volume = volume;
signal.time = TimeCurrent();
signal.type =
isBullish
? POSITION_TYPE_BUY
: POSITION_TYPE_SELL;
signal.mode = X_ORDER_MODE_MARKET;
//
// Apply Targets ...
if (HasChild(targets))
{
//
ApplyTargetsOnSignal(
forDir,
targets,
signal //
);
}
//
// Validate Signal ...
result = signal.IsValid();
if (result)
{
//
NormalizeSignal(signal);
result = signal.IsValid();
}
//
if (!result)
{
signal.Clean();
}
//
return result;
}
/**
* Check Signaller Has Restrictions or not ...
*
* @return ( bool )
*/
bool HasRestrictions()
{
//
bool result = false;
//
result =
//
// Rest Delay ...
restingDelay > 0 ||
//
// Resting Signals ...
restingSignals > 0 ||
//
// Rest Until ...
IsXValid(restUntil)
//
;
//
return result;
}
/**
* Handle Restrictions On Signal ...
*
* @param signal: XSignal, reference to Provided Sginal ...
*
* @return ( bool )
*/
bool HandleRestrictions(XSignal &signal)
{
//
// Ignore Signal Execution ...
bool result = true;
//
// Check Restrictions Exists ...
if (!HasRestrictions())
{
//
// Disable Signal Ignoring and Allow Notify Signal ...
result = false;
return result;
}
//
datetime cTime = TimeCurrent();
//
// Resting Signals ...
if (restingSignals > 0)
{
//
restingSignals--;
return result;
}
//
// Rest Until ...
if (IsXValid(restUntil))
{
//
if (cTime > restUntil)
{
//
restUntil = NULL;
//
// Disable Signal Ignoring and Allow Notify Signal ...
result = false;
return result;
}
else
{
//
// Ignore Signal ...
return result;
}
}
//
// Resting Delay ...
if (restingDelay > 0 &&
IsXValid(lastSignalAt))
{
//
int lastSignalIDX = GetBarIndex(
signal.symbol,
signal.period,
lastSignalAt //
);
if (IsValidIndex(lastSignalIDX))
{
//
if (lastSignalIDX > restingDelay)
{
//
restingDelay = 0;
//
// Disable Signal Ignoring and Allow Notify Signal ...
result = false;
return result;
}
else
{
//
// Ignore Signal ...
return result;
}
}
}
//
return result;
}
/**
* Reset All Restrictions ...
*/
void ResetRestrictions()
{
//
restingDelay = 0;
restUntil = NULL;
restingSignals = 0;
}
//
// Private ...
private:
//
// Props ...
//
// Event Listeners ...
TOnSignal onSignalEventListeners[];
};
//
@@ -0,0 +1,711 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XCTarget
// Description: provides all Positions Target requirements ...
//
//
// 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 "../Classes/x-saherelm.x-trade.class.mq5"
//
// Implementation ...
class XCTarget : public XCBase
{
//
// Public ...
public:
//
XCTrade *trader;
XCAlert *alert;
XSignal signals[];
//
// Constructor ...
XCTarget(
XCTrade *_trader, //
XCAlert *_alert //
) : XCBase()
{
//
alert = _alert;
trader = _trader;
//
XClean(signals);
}
//
// Deconstructor ...
~XCTarget()
{
Destroy();
}
//
void Destroy()
{
//
XClean(signals);
}
//
// Actions ...
/**
* Manage Positions ...
*
* @param barIndex: int, Bar Index ...
*/
void Manage(int barIndex = 0)
{
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
// Extract In Profit Positions ...
XPosition positions[];
int count = GetInProfitPositions(positions);
bool has = IsValidIndex(count);
if (!has)
{
return;
}
//
XSignal iSignal;
XTarget iTarget;
int signalIDX = -1;
int targetIDX = -1;
XPosition iPosition;
//
// Loop through Positions ...
for (int i = 0; i < count; i++)
{
//
// Select Positions ...
iPosition = positions[i];
has = FindSignal(
signalIDX,
iPosition.ticket //
);
if (!has)
{
continue;
}
iSignal = signals[signalIDX];
//
// Selecting Target ...
targetIDX = iSignal.appliedTargetIDX;
if (iSignal.isTargetApplied)
{
targetIDX++;
}
//
// Validate Targets Size ...
has = HasChild(iSignal.targets) &&
targetIDX < ArraySize(iSignal.targets);
if (has)
{
//
// Select Target ...
iTarget = iSignal.targets[targetIDX];
//
// Check Can Apply Target and Apply it ...
has = HandleApplyTarget(iTarget, iPosition);
if (has)
{
//
// Update Target IDX ...
iSignal.appliedTargetIDX++;
}
}
//
// Update Signal ...
signals[signalIDX] = iSignal;
//
// Cleanup ...
iSignal.Clean();
iTarget.Clean();
iPosition.Clean();
}
//
// Cleanup Resources ...
iSignal.Clean();
iTarget.Clean();
iPosition.Clean();
}
/**
* Extract in Profit Positions ...
*
* @param positions: XPosition, reference collection to holds result ...
*
* @return ( int )
*/
int GetInProfitPositions(
XPosition &positions[] //
)
{
//
int result = 0;
//
// Prepare ...
XClean(positions);
//
// Validate ...
if (trader == NULL)
{
return result;
}
//
result = trader.GetInProfitPositions(
positions,
NULL, // All Symbols ...
NULL, // All Providers ...
NULL, // All Periods ...
NULL, // All Position Types ...
X_POSITION_SELECT_ALL, // Select Method ...
true, // Filter by Magic ...
true // Force Clean ...
);
if (IsValidSize(result))
{
//
XPosition iPos;
XPosition tmp[];
Copy(
positions,
tmp //
);
XClean(positions);
while (HasChild(tmp))
{
//
iPos = tmp[0];
ArrayRemove(
tmp,
0,
1 //
);
//
int idx = -1;
bool has = FindSignal(
idx,
iPos.ticket //
);
if (has)
{
//
AddRef(
iPos,
positions //
);
}
}
//
XClean(tmp);
iPos.Clean();
//
result = ArraySize(positions);
}
//
return result;
}
/**
* Add Executed Signal ...
*
* @param signal: XSignal, reference to Executed Signal ...
*/
void AddExecutedSignal(XSignal &signal)
{
//
// Validate ...
if (!signal.IsValid() || !signal.IsExecuted())
{
return;
}
//
AddRef(
signal,
signals //
);
}
//
// Trade Event Handlers ...
/**
* Handle Stop Loss Event Triggered ...
*
* @param deal: XDeal instance refrence, provides Triggered Deal info ...
*/
void HandleOnStopLossTriggered(const XDeal &deal)
{
RemoveSignal(deal.positionId);
}
/**
* Handle Take Profit Event Triggered ...
*
* @param deal: XDeal instance refrence, provides Triggered Deal info ...
*/
void HandleOnTakeProfitTriggered(const XDeal &deal)
{
RemoveSignal(deal.positionId);
}
/**
* Handle Position Force Closed Event ...
*
* @param ticket: ulong, triggered Positions ticket ...
* @param position: XPosition instance refrence, Triggered Position ...
* @param comment: string, Comment ...
*/
void HandleOnPositionForceClosed(
const ulong ticket,
const XPosition &position,
const string comment //
)
{
RemoveSignal(ticket);
}
//
// Event Handlers Registration ...
//
void AddOnStopLossEventHandler(TOnStopLoss handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mStopLossEventHandlers
//
);
}
//
void AddOnTakeProfitEventHandler(TOnTakeProfit handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mTakeProfitEventHandlers
//
);
}
//
void AddOnForceClosePositionEventHandler(TOnForceClose handler)
{
//
if (handler == NULL)
{
return;
}
//
Add(
handler,
mOnForceCloseEventHandlers
//
);
}
//
// Protected ...
protected:
//
/**
* Find Specified Signal ...
*
* @param index: int, reference to holds detected index ...
* @param signal: XSignal, reference to Specified Signal ...
*
* @return ( bool )
*/
bool FindSignal(
int &index,
XSignal &signal //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Validate ...
result = signal.IsValid() &&
HasChild(signals);
if (!result)
{
return result;
}
//
// Looping Through Signals ...
int count = ArraySize(signals);
for (int i = 0; i < count; i++)
{
//
result = signals[i]
.IsSameAs(signal);
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Find Specified Signal ...
*
* @param index: int, reference to holds detected index ...
* @param ticket: ulong, Specified Signal Position ID ...
*
* @return ( bool )
*/
bool FindSignal(
int &index,
ulong ticket //
)
{
//
bool result = false;
//
// Prepare ...
index = -1;
//
// Validate ...
result = NotEmptyZero(ticket) &&
HasChild(signals);
if (!result)
{
return result;
}
//
// Looping Through Signals ...
int count = ArraySize(signals);
for (int i = 0; i < count; i++)
{
//
result = signals[i].IsValid() &&
signals[i].IsExecuted() &&
signals[i].positionId == ticket;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
/**
* Remove Specified Signal ...
*
* @param ticket: ulong, Specified Ticket ...
*/
void RemoveSignal(ulong ticket)
{
//
bool has = NotEmptyZero(ticket) &&
HasChild(signals);
if (!has)
{
return;
}
//
int idx = -1;
has = FindSignal(
idx,
ticket //
);
if (!has)
{
return;
}
//
ArrayRemove(
signals,
idx,
1 //
);
}
/**
* Check Can Apply Specified Target on Specified Position or not ...
*
* @param target: XTarget, reference to Specified Target for Apply ...
* @param position: XPosition, reference to Specified Position ...
*
* @return ( bool )
*/
bool CanApplyTarget(
XTarget &target,
XPosition &position //
)
{
//
bool result = false;
//
// Validate ...
result =
target.IsValid() &&
position.IsValid();
if (!result)
{
return result;
}
//
// Check Price Reached Targets Value and Distance ...
double targetDistance = (target.actingDistance > 0 ? target.actingDistance : 0) * position.GetPointsValue();
result =
IsLong(position.type)
? position.price >= target.target + targetDistance
: position.price <= target.target - targetDistance;
//
return result;
}
/**
* Apply Specified Target on Specified Position ...
*
* @param target: XTarget, reference to Specified Target for Apply ...
* @param position: XPosition, reference to Specified Position ...
*
* @return ( bool )
*/
bool HandleApplyTarget(
XTarget &target,
XPosition &position //
)
{
//
bool result = false;
//
// Validate ...
result =
target.IsValid() &&
position.IsValid() &&
CanApplyTarget(
target,
position //
);
if (!result)
{
return result;
}
//
// Apply Target ...
string comment = NULL;
string message = NULL;
//
// Do Risk Free if Provided ...
if (result &&
target.doRF)
{
//
comment = "Taregt Manager do RF ...";
result = trader.Modify(
position.ticket,
target.target, // SL ...
position.tp, // TP ...
comment //
);
//
// Handle Alert ...
if (result)
{
//
message = "Target Manager do RF " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") on: " + ToXString(position.price);
alert.SendAlert(message);
}
}
//
// Do Risk Free on Entry if Provided ...
if (result &&
target.doRFOnEntry)
{
//
comment = "Target Manager do RF on Entry ...";
double actingDistance = position.GetPointsValue() * target.actingDistance;
bool isLong = IsLong(position.type);
double sl = position.entry + (isLong
? actingDistance
: (-1 * actingDistance) //
);
result = trader.Modify(
position.ticket,
sl, // SL ...
position.tp, // TP ...
comment //
);
//
// Handle Alert ...
if (result)
{
//
message = "Target Manager do RF " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") on Entry ...";
alert.SendAlert(message);
}
}
//
// Do Partial Close if Provided ...
if (result &&
target.volumeMultiplier > 0)
{
//
double volume = NormalizeVolume((position.volume * target.volumeMultiplier), position.symbol);
if (volume != position.volume)
{
//
comment = "Target Manager do Partial Close ...";
result = trader.ClosePartial(
position.ticket,
volume,
comment //
);
//
// Handle Alert ...
if (result)
{
//
message = "Target Manager do Partial Close " + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") by: " + ToXString(volume);
alert.SendAlert(message);
}
}
}
//
// Handle Replace TP ...
if (result &&
target.tpValue > 0)
{
//
// Validate TP Value ...
bool isLong = IsLong(position.type);
bool isValid = isLong
? target.tpValue > position.price &&
target.tpValue > position.tp
: target.tpValue < position.price &&
target.tpValue < position.tp;
if (isValid)
{
//
comment = "Target Manager Change TP ...";
result = trader.Modify(
position.ticket,
position.sl, // SL ...
target.tpValue, // TP ...
comment //
);
//
// Handle Alert ...
if (result)
{
//
message = "Target Manager Change TP of" + ToXString(position.type) + " Position (" + ToXString(position.ticket) + ") to: " + ToXString(target.tpValue) + " ...";
alert.SendAlert(message);
}
}
}
//
return result;
}
//
// Private ...
private:
//
//
// Required Event Handlers ...
TOnStopLoss mStopLossEventHandlers[];
TOnTakeProfit mTakeProfitEventHandlers[];
TOnForceClose mOnForceCloseEventHandlers[];
};
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,792 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// --------------------------------------
// Name: XCVolume
// Description: provides all Requirements for Volume Managing ...
//
//
// 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
//
// Template Variables of Inputs for Using ...
// input group "Volume";
// input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_STATIC; // Volume Applying Type
// input double eaStaticVoluem = X_MIN_VOLUME; // Static Volume
// input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
// input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
// input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
// input double eaConstantPercent = 0.0; // Constant Percent of Balance Per Trade
// input double eaConstantBalance = 0.0; // Constant Balance for Calculations
// XCVolume *eaVolume;
// eaVolume = new XCVolume();
// bool result = eaVolume.Init(
// eaVolumeSelect,
// eaStaticVoluem,
// eaDynamicVolumeStepBalance,
// eaDynamicVolumeStepVolume,
// eaConstantRiskBalance,
// eaConstantPercent,
// eaConstantBalance //
// );
// if (!result) {
// return INIT_FAILED;
// }
//
// Imports ...
#include "../Classes/x-saherelm.x-account.class.mq5"
#include "../Libraries/x-saherelm.x-trade.lib.mq5"
//
// Definitions ...
#define X_MIN_VOLUME 0.01
//
enum ENUM_X_VOLUME_SELECT_TYPE
{
X_VOLUME_NONE, // None
X_VOLUME_STATIC, // Static Volume
X_VOLUME_CURRENT, // Current Balance
X_VOLUME_EQUITY, // Current Equity
X_VOLUME_CONSTANT // Constant Value
};
//
bool IsValid(ENUM_X_VOLUME_SELECT_TYPE value)
{
//
bool result = false;
//
result = value != X_VOLUME_NONE;
//
return result;
}
//
string ToString(ENUM_X_VOLUME_SELECT_TYPE value)
{
//
string result = NULL;
//
result = EnumToString(value);
//
return result;
}
//
// Implementation ...
class XCVolume : public XCBase
{
//
// Public ...
public:
//
// Props ...
XCAccount *account;
//
// Constructor ...
XCVolume()
{
//
account = new XCAccount();
//
Default();
}
//
// Deconstructor ...
~XCVolume()
{
//
ZeroMemory(account);
}
//
bool Init(
ENUM_X_VOLUME_SELECT_TYPE _SelectType,
double _StaticVolume,
double _DynamicVolumeStepBalance,
double _DynamicVolumeStepVolume,
double _ConstantRiskBalance,
double _ConstantPercent,
double _ConstantBalance //
)
{
//
bool result = false;
//
mVolumeType = _SelectType;
mStaticVolume = _StaticVolume;
mConstantPercent = _ConstantPercent;
mConstantBalance = _ConstantBalance;
mConstantRiskBalance = _ConstantRiskBalance;
mDynamicVolumeStepVolume = _DynamicVolumeStepVolume;
mDynamicVolumeStepBalance = _DynamicVolumeStepBalance;
//
result =
//
CanUseStaticVolume() ||
CanUseDynamicVolume() ||
CanUseConstantRiskBalance() ||
CanUseConstantBalancePercent()
//
;
//
return result;
}
//
// Prperties ...
/**
* Get Volume Calculating Method ...
*
* @return (ENUM_X_VOLUME_SELECT_TYPE)
*/
ENUM_X_VOLUME_SELECT_TYPE VolumeType()
{
return mVolumeType;
}
/**
* Set Volume Calculating Method ...
*
* @param value: ENUM_X_VOLUME_SELECT_TYPE member ...
*/
void VolumeType(ENUM_X_VOLUME_SELECT_TYPE value)
{
mVolumeType = value;
}
/**
* Get Static Volume ...
*
* @return ( double )
*/
double StaticVolume()
{
return mStaticVolume;
}
/**
* Set Static Volume ...
*
* @param value: double
*/
void StaticVolume(double value)
{
//
value = NormalizeDouble(value, 0.01, 1);
//
mStaticVolume = value;
}
/**
* Get Dynamic Volume Step Balance ...
* used to Calculate Final Lottage ...
*
* @return ( double )
*/
double DynamicVolumeStepBalance()
{
return mDynamicVolumeStepBalance;
}
/**
* Set Dynamic Volume Step Balance ...
* used to Calculate Final Lottage ...
*
* @param value: Argument 1
*/
void DynamicVolumeStepBalance(double value)
{
//
value = NormalizeDouble(value, 0);
//
mDynamicVolumeStepBalance = value;
}
/**
* Get Dynamic Volume Step Volume ...
* used to Calculate Final Lottage ...
* how much increase Final Volume based oBalance Step ...
*
* @return ( double )
*/
double DynamicVolumeStepVolume()
{
return mDynamicVolumeStepVolume;
}
/**
* Get Dynamic Volume Step Volume ...
* used to Calculate Final Lottage ...
* how much increase Final Volume based oBalance Step ...
*
* @param value: double
*/
void DynamicVolumeStepVolume(double value)
{
//
value = NormalizeDouble(value, 0.01, 0.1);
//
mDynamicVolumeStepVolume = value;
}
/**
* Get Constant Balance Use for Dyamic Volume Calculation ...
*
* @return ( double )
*/
double ConstantBalance()
{
return mConstantBalance;
}
/**
* Set Constant Balance Use for Dyamic Volume Calculation ...
*
* @param value: Argument 1
*/
void ConstantBalance(double value)
{
//
value = NormalizeDouble(value, 0);
//
mConstantBalance = value;
}
/**
* Get Constant Risk Value Based on Account Currency ...
*
* @return ( double )
*/
double ConstantRiskBalance()
{
return mConstantRiskBalance;
}
/**
* Get Constant Risk Value Based on Account Currency ...
*
* @param value: double
*/
void ConstantRiskBalance(double value)
{
//
value = NormalizeDouble(value, 0);
//
mConstantRiskBalance = value;
}
/**
* Get Constant Percent Based On Selected Balance ...
*
* @return ( double )
*/
double ConstantPercent()
{
return mConstantPercent;
}
/**
* Set Constant Percent Based On Selected Balance ...
*
* @param value: double ...
*/
void ConstantPercent(double value)
{
//
value = NormalizeDouble(value, 0, 100);
//
mConstantPercent = value;
}
//
// Tools ...
/**
* Retrieve Balance based on Provided Volume Type ...
*
* @return ( double )
*/
double GetBalance()
{
//
double result = 0;
//
if (!IsValid(mVolumeType))
{
return result;
}
//
if (mConstantBalance > 0 &&
mVolumeType == X_VOLUME_CONSTANT)
{
result = mConstantBalance;
}
else if (mVolumeType == X_VOLUME_CURRENT)
{
result = account.GetBalance();
}
else if (mVolumeType == X_VOLUME_EQUITY)
{
result = account.GetEquity();
}
//
return result;
}
/**
* Retrieve Balance based on Provided Volume Type ...
*
* @return ( double )
*/
double GetBalance(ENUM_X_VOLUME_SELECT_TYPE type)
{
//
double result = 0;
//
if (!IsValid(type))
{
return result;
}
//
if (mConstantBalance > 0 &&
type == X_VOLUME_CONSTANT)
{
result = mConstantBalance;
}
else if (type == X_VOLUME_CURRENT)
{
result = account.GetBalance();
}
else if (type == X_VOLUME_EQUITY)
{
result = account.GetEquity();
}
//
return result;
}
/**
* Calculate Volume Based On Given Configuration ...
*
* @param symbol: string, Trading Symbol ...
* @param entry: double, Entry Price ...
* @param sl: double, Stop Loss Price ...
*
* @return ( double )
*/
double CalculateVolume(
string symbol,
double entry,
double sl //
)
{
//
double result = X_MIN_VOLUME;
//
bool has = false;
//
// Validate Args ...
has =
sl > 0 &&
entry > 0 &&
IsValid(symbol);
if (!has)
{
return result;
}
//
// Retrieve Balance Type ...
double balance = GetBalance();
double points = GetPoints(symbol);
double riskPrice = MathAbs(entry - sl);
double riskInPoints = riskPrice / points;
//
has = CanUseStaticVolume();
if (has)
{
result = mStaticVolume;
}
//
has = CanUseDynamicVolume();
if (has)
{
//
double multiplier = balance / mDynamicVolumeStepBalance;
if (multiplier < 0)
{
multiplier = 1;
}
//
result = multiplier * mDynamicVolumeStepVolume;
}
//
has = CanUseConstantRiskBalance();
if (has)
{
//
result = account.CalculateVolume(
symbol,
mConstantRiskBalance,
riskInPoints //
);
}
//
has = CanUseConstantBalancePercent();
if (has)
{
//
double riskAmountPerBalance = (mConstantPercent * balance) / 100;
//
result = account.CalculateVolume(
symbol,
riskAmountPerBalance,
riskInPoints //
);
}
//
if (result < X_MIN_VOLUME)
{
result = X_MIN_VOLUME;
}
//
// Normalize Volume ...
result = NormalizeVolume(result, symbol);
//
return result;
}
/**
* Calculate Volume Based On Given Configuration ...
*
* @param signal: XSignal instance reference, provided required Data ...
*
* @return ( double )
*/
double CalculateVolume(XSignal &signal)
{
//
double result = X_MIN_VOLUME;
//
if (!signal.IsValid())
{
return result;
}
//
result = CalculateVolume(
signal.symbol,
signal.entry,
signal.sl //
);
//
return result;
}
/**
* Calculate Specified Percent of Selected Balance for Volume ...
*
* @param percent: double, percent of Balance Risking ...
* @param symbol: string, Trading Symbol ...
* @param entry: double, Entry Price ...
* @param sl: double Stop Loss Price ...
*
* @return ( double )
*/
double CalculateVolume(
ENUM_X_VOLUME_SELECT_TYPE selectType,
double percent,
string symbol,
double entry,
double sl //
)
{
//
double result = X_MIN_VOLUME;
//
bool has = false;
//
// Validate Args ...
has =
sl > 0 &&
entry > 0 &&
percent > 0 &&
IsValid(symbol) &&
IsValid(selectType) &&
(selectType == X_VOLUME_EQUITY ||
selectType == X_VOLUME_CURRENT);
if (!has)
{
return result;
}
//
// Retrieve Balance Type ...
double points = GetPoints(symbol);
double riskPrice = MathAbs(entry - sl);
double balance = GetBalance(selectType);
double riskInPoints = riskPrice / points;
//
double riskAmountPerBalance = (percent * balance) / 100;
//
result = account.CalculateVolume(
symbol,
riskAmountPerBalance,
riskInPoints //
);
//
return result;
}
//
// Protected ...
protected:
//
// Tools ...
/**
* Set Default Props ...
*/
void Default()
{
//
VolumeType(X_VOLUME_STATIC);
StaticVolume(0.01);
//
ConstantBalance(0);
ConstantPercent(0);
ConstantRiskBalance(0);
//
DynamicVolumeStepBalance(0);
DynamicVolumeStepVolume(0.01);
}
/**
* Check Configuration is Valid For Static Volume ...
*
* @return ( bool )
*/
bool CanUseStaticVolume()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
// Static Volume ...
result =
//
mVolumeType == X_VOLUME_STATIC &&
mStaticVolume > 0 &&
//
mDynamicVolumeStepBalance == 0 &&
//
mConstantBalance == 0 &&
mConstantPercent == 0 &&
mConstantRiskBalance == 0
//
;
//
return result;
}
/**
* Check Configuration is Valid For Dynamic Volume ...
*
* @return ( bool )
*/
bool CanUseDynamicVolume()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
result =
//
(mVolumeType == X_VOLUME_CURRENT ||
mVolumeType == X_VOLUME_EQUITY ||
(mVolumeType == X_VOLUME_CONSTANT &&
mConstantBalance > 0)) &&
//
mDynamicVolumeStepBalance > 0 &&
mDynamicVolumeStepVolume > 0 &&
//
mStaticVolume == 0 &&
mConstantPercent == 0 &&
mConstantRiskBalance == 0
//
;
//
return result;
}
/**
* Check Configuration is Valid For Constant Risk Balance ...
*
* @return ( bool )
*/
bool CanUseConstantRiskBalance()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
result =
//
(mVolumeType == X_VOLUME_CURRENT ||
mVolumeType == X_VOLUME_EQUITY ||
(mVolumeType == X_VOLUME_CONSTANT &&
mConstantBalance > 0)) &&
//
mConstantRiskBalance > 0 &&
//
mStaticVolume == 0 &&
mConstantPercent == 0 &&
mDynamicVolumeStepBalance == 0
//
;
//
return result;
}
/**
* Check Configuration is Valid For Constant Risk Percent ...
*
* @return ( bool )
*/
bool CanUseConstantBalancePercent()
{
//
bool result = false;
//
result = IsValid(mVolumeType);
if (!result)
{
return result;
}
//
result =
//
(mVolumeType == X_VOLUME_CURRENT ||
mVolumeType == X_VOLUME_EQUITY ||
(mVolumeType == X_VOLUME_CONSTANT &&
mConstantBalance > 0)) &&
//
mConstantPercent > 0 &&
//
mStaticVolume == 0 &&
mConstantRiskBalance == 0 &&
mDynamicVolumeStepBalance == 0
//
;
//
return result;
}
//
// Private ...
private:
//
// Props ...
//
ENUM_X_VOLUME_SELECT_TYPE mVolumeType; // Balance Type ...
//
// Static Volume ...
double mStaticVolume; // Static Volume ...
//
double mDynamicVolumeStepBalance; // Step of Balance ...
double mDynamicVolumeStepVolume; // Step of Volume ...
//
double mConstantBalance; // Constant Balance ....
double mConstantRiskBalance; // Constant Risk Balance ...
double mConstantPercent; // Constant Percent of Balance ...
};
//
@@ -0,0 +1,344 @@
//+------------------------------------------------------------------+
//| TestRegresser.mq5 |
//| SaherElm IT Center |
//| https://www.saherelm.ir |
//+------------------------------------------------------------------+
#property copyright "SaherElm IT Center"
#property link "https://www.saherelm.ir"
#property version "1.00"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
#include <ChartObjects/ChartObjectsLines.mqh>
//
// Inputs ...
input int mLoopbackLength = 200;
input ENUM_X_PRICE mPriceType = X_PRICE_HIGH;
//
// Calculation ...
input group "Calculation";
input int zigzagDepth = 12; // Depth
input int zigzagDeviation = 5; // Deviation
input int zigzagBackStep = 3; // Back Step
//
// Variables ...
//
int mZigZagHandler = INVALID_HANDLE;
//
// double mSumX = 0;
// double mSumY = 0;
// double mSumXY = 0;
// double mSumX2 = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
double xData[];
double yData[];
int xDataCount = CollectData(
xData,
yData //
);
//
// Initialize ZigZag Handler ...
mZigZagHandler = iCustom(
_Symbol,
_Period,
"ZigZagColor",
zigzagDepth,
zigzagDeviation,
zigzagBackStep //
);
if (mZigZagHandler == INVALID_HANDLE)
{
Print("Error creating ZigZag handle");
return (INIT_FAILED);
}
// //
// for (int i = 0; i < mLoopbackLength; i++)
// {
// //
// double iY = yData[i];
// double iX = xData[i];
// //
// mSumX += iX;
// mSumY += iY;
// mSumXY += (iX * iY);
// mSumX2 += (iX * iX);
// }
// //
// for (int i = 0; i < mLoopbackLength; i++)
// {
// //
// double iY = GetAppliedPrice(
// _Symbol,
// _Period,
// i,
// mPriceType //
// );
// double iX = i + 1;
// //
// mSumX += iX;
// mSumY += iY;
// mSumXY += (iX * iY);
// mSumX2 += (iX * iX);
// }
//
// int n = mLoopbackLength;
// double slope = (n * mSumXY - mSumX * mSumY) / (n * mSumX2 - mSumX * mSumX);
// double intercept = (mSumY - slope * mSumX) / n;
// //
// double xData[];
// double yData[];
// int xDataCount = CollectData(
// xData,
// yData //
// );
double _cSlope;
double _cIntercept;
int calculatedCount = CalculateSlopeandIntercept(
_cSlope,
_cIntercept,
xData,
yData //
);
//
datetime time1 = iTime(_Symbol, _Period, mLoopbackLength);
datetime time2 = iTime(_Symbol, _Period, 0);
// //
// double price1 = (intercept + slope * mLoopbackLength);
// double price2 = (intercept + slope);
//
double cPrice1 = PredictValue(
_cSlope,
_cIntercept,
time1 //
);
double cPrice2 = PredictValue(
_cSlope,
_cIntercept,
time2 //
);
//
string name = "TrendLine";
string cName = "cTrendLine";
//
// CChartObjectTrend *iTrend = new CChartObjectTrend();
// bool isCreated = iTrend.Create(
// ChartID(),
// name,
// 0,
// time1,
// price1,
// time2,
// price2 //
// );
// if (isCreated)
// {
// //
// // Styling Trend Line ...
// }
//
CChartObjectTrend *iCTrend = new CChartObjectTrend();
bool isCreated = iCTrend.Create(
ChartID(),
cName,
0,
time1,
cPrice1,
time2,
cPrice2 //
);
if (isCreated)
{
//
// Styling Trend Line ...
}
//
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//
int CollectData(
double &xData[],
double &yData[],
int barIndex = 0 //
)
{
//
int result = false;
//
SpecifiedClean(xData);
SpecifiedClean(yData);
//
barIndex = NormalizeInt(barIndex, 0);
//
int start = barIndex;
int end = start + mLoopbackLength;
for (int i = start; i < end; i++)
{
//
double iY = GetAppliedPrice(
_Symbol,
_Period,
i //
);
//
datetime iTime = iTime(
_Symbol,
_Period,
i //
);
double iX = i + 1; // (double)TimeToSeconds(iTime);
//
Add(
iX,
xData //
);
//
Add(
iY,
yData //
);
}
//
result = ArraySize(xData);
//
return result;
}
//
int CalculateSlopeandIntercept(
double &_slope,
double &_intercept,
double &xData[],
double &yData[] //
)
{
//
int result = 0;
//
bool has = false;
//
_slope = 0;
_intercept = 0;
//
if (!HasChild(xData) ||
!HasChild(yData))
{
return result;
}
//
double sumX = 0;
double sumY = 0;
double sumXY = 0;
double sumX2 = 0;
//
double x = 0;
double y = 0;
int end = MathMin(ArraySize(xData), ArraySize(yData));
for (int i = 0; i < end; i++)
{
//
double x = xData[i];
double y = yData[i];
//
sumX += x;
sumY += y;
sumXY += x * y;
sumX2 += x * x;
}
//
int n = end;
_slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
_intercept = (sumY - _slope * sumX) / n;
//
result = n;
//
return result;
}
//
double PredictValue(
double &_slope,
double &_intercept,
datetime forTime //
)
{
//
double result = 0;
//
if (!IsSpecifiedValid(forTime))
{
return result;
}
//
double forX = iBarShift(
_Symbol,
_Period,
forTime //
); // (double)TimeToSeconds(forTime);
result = (_intercept + _slope * forX);
//
return result;
}
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,320 @@
// #region Signals ...
// #region POI ...
bool IsBullishPOILongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
// IMPORTANT: Use near Support/Resistance ...
bool result = poiDetector.IsBullishPOI(barIndex) &&
kiParser.IsSafeBullishEntry(barIndex) &&
IsTFBullishPattern(barIndex, lowerTF);
//
return result;
}
bool IsBearishPOIShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
// IMPORTANT: Use near Support/Resistance ...
bool result = poiDetector.IsBearishPOI(barIndex) &&
kiParser.IsSafeBearishEntry(barIndex) &&
IsTFBearishPattern(barIndex, lowerTF);
//
return result;
}
bool ExitBullishPOILong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishReversalPOI(barIndex) ||
poiDetector.IsBearishBreakoutPOI(barIndex) ||
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool ExitBearishPOIShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishReversalPOI(barIndex) ||
poiDetector.IsBullishBreakoutPOI(barIndex) ||
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
// #endregion
// #region Breakout ...
bool IsBreakoutLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result = false;
//
result =
kiParser.IsVolatilityHigh(barIndex) &&
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishBreakoutPOI(barIndex);
//
return result;
}
bool IsBreakoutShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result = false;
//
result =
kiParser.IsVolatilityHigh(barIndex) &&
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishBreakoutPOI(barIndex);
//
return result;
}
bool ExitBreakoutLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishReversalPOI(barIndex) ||
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool ExitBreakoutShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishReversalPOI(barIndex) ||
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
// #endregion
// #region Reversal ...
bool IsReversalLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
kiParser.IsRSIBullish(barIndex) &&
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishReversalPOI(barIndex);
//
return result;
}
bool IsReversalShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
kiParser.IsRSIBearish(barIndex) &&
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishReversalPOI(barIndex);
//
return result;
}
bool ExitReversalLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishBreakoutPOI(barIndex) ||
poiDetector.IsBearishContinuationPOI(barIndex);
//
return result;
}
bool ExitReversalShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishBreakoutPOI(barIndex) ||
poiDetector.IsBullishContinuationPOI(barIndex);
//
return result;
}
// #endregion
// #region Continuation ...
bool IsContinuationLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBullishPattern(barIndex, lowerTF) &&
kiParser.IsTrendStrongBullish(barIndex) &&
poiDetector.IsBullishContinuationPOI(barIndex);
//
return result;
}
bool IsContinuationShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBearishPattern(barIndex, lowerTF) &&
kiParser.IsTrendStrongBearish(barIndex) &&
poiDetector.IsBearishContinuationPOI(barIndex);
//
return result;
}
bool ExitContinuationLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishReversalPOI(barIndex) ||
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool ExitContinuationShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishReversalPOI(barIndex) ||
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
// #endregion
// #region Exhaustion ...
bool IsExhaustionLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishExhaustionPOI(barIndex);
//
return result;
}
bool IsExhaustionShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishExhaustionPOI(barIndex);
//
return result;
}
bool ExitExhaustionLong(int barIndex = 0)
{
return poiDetector.IsBearishBreakoutPOI(barIndex);
}
bool ExitExhaustionShort(int barIndex = 0)
{
return poiDetector.IsBullishBreakoutPOI(barIndex);
}
// #endregion
// #region Trend Exhaustion ...
bool IsTrendExhaustionLongEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBullishPattern(barIndex, lowerTF) &&
poiDetector.IsBearishTrendExhaustedPOI(barIndex);
//
return result;
}
bool IsTrendExhaustionShortEntry(
int barIndex = 0,
ENUM_TIMEFRAMES lowerTF = PERIOD_M5 //
)
{
//
bool result =
IsTFBearishPattern(barIndex, lowerTF) &&
poiDetector.IsBullishTrendExhaustedPOI(barIndex);
//
return result;
}
bool ExitTrendExhaustionLong(int barIndex = 0)
{
//
bool result =
poiDetector.IsBearishBreakoutPOI(barIndex) ||
poiDetector.IsBearishContinuationPOI(barIndex);
//
return result;
}
bool ExitTrendExhaustionShort(int barIndex = 0)
{
//
bool result =
poiDetector.IsBullishBreakoutPOI(barIndex) ||
poiDetector.IsBullishContinuationPOI(barIndex);
//
return result;
}
// #endregion
// #endregion
@@ -0,0 +1,825 @@
int CountKIFastTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKIFast(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKISlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKISlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKISuperSlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKISuperSlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKIUpperTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKIUpper(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountKILowerTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetKILower(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountMAFastTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetMAFast(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountMASlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetMASlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
int CountMASuperSlowTouches(
int barIndex = 0,
int loopback = 5,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
ENUM_X_BOUNDARY_PRICE priceType = X_BOUNDARY_PRICE_HIGH_LOW //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 1);
barIndex = NormalizeBarIndex(barIndex);
//
if (!IsValid())
{
return result;
}
//
XOHCL iBar;
bool has = false;
double iValue = 0;
double affectedValue = 0;
double iConfirnValue = 0;
bool isBullish = !HasDirection(forDir) || IsXBullish(forDir);
bool isBearish = !HasDirection(forDir) || IsXBearish(forDir);
ENUM_X_PRICE bullishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bullishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
ENUM_X_PRICE bearishTouchUpperPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_HIGH
: X_PRICE_UP;
ENUM_X_PRICE bearishTouchLowerPriceType = priceType == X_BOUNDARY_PRICE_HIGH_LOW
? X_PRICE_LOW
: X_PRICE_DOWN;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
has = iBar.Init(symbol, period, i);
if (!has)
{
continue;
}
//
affectedValue = helper.GetMASuperSlow(i);
//
// Bullish Touches ...
if (isBullish)
{
//
iValue = iBar.GetPrice(bullishTouchLowerPriceType);
iConfirnValue = iBar.GetPrice(bullishTouchUpperPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue <= affectedValue &&
iConfirnValue >= affectedValue;
if (has)
{
result++;
}
}
//
// Bearish Touches ...
if (isBearish)
{
//
iValue = iBar.GetPrice(bearishTouchUpperPriceType);
iConfirnValue = iBar.GetPrice(bearishTouchLowerPriceType);
has =
NotEmptyZero(iValue) &&
NotEmptyZero(affectedValue) &&
NotEmptyZero(iConfirnValue) &&
iValue >= affectedValue &&
iConfirnValue <= affectedValue;
if (has)
{
result++;
}
}
//
iBar.Clean();
}
//
iBar.Clean();
//
return result;
}
@@ -0,0 +1,458 @@
int CounteZoneTouches(
XBoxZone &zone,
double threshold = 10,
int loopback = 100 //
)
{
//
int result = 0;
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
threshold = NormalizeDouble(threshold, 10);
//
if (!zone.IsValid())
{
return result;
}
//
XOHCL tmpBar;
int start = zone.ToIndex();
bool isUpperTouched = false;
bool isLowerTouched = false;
double points = GetPoints(zone.symbol);
double distance = points * threshold;
int end = MathMin(start + loopback, zone.FromIndex());
for (int i = start; i < end; i++)
{
//
if (tmpBar.Init(zone.symbol, zone.period, i))
{
//
isUpperTouched = MathAbs(tmpBar.high - zone.upper) <= distance;
isLowerTouched = MathAbs(tmpBar.low - zone.lower) <= distance;
//
if (
(zone.IsBullish() &&
(isLowerTouched ||
MathAbs(tmpBar.close - zone.lower) <= distance)) ||
(zone.IsBearish() &&
(isUpperTouched ||
MathAbs(tmpBar.close - zone.upper) <= distance)))
{
//
result++;
Add(
tmpBar.time,
zone.tests //
);
}
//
tmpBar.Clean();
}
}
//
tmpBar.Clean();
//
return result;
}
bool HasNearZone(
int &index,
double price,
double threshold,
XBoxZone &zones[] //
)
{
//
bool result = false;
//
index = -1;
//
// Validate ...
result = HasChild(zones) &&
NotEmptyZero(price) &&
NotEmptyZero(threshold) &&
price > 0 &&
threshold > 0;
if (!result)
{
return result;
}
//
double points = GetPoints(zones[0].symbol);
double distance = points * threshold;
for (int i = 0; i < ArraySize(zones); i++)
{
//
// Check Price Distance by Upper ...
result = price >= zones[i].lower - distance &&
price <= zones[i].upper + distance;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
bool IsNearZone(
double price,
XBoxZone &zone,
double threshold = 0 //
)
{
//
bool result = false;
//
result =
zone.IsValid() &&
NotEmptyZero(price);
if (!result)
{
return result;
}
//
double points = GetPoints(zone.symbol);
double distance = points * threshold;
//
result = price >= zone.lower - distance &&
price <= zone.upper + distance;
//
return result;
}
/*
* Check Recently Pattern Zone is Touched or not ...
*
* @param zone: XBoxZone, Touched Zone ...
* @param patterns: ENUM_X_BAR_PATTERN, Allowed to Check Patterns ...
* @param patternsDir: ENUM_X_DIRECTION, Allowed Directions ...
* @param price: double, a Price to Check Toch or Reject ...
* @param barIndex: int, Bar Index to Start Checking ...
* @param loopback: int, Loopback for Pattern Formations ...
* @param threshold: double, threshold for Pattern touch ...
* @param forPeriod: ENUM_TIMEFRAMES, Time Frame to Check Patterns ...
* @param forDir: ENUM_X_DIRECTION, Directions for Pattern's Formation Check ...
*
* @return ( bool )
*/
bool HasRecentPatternTouched(
XBoxZone &zone,
ENUM_X_BAR_PATTERN &patterns[],
ENUM_X_DIRECTION &patternsDir[],
double price,
int barIndex = 0,
int loopback = 5,
double threshold = 5,
ENUM_TIMEFRAMES forPeriod = NULL,
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE //
)
{
//
bool result = false;
//
zone.Clean();
//
// Validate ...
result =
HasChild(patterns) &&
NotEmptyZero(price) &&
HasChild(patternsDir) &&
ArraySize(patterns) == ArraySize(patternsDir);
if (!result)
{
return result;
}
//
// Normalize ...
loopback = NormalizeInt(loopback, 2);
barIndex = kiParser.NormalizeBarIndex(barIndex);
if (IsXValid(forPeriod))
{
forPeriod = period;
}
//
XOHCL iBar;
bool has = false;
int iBullishIDX = -1;
int iBearishIDX = -1;
bool isBullish = false;
bool isBearish = false;
XBoxZone iBullishZones[];
XBoxZone iBearishZones[];
XPatternAnalysis iAnalysis;
XPatternAnalysisConfig iConfig;
//
// Preparing Pattern Analysis Config ...
iConfig.Default();
//
Copy(
patterns,
iConfig.allowedPatterns //
);
Copy(
patternsDir,
iConfig.allowedDirs //
);
//
// XAUUSD ...
iConfig.AddPattern(X_BAR_PATTERN_FVG);
iConfig.AddPattern(X_BAR_PATTERN_PIERCING);
//
// Looping Back ...
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
// Initialize Bar ...
has = iBar.Init(symbol, forPeriod, i);
if (!has)
{
continue;
}
//
// Analyse Patterns ...
has = AnalyseBarPatterns(iBar, iAnalysis, iConfig);
if (!has)
{
//
iBar.Clean();
continue;
}
//
// Bullish ...
has = iAnalysis.Count(X_DIRECTION_BULLISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBullishZones, X_DIRECTION_BULLISH);
has = HasChild(iBullishZones);
if (has)
{
//
has = HasNearZone(
iBullishIDX,
price,
threshold,
iBullishZones //
);
if (has)
{
isBullish = true;
}
}
}
//
// Bearish ...
has = iAnalysis.Count(X_DIRECTION_BEARISH) > 0;
if (has)
{
//
iAnalysis.GetPatterns(iBearishZones, X_DIRECTION_BEARISH);
has = HasChild(iBearishZones);
if (has)
{
//
has = HasNearZone(
iBearishIDX,
price,
threshold,
iBearishZones //
);
if (has)
{
isBearish = true;
}
}
}
//
// Summarizing Result ...
has =
HasDirection(forDir)
? (isBullish && !isBearish && IsXBullish(forDir)) ||
(isBearish && !isBullish && IsXBearish(forDir))
: (isBullish && !isBearish) || (isBearish && !isBullish);
if (has)
{
//
// Fill Zones ...
if (isBullish)
{
zone = iBullishZones[iBullishIDX];
}
else
{
zone = iBearishZones[iBearishIDX];
}
break;
}
//
// Cleanup Resource ...
iBar.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
}
//
// Cleanup Resources ...
iBar.Clean();
iConfig.Clean();
iAnalysis.Clean();
XClean(iBullishZones);
XClean(iBearishZones);
//
return result;
}
void ValidateZones(
XBoxZone &zones[],
int barIndex = 0,
int minimumRetests = 2,
double retestThreshold = 10,
int retestLoopback = 100,
ENUM_X_BOUNDARY_PRICE forPriceType = X_BOUNDARY_PRICE_UP_DOWN //
)
{
//
bool has = false;
//
// Validation ...
has = HasChild(zones) &&
IsXValid(forPriceType);
if (!has)
{
return;
}
//
// Normalizetion ...
barIndex = kiParser.NormalizeBarIndex(barIndex);
minimumRetests = NormalizeInt(minimumRetests, 0);
retestLoopback = NormalizeInt(retestLoopback, 50);
retestThreshold = NormalizeDouble(retestThreshold, 5, 10);
//
XOHCL tmpBar;
XBoxZone tmp;
XBoxZone tmps[];
double tmpValue = 0;
for (int i = 0; i < ArraySize(zones); i++)
{
//
tmp = zones[i];
//
if (minimumRetests > 0)
{
//
int retests = CounteZoneTouches(tmp, retestThreshold, retestLoopback);
if (retests < minimumRetests)
{
continue;
}
}
//
// Validate Zone ...
has = false;
for (int j = barIndex; j < tmp.FromIndex(); j++)
{
//
// Initial Bar ...
if (tmpBar.Init(tmp.symbol, tmp.period, j))
{
//
tmpValue = forPriceType == X_BOUNDARY_PRICE_UP_DOWN
? tmp.IsBullish()
? tmpBar.GetDown()
: tmpBar.GetUp()
: forPriceType == X_BOUNDARY_PRICE_HIGH_LOW
? tmp.IsBullish()
? tmpBar.low
: tmpBar.high
: EMPTY_VALUE;
if (NotEmptyZero(tmpValue))
{
//
// Check Break ...
has = tmp.IsBullish()
? tmpValue < tmp.lower
: tmpValue > tmp.upper;
//
// If Breakes ...
if (has)
{
break;
}
}
//
tmpBar.Clean();
}
}
//
// Not Breaked ...
if (!has)
{
//
AddIfNotExists(
tmp,
tmps //
);
}
//
tmp.Clean();
}
//
// Update Zones ...
XClean(zones);
Copy(
tmps,
zones //
);
XClean(tmps);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,33 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Expert Advisor
// -------------------------------------------------
// Name: X121XKIEA
// Description: Base Expert Advisor as Template ...
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property icon "../Images/SaherElm_Logo_Color.ico"
#property description "SaherElm XFIMA Expert Advisor"
#property strict
//
#define ShortName "X121XKIEA"
//
// Importts ...
#include "../X121XKIEA/Classes/x-saherelm.x121xki.expert.class.mq5"
//
// Inputs ...
//#region Inputs ...
//#endregion
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,843 @@
//
// Order Flow ...
//
bool drawOrderFlow;
XBoxZone orderFlow[];
bool manageOrderFlow;
ENUM_X_DIRECTION orderFlowDir;
//
bool HasOrderFlow()
{
//
return HasChild(orderFlow) &&
HasDirection(orderFlowDir);
}
//
bool HasBullishOrderFlow()
{
return HasOrderFlow() &&
IsXBullish(orderFlowDir);
}
//
bool HasBearishOrderFlow()
{
return HasOrderFlow() &&
IsXBearish(orderFlowDir);
}
//
bool GetOrderFlowBoundary(
double &upper,
double &lower //
)
{
//
bool result = false;
//
// Prepare ...
upper = EMPTY_VALUE;
lower = EMPTY_VALUE;
//
// Validate ...
result = HasOrderFlow();
if (!result)
{
return result;
}
//
int idx = -1;
//
// Upper ...
idx = GetHighest(orderFlow);
if (IsValidIndex(idx))
{
upper = orderFlow[idx].upper;
}
//
// Lower ...
idx = GetLowest(orderFlow);
if (IsValidIndex(idx))
{
lower = orderFlow[idx].lower;
}
//
result = NotEmptyZero(upper) &&
NotEmptyZero(lower) &&
upper > lower;
//
// Cleanup ...
if (!result)
{
//
upper = EMPTY_VALUE;
lower = EMPTY_VALUE;
}
//
return result;
}
//
bool ValidateOrderFlow(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasOrderFlow();
if (!result)
{
return result;
}
//
double upper = EMPTY_VALUE;
double lower = EMPTY_VALUE;
result = GetOrderFlowBoundary(upper, lower);
result = result &&
HasBullishOrderFlow()
? bar.low > lower
: bar.high < upper;
//
return result;
}
//
void DrawOrderFlow()
{
//
if (!drawOrderFlow || !HasOrderFlow())
{
return;
}
//
poiDrawer.DrawZones(orderFlow, structureDrawConfig.drawConfig);
}
//
void ManageOrderFlow(XOHCL &bar)
{
//
// Validate Exists ...
if (HasOrderFlow())
{
//
if (!ValidateOrderFlow(bar))
{
//
// Invalidate OrderFlow ...
XClean(orderFlow);
orderFlowDir = X_DIRECTION_NONE;
}
}
//
// Detect New ...
if (!HasOrderFlow())
{
//
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
// patternConfig.Default();
// patternConfig.supportAndResistanceLoopbackLength = 21;
// patternConfig.supportAndResistanceValidationLength = 7;
//
poiDetector.HasOrderFlow(
bar,
orderFlowDir,
orderFlow,
structureConfig.orderFlowValidation,
structureConfig.orderFlowUseOB,
structureConfig.orderFlowUseFVG,
structureConfig.orderFlowUseSupportAndResistance,
patternConfig.supportAndResistanceLoopbackLength,
patternConfig.supportAndResistanceValidationLength,
structureConfig.loopback //
);
}
//
// Update Exists ...
if (HasOrderFlow())
{
//
// Update to Times ...
UpdateToTime(orderFlow, TimeCurrent());
//
DrawOrderFlow();
}
}
//
// Zone ...
//
XBoxZone support;
XBoxZone resistance;
bool drawZones;
bool drawSupport;
bool manageZones;
bool drawResistance;
//
bool HasZones()
{
return HasSupport() ||
HasResistance();
}
//
bool HasSupport()
{
return support.IsValid();
}
//
bool HasResistance()
{
return resistance.IsValid();
}
//
bool ValidateZones(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasZones();
if (!result)
{
return result;
}
//
// Support ...
bool hasSupport = HasSupport();
if (hasSupport)
{
//
result = bar.close > support.lower &&
!IsBreaked(support, X_PRICE_CLOSE);
if (!result)
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
//
support.breakAt = bar.time;
support.Clean();
}
}
//
// Resistance ...
bool hasResistance = HasResistance();
if (hasResistance)
{
//
result = bar.close < resistance.upper &&
!IsBreaked(resistance, X_PRICE_CLOSE);
if (!result)
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
//
resistance.breakAt = bar.time;
resistance.Clean();
}
}
//
result =
(hasSupport && !HasSupport()) ||
(hasResistance && !HasResistance());
//
return result;
}
//
void DrawZones()
{
//
if (!drawZones || !HasZones())
{
return;
}
//
if (drawSupport && HasSupport())
{
poiDrawer.DrawZone(support, structureDrawConfig.drawConfig);
}
//
if (drawResistance && HasResistance())
{
poiDrawer.DrawZone(resistance, structureDrawConfig.drawConfig);
}
}
//
void ManageZones(XOHCL &bar)
{
//
// Validate Exists ...
if (HasZones())
{
//
if (!ValidateZones(bar))
{
//
// Invalidate Zones ...
//
// Support ...
if (IsXValid(support.breakAt))
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
//
support.Clean();
}
//
// Resistance ...
if (IsXValid(resistance.breakAt))
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
//
resistance.Clean();
}
}
}
//
// Detect New ...
XOHCL tmpBar;
bool has = false;
//
// Detect Support ...
if (!HasSupport())
{
//
has = poiDetector.HasSupport(
bar,
tmpBar,
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
);
if (has)
{
//
has = ToSupportBox(tmpBar, support, bar.time);
has =
has &&
!IsBreaked(support, X_PRICE_CLOSE);
if (!has)
{
//
if (support.IsValid())
{
//
iResistance = support;
iResistance.breakAt = NULL;
iResistance.dir = X_DIRECTION_BEARISH;
iResistance.to = bar.time + (PeriodSeconds(bar.period));
iResistance.from = bar.time - (PeriodSeconds(bar.period));
}
//
support.Clean();
}
}
}
//
// Detect Resistance ...
if (!HasResistance())
{
//
has = poiDetector.HasResistance(
bar,
tmpBar,
structureConfig.barsAnalysisConfig.supportAndResistanceValidationLength,
structureConfig.barsAnalysisConfig.supportAndResistanceLoopbackLength //
);
if (has)
{
//
has = ToResistanceBox(tmpBar, resistance, bar.time);
has =
has &&
!IsBreaked(resistance, X_PRICE_CLOSE);
if (!has)
{
//
if (resistance.IsValid())
{
//
iSupport = resistance;
iSupport.breakAt = NULL;
iSupport.dir = X_DIRECTION_BULLISH;
iSupport.to = bar.time + (PeriodSeconds(bar.period));
iSupport.from = bar.time - (PeriodSeconds(bar.period));
}
//
resistance.Clean();
}
}
}
//
// Update Exists ...
if (HasZones())
{
//
if (HasSupport())
{
//
support.to = bar.time;
support.type = "XFIMASup";
}
//
if (HasResistance())
{
//
resistance.to = bar.time;
resistance.type = "XFIMARes";
}
//
DrawZones();
}
//
// Cleanup ...
tmpBar.Clean();
}
//
XBoxZone iSupport;
XBoxZone iResistance;
bool drawIZones;
bool drawISupport;
bool manageIZones;
bool drawIResistance;
//
bool HasIZones()
{
//
return HasISupport() ||
HasIResistance();
}
//
bool HasISupport()
{
return iSupport.IsValid();
}
//
bool HasIResistance()
{
return iResistance.IsValid();
}
//
void DrawIZones()
{
//
if (!drawIZones || !HasIZones())
{
return;
}
//
if (drawISupport && HasISupport())
{
poiDrawer.DrawZone(iSupport, structureDrawConfig.drawConfig);
}
//
if (drawIResistance && HasIResistance())
{
poiDrawer.DrawZone(iResistance, structureDrawConfig.drawConfig);
}
}
//
bool ValidateIZones(XOHCL &bar)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasIZones();
if (!result)
{
return result;
}
//
//
// Support ...
bool hasSupport = HasISupport();
if (hasSupport)
{
//
result = bar.close > iSupport.lower &&
!IsBreaked(iSupport, X_PRICE_CLOSE);
if (!result)
{
//
iSupport.breakAt = bar.time;
iSupport.Clean();
}
}
//
// Resistance ...
bool hasResistance = HasIResistance();
if (hasResistance)
{
//
result = bar.close < iResistance.upper &&
!IsBreaked(iResistance, X_PRICE_CLOSE);
if (!result)
{
//
iResistance.breakAt = bar.time;
iResistance.Clean();
}
}
//
result =
(hasSupport && !HasISupport()) ||
(hasResistance && !HasIResistance());
//
return result;
}
//
void ManageIZones(XOHCL &bar)
{
//
// Validate Exists ...
if (HasIZones())
{
//
if (!ValidateIZones(bar))
{
//
// Invalidate Zones ...
//
// Support ...
if (IsXValid(iSupport.breakAt))
{
iSupport.Clean();
}
//
// Resistance ...
if (IsXValid(iResistance.breakAt))
{
iResistance.Clean();
}
}
}
//
// Update Exists ...
if (HasIZones())
{
//
if (HasISupport())
{
//
iSupport.to = bar.time;
iSupport.type = "XFIMAISup";
}
//
if (HasIResistance())
{
//
iResistance.to = bar.time;
iResistance.type = "XFIMAIRes";
}
//
DrawIZones();
}
}
//
// Trends ...
//
XTrend scTrend;
XTrend mcTrend;
XTrend lcTrend;
XTrend hcTrend;
//
bool drawTrends;
bool drawSCTrend;
bool drawMCTrend;
bool drawLCTrend;
bool drawHCTrend;
bool manageTrends;
//
bool HasTrend()
{
//
bool result =
HasSCTrend() ||
HasMCTrend() ||
HasLCTrend() ||
HasHCTrend();
//
return result;
}
//
bool HasSCTrend()
{
return scTrend.IsValid() &&
scTrend.HasTrend();
}
//
bool HasMCTrend()
{
return mcTrend.IsValid() &&
mcTrend.HasTrend();
}
//
bool HasLCTrend()
{
return lcTrend.IsValid() &&
lcTrend.HasTrend();
}
//
bool HasHCTrend()
{
return hcTrend.IsValid() &&
hcTrend.HasTrend();
}
//
void DrawTrends()
{
//
if (!drawTrends || !HasTrend())
{
return;
}
//
// SC ...
if (drawSCTrend && HasSCTrend())
{
poiDrawer.DrawTrendLine(scTrend, structureDrawConfig.drawConfig);
}
//
// MC ...
if (drawMCTrend && HasMCTrend())
{
poiDrawer.DrawTrendLine(mcTrend, structureDrawConfig.drawConfig);
}
//
// LC ...
if (drawLCTrend && HasLCTrend())
{
poiDrawer.DrawTrendLine(lcTrend, structureDrawConfig.drawConfig);
}
//
// HC ...
if (drawHCTrend && HasHCTrend())
{
poiDrawer.DrawTrendLine(hcTrend, structureDrawConfig.drawConfig);
}
}
//
void ManageTrends(XOHCL &bar)
{
//
// Validate ...
bool has = bar.IsValid();
if (!has)
{
return;
}
//
XTrend tmpTrend;
//
// SC ...
tmpTrend.Clean();
has = fimaParser.HasSCTrend(tmpTrend, bar.Index());
if (has)
{
scTrend = tmpTrend;
}
//
// MC ...
tmpTrend.Clean();
has = fimaParser.HasMCTrend(tmpTrend, bar.Index());
if (has)
{
mcTrend = tmpTrend;
}
//
// LC ...
tmpTrend.Clean();
has = fimaParser.HasLCTrend(tmpTrend, bar.Index());
if (has)
{
lcTrend = tmpTrend;
}
//
// HC ...
tmpTrend.Clean();
has = fimaParser.HasHCTrend(tmpTrend, bar.Index());
if (has)
{
hcTrend = tmpTrend;
}
//
DrawTrends();
//
// Cleanup ...
tmpTrend.Clean();
}
//
void Manage(XOHCL &bar)
{
//
bool has = bar.IsValid();
if (!has)
{
return;
}
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
has = bar.GetPreviousBar(pBar);
has = has &&
pBar.GetPreviousBar(p2Bar);
has = has &&
p2Bar.GetPreviousBar(p3Bar);
if (!has)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
}
//
ManageTrends(bar);
ManageZones(p2Bar);
ManageIZones(p2Bar);
ManageOrderFlow(p3Bar);
//
// Cleanup ...
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
}
//
// Configure ...
drawZones = false;
drawIZones = false;
drawTrends = false;
drawSCTrend = false;
drawMCTrend = false;
drawLCTrend = false;
drawHCTrend = false;
drawSupport = false;
drawISupport = false;
drawOrderFlow = false;
drawResistance = false;
drawIResistance = false;
//
manageZones = true;
manageIZones = true;
manageTrends = false;
manageOrderFlow = true;
//
// Manage ...
Manage(iBar);
@@ -0,0 +1,496 @@
/**
* Check Bar Has Signal Based on Strategy 3 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool Strategy1HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validator Flags ...
bool validateByZones = true;
bool validateByPinBar = true;
bool validateByBarPatterns = true;
bool validateByCyclesTrend = true;
bool validateByMaFastSlowGrows = true;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
XPatternAnalysis pBarPatterns;
XPatternAnalysis p2BarPatterns;
XPatternAnalysis p3BarPatterns;
XPatternAnalysisConfig iPatternsConfig;
//
// Reading Bars ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Reading Bar Patterns ...
iPatternsConfig.Default();
iPatternsConfig.FullPattern();
result =
result &&
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
iPatternsConfig //
);
result =
result &&
poiDetector.AnalyseBarPatterns(
p2Bar,
p2BarPatterns,
iPatternsConfig //
);
result =
result &&
poiDetector.AnalyseBarPatterns(
p3Bar,
p3BarPatterns,
iPatternsConfig //
);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
p2BarPatterns.Clean();
p3BarPatterns.Clean();
iPatternsConfig.Clean();
//
return result;
}
//
// Detect a Cross of MAs ...
bool isFastCrossedOverSlow = fimaParser.IsMAFastCrossedOverSlow(p2Bar.Index());
bool isFastCrossedUnderSlow = fimaParser.IsMAFastCrossedUnderSlow(p2Bar.Index());
//
isBullish = isFastCrossedOverSlow;
isBearish = isFastCrossedUnderSlow;
//
result = isBullish || isBearish;
//
// Validate Cross By Over/Under Last ...
if (result && validateByMaFastSlowGrows)
{
//
// Bullish ...
bool isFastOverLast = fimaParser.IsMAFastOverLast(pBar.Index());
bool isSlowOverLast = fimaParser.IsMASlowOverLast(pBar.Index());
bool isOverLast = isFastOverLast && isSlowOverLast;
//
// Bearish ...
bool isFastUnderLast = fimaParser.IsMAFastUnderLast(pBar.Index());
bool isSlowUnderLast = fimaParser.IsMASlowUnderLast(pBar.Index());
bool isUnderLast = isFastUnderLast && isSlowUnderLast;
//
isBullish =
isBullish &&
isOverLast;
//
isBearish =
isBearish &&
isUnderLast;
//
result = isBullish || isBearish;
}
//
// Validate By Cycles Trend ...
if (result && validateByCyclesTrend)
{
//
// Reading Cycles Trend ...
//
// Bullish ...
//
bool isLCMABullish = fimaParser.IsLCMABullish(pBar.Index());
bool isHCMABullish = fimaParser.IsHCMABullish(pBar.Index());
//
bool isLCMAOverLast = fimaParser.IsLCMAOverLast(pBar.Index());
bool isHCMAOverLast = fimaParser.IsHCMAOverLast(pBar.Index());
//
bool isCyclesMABullish = isLCMABullish && isHCMABullish && isLCMAOverLast && isHCMAOverLast;
//
// Bearish ...
//
bool isLCMABearish = fimaParser.IsLCMABearish(pBar.Index());
bool isHCMABearish = fimaParser.IsHCMABearish(pBar.Index());
//
bool isLCMAUnderLast = fimaParser.IsLCMAUnderLast(pBar.Index());
bool isHCMAUnderLast = fimaParser.IsHCMAUnderLast(pBar.Index());
//
bool isCyclesMABearish = isLCMABearish && isHCMABearish && isLCMAUnderLast && isHCMAUnderLast;
//
isBullish =
isBullish &&
isCyclesMABullish;
//
isBearish =
isBearish &&
isCyclesMABearish;
//
result = isBullish || isBearish;
}
//
// Validate Has a PinBar ...
if (result && validateByPinBar)
{
//
bool isPBarIsPinBar = poiDetector.IsPinnedBar(pBar, dir);
bool isPBarIsPinBarBullish = isPBarIsPinBar && IsXBullish(dir);
bool isPBarIsPinBarBearish = isPBarIsPinBar && IsXBearish(dir);
//
bool isP2BarIsPinBar = poiDetector.IsPinnedBar(p2Bar, dir);
bool isP2BarIsPinBarBullish = isP2BarIsPinBar && IsXBullish(dir);
bool isP2BarIsPinBarBearish = isP2BarIsPinBar && IsXBearish(dir);
//
bool isBullishPin = isPBarIsPinBarBullish || isP2BarIsPinBarBullish;
bool isBearishPin = isPBarIsPinBarBearish || isP2BarIsPinBarBearish;
//
isBullish =
isBullish &&
isBullishPin;
//
isBearish =
isBearish &&
isBearishPin;
//
result = isBullish || isBearish;
}
//
// Validate By Bar Patterns ...
if (result && validateByBarPatterns)
{
//
int count = 0;
int bullishCount = 0;
int bearishCount = 0;
//
count = pBarPatterns.Count(X_DIRECTION_BULLISH);
bullishCount += count;
//
count = p2BarPatterns.Count(X_DIRECTION_BULLISH);
bullishCount += count;
//
count = pBarPatterns.Count(X_DIRECTION_BEARISH);
bearishCount += count;
//
count = p2BarPatterns.Count(X_DIRECTION_BEARISH);
bearishCount += count;
//
bool hasBullishScore = IsValidSize(bullishCount) &&
bullishCount > bearishCount;
//
bool hasBearishScore = IsValidSize(bearishCount) &&
bearishCount > bullishCount;
//
// Reading Bar Patterns ...
//
// Bullish ...
bool isPBarHasBullishPatterns =
(pBarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BULLISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BULLISH));
bool isP2BarHasBullishPatterns =
(p2BarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BULLISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BULLISH));
bool hasBullishPatterns = isPBarHasBullishPatterns || isP2BarHasBullishPatterns;
//
// Bearish ...
bool isPBarHasBearishPatterns =
(pBarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BEARISH) ||
pBarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BEARISH));
bool isP2BarHasBearishPatterns =
(p2BarPatterns.HasPattern(X_BAR_PATTERN_FLAG, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_STAR, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PINNED, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_RISING, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_ENGULFED, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_MOMENTUM, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_PIERCING, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_SIGNALKEY, X_DIRECTION_BEARISH) ||
p2BarPatterns.HasPattern(X_BAR_PATTERN_TRUE_GAPED, X_DIRECTION_BEARISH));
bool hasBearishPatterns = isPBarHasBearishPatterns || isP2BarHasBearishPatterns;
//
isBullish =
isBullish &&
hasBullishScore &&
hasBullishPatterns;
//
isBearish =
isBearish &&
hasBearishScore &&
hasBearishPatterns;
//
result = isBullish || isBearish;
}
//
// Validate By Zones ...
if (result && validateByZones)
{
//
XBoxZone zones[];
int count = poiDetector.DetectZones(
pBar,
zones,
true, // Validate Zones ...
false, // OB ...
true, // FVG ...
true, // Supports ...
true, // Resistances ...
X_DIRECTION_NONE, // All Directions ...
X_SORT_BY_DATE, // Sort By ...
X_DIRECTION_BEARISH, // Sort Direction ...
5, // Zones Loopback ...
5, // Zones Validation ...
100 // Loopback ...
);
//
bool has = IsValidSize(count);
if (has)
{
poiDrawer.DrawZones(zones, structureDrawConfig.drawConfig);
}
}
//
if (result)
{
//
DebugBreak();
//
result = false;
isBullish = false;
isBearish = false;
}
//
// Detecting Direction ...
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
// Since Zone Prepared in Above Steps ...
// here we only Validate it ...
result = zone.IsValid();
}
//
// Draws ...
if (result)
{
//
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
XPatternAnalysisDrawConfig iPatternsConfig = structureDrawConfig.barAnalysisDrawConfig;
iConfig.trendRayLeft = false;
iConfig.trendRayRight = false;
//
// Draw Zone ...
if (zone.IsValid())
{
//
iConfig.zonesStyle = STYLE_DASHDOT;
iConfig.bullishColor = clrYellow;
iConfig.bearishColor = clrDarkOrange;
//
poiDrawer.DrawZone(zone, iConfig);
}
//
// poiDrawer.DrawZone(mcPVZone, iConfig);
// poiDrawer.DrawZone(lcPVZone, iConfig);
// poiDrawer.DrawZone(hcPVZone, iConfig);
//
// poiDrawer.DrawZone(pinBarZone, iConfig);
// poiDrawer.DrawZone(pullbackZone, iConfig);
// poiDrawer.DrawTrendLine(pinBarZoneTrend, iConfig);
//
poiDrawer.DrawPatternAnalysis(pBarPatterns, iPatternsConfig);
poiDrawer.DrawPatternAnalysis(p2BarPatterns, iPatternsConfig);
poiDrawer.DrawPatternAnalysis(p3BarPatterns, iPatternsConfig);
//
// if (hasATRBox)
// {
// poiDrawer.DrawZone(atrBox, iConfig);
// }
//
// if (hasDoublePatterns)
// {
// //
// poiDrawer.DrawPatternAnalysis(iPatterns, iPatternsConfig);
// poiDrawer.DrawPatternAnalysis(iPPatterns, iPatternsConfig);
// }
//
iConfig.Clean();
iPatternsConfig.Clean();
//
DebugBreak();
// //
// result = false;
// isBullish = false;
// isBearish = false;
// zone.Clean();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
p2BarPatterns.Clean();
p3BarPatterns.Clean();
iPatternsConfig.Clean();
//
return result;
}
@@ -0,0 +1,949 @@
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validation Flags ...
bool validateByBarPatterns = true;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Do ...
//
// Retrieve pBar Patterns ...
XPatternAnalysis pBarPatterns;
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
//
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
patternConfig //
);
//
bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
//
isBullish =
isConsolidation &&
zone.IsBullish();
//
isBearish =
isConsolidation &&
zone.IsBearish();
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Force PBar Has Pattern ...
if (result && validateByBarPatterns)
{
//
// Analyse Bar Patterns ...
result = pBarPatterns.IsValid();
//
// Bullish ...
bool isPBarHasBullishPatterns =
result &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
result &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Reset Flags ...
if (!result)
{
//
isBullish = false;
isBearish = false;
}
}
//
if (result)
{
//
poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
DebugBreak();
//
result = false;
isBullish = false;
isBearish = false;
}
// //
// // Validate based on Bars Patterns ...
// bool validateByBarPatterns = true;
// if (validateByBarPatterns)
// {
// //
// // Reading pBar Patterns ...
// XPatternAnalysis pBarAnalysis;
// poiDetector.AnalyseBarPatterns(
// pBar,
// pBarAnalysis,
// structureConfig.barsAnalysisConfig //
// );
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// (bar.close > pBar.low ||
// bar.open > pBar.low) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// (bar.close < pBar.high ||
// bar.open < pBar.high) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
// //
// // Checking PullBack ...
// bool validateByPullback = false;
// if (validateByPullback)
// {
// //
// XBoxZone pullback;
// ENUM_X_DIRECTION pullbackDir;
// bool isPullBack = result &&
// poiDetector.IsPullbackPattern(
// pBar,
// pullback,
// pullbackDir,
// 2,
// false // Force Break ...
// );
// bool isPullbackBullish = isPullBack &&
// IsXBullish(pullbackDir);
// bool isPullbackBearish = isPullBack &&
// IsXBearish(pullbackDir);
// //
// isBullish =
// isBullish &&
// isPullbackBullish;
// //
// isBearish =
// isBearish &&
// isPullbackBearish;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
//
// Validate ...
result = isBullish ||
isBearish;
//
// Prepare Zone ...
if (result)
{
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
//
return result;
}
// //
// bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
// //
// isBullish =
// isConsolidation &&
// zone.IsBullish();
// //
// isBearish =
// isConsolidation &&
// zone.IsBearish();
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Force PBar Has Pattern ...
// if (result && validateByBarPatterns)
// {
// //
// // Analyse Bar Patterns ...
// result = pBarPatterns.IsValid();
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Reset Flags ...
// if (!result)
// {
// //
// isBullish = false;
// isBearish = false;
// }
// }
// //
// if (result)
// {
// //
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
// poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
// DebugBreak();
// //
// result = false;
// isBullish = false;
// isBearish = false;
// }
// //
// // Validate based on Bars Patterns ...
// bool validateByBarPatterns = true;
// if (validateByBarPatterns)
// {
// //
// // Reading pBar Patterns ...
// XPatternAnalysis pBarAnalysis;
// poiDetector.AnalyseBarPatterns(
// pBar,
// pBarAnalysis,
// structureConfig.barsAnalysisConfig //
// );
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// (bar.close > pBar.low ||
// bar.open > pBar.low) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// (bar.close < pBar.high ||
// bar.open < pBar.high) &&
// (
// //
// pBarAnalysis.IsPinned(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarAnalysis.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
// //
// // Checking PullBack ...
// bool validateByPullback = false;
// if (validateByPullback)
// {
// //
// XBoxZone pullback;
// ENUM_X_DIRECTION pullbackDir;
// bool isPullBack = result &&
// poiDetector.IsPullbackPattern(
// pBar,
// pullback,
// pullbackDir,
// 2,
// false // Force Break ...
// );
// bool isPullbackBullish = isPullBack &&
// IsXBullish(pullbackDir);
// bool isPullbackBearish = isPullBack &&
// IsXBearish(pullbackDir);
// //
// isBullish =
// isBullish &&
// isPullbackBullish;
// //
// isBearish =
// isBearish &&
// isPullbackBearish;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
/**
* Check Bar Has Signal Based on Strategy 4 ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Validation Flags ...
bool validateByBarPatterns = false;
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
XOHCL p3Bar;
bool isBullish = false;
bool isBearish = false;
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
result = result &&
p2Bar.GetPreviousBar(p3Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
//
return result;
}
//
// Do ...
//
// Retrieve pBar Patterns ...
XPatternAnalysis pBarPatterns;
XPatternAnalysis p2BarPatterns;
XPatternAnalysisConfig patternConfig = structureConfig.barsAnalysisConfig;
//
poiDetector.AnalyseBarPatterns(
pBar,
pBarPatterns,
patternConfig //
);
poiDetector.AnalyseBarPatterns(
p2Bar,
p2BarPatterns,
patternConfig //
);
//
bool hasSupport = p2BarPatterns.IsValid() &&
p2BarPatterns.IsSupport();
bool hasResistance = p2BarPatterns.IsValid() &&
p2BarPatterns.IsResistance();
//
isBullish =
hasSupport &&
p2BarPatterns.Count(X_DIRECTION_BULLISH) >= 4;
//
isBearish =
hasResistance &&
p2BarPatterns.Count(X_DIRECTION_BEARISH) >= 4;
//
// Summarize Result ...
result = isBullish || isBearish;
//
// Extract Affected Zone ...
if (result)
{
//
XOHCL tmpBar;
XPivot tmpPivot;
XBoxZone tmpZone;
//
if (hasSupport)
{
//
hasSupport = p2BarPatterns.GetSupport(tmpBar, tmpPivot, tmpZone);
isBullish =
isBullish &&
hasSupport &&
(IsActed(pBar, tmpZone) ||
IsTested(pBar, tmpZone));
}
//
if (hasResistance)
{
//
hasResistance = p2BarPatterns.GetResistance(tmpBar, tmpPivot, tmpZone);
isBearish =
isBearish &&
hasResistance &&
(IsActed(pBar, tmpZone) ||
IsTested(pBar, tmpZone));
}
//
// Cleanup ...
tmpBar.Clean();
tmpZone.Clean();
tmpPivot.Clean();
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate based on Bars Patterns ...
if (result && validateByBarPatterns)
{
//
// Bullish...
bool isPBarHasBullishPatterns =
pBarPatterns.IsValid() &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
//
);
//
// Bearish ...
bool isPBarHasBearishPatterns =
pBarPatterns.IsValid() &&
(
//
pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
//
);
//
isBullish =
isBullish &&
isPBarHasBullishPatterns &&
!isPBarHasBearishPatterns;
//
isBearish =
isBearish &&
isPBarHasBearishPatterns &&
!isPBarHasBullishPatterns;
//
// Summarize Result ...
result = isBullish || isBearish;
}
if (result)
{
//
poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
poiDrawer.DrawPatternAnalysis(p2BarPatterns, structureDrawConfig.barAnalysisDrawConfig);
DebugBreak();
//
result = false;
isBullish = false;
isBearish = false;
}
// //
// bool isConsolidation = poiDetector.DetectXPVZone(zone, p2Bar.Index());
// //
// isBullish =
// isConsolidation &&
// zone.IsBullish();
// //
// isBearish =
// isConsolidation &&
// zone.IsBearish();
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Force PBar Has Pattern ...
// if (result && validateByBarPatterns)
// {
// //
// // Analyse Bar Patterns ...
// result = pBarPatterns.IsValid();
// //
// // Bullish ...
// bool isPBarHasBullishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BULLISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BULLISH)
// //
// );
// //
// // Bearish ...
// bool isPBarHasBearishPatterns =
// result &&
// (
// //
// pBarPatterns.IsPinned(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsEngulfed(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsMomentum(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsPiercing(X_DIRECTION_BEARISH) ||
// pBarPatterns.IsSignalKey(X_DIRECTION_BEARISH)
// //
// );
// //
// isBullish =
// isBullish &&
// isPBarHasBullishPatterns &&
// !isPBarHasBearishPatterns;
// //
// isBearish =
// isBearish &&
// isPBarHasBearishPatterns &&
// !isPBarHasBullishPatterns;
// //
// // Summarize Result ...
// result = isBullish || isBearish;
// //
// // Reset Flags ...
// if (!result)
// {
// //
// isBullish = false;
// isBearish = false;
// }
// }
// //
// if (result)
// {
// //
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
// poiDrawer.DrawPatternAnalysis(pBarPatterns, structureDrawConfig.barAnalysisDrawConfig);
// DebugBreak();
// //
// result = false;
// isBullish = false;
// isBearish = false;
// }
// //
// // Checking PullBack ...
// bool validateByPullback = false;
// if (validateByPullback)
// {
// //
// XBoxZone pullback;
// ENUM_X_DIRECTION pullbackDir;
// bool isPullBack = result &&
// poiDetector.IsPullbackPattern(
// pBar,
// pullback,
// pullbackDir,
// 2,
// false // Force Break ...
// );
// bool isPullbackBullish = isPullBack &&
// IsXBullish(pullbackDir);
// bool isPullbackBearish = isPullBack &&
// IsXBearish(pullbackDir);
// //
// isBullish =
// isBullish &&
// isPullbackBullish;
// //
// isBearish =
// isBearish &&
// isPullbackBearish;
// //
// // Summarize Result ...
// result = isBullish ||
// isBearish;
// }
//
// Validate ...
result = isBullish ||
isBearish;
//
// Prepare Zone ...
if (result)
{
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
p3Bar.Clean();
pBarPatterns.Clean();
patternConfig.Clean();
p2BarPatterns.Clean();
//
return result;
}
bool validateByPVChange = false;
bool validateByPVInside = false;
//
// Validate By PV Inside ...
if (result && validateByPVInside)
{
//
double pVale = fimaHelper.GetVale(pBar.Index());
double pPeak = fimaHelper.GetPeak(pBar.Index());
//
bool isValePassed = pVale <= support.upper &&
pVale >= support.upper &&
fimaParser.IsValeSame(pBar.Index());
//
bool isPeakPassed = pPeak <= resistance.upper &&
pPeak >= resistance.upper &&
fimaParser.IsPeakSame(pBar.Index());
//
isBullish =
isBullish &&
isValePassed;
//
isBearish =
isBearish &&
isPeakPassed;
//
// Summarize Result ...
result = isBullish || isBearish;
}
//
// Validate by PV Change ...
if (result && validateByPVChange)
{
//
// bullish => p3, p2 vale under last ...
// bearish => p3, p2 peak over last ...
//
bool isValePassed =
fimaParser.IsValeUnderLast(p2Bar.Index()) ||
fimaParser.IsValeUnderLast(p3Bar.Index());
//
bool isPeakPassed =
fimaParser.IsPeakOverLast(p2Bar.Index()) ||
fimaParser.IsPeakOverLast(p3Bar.Index());
//
isBullish =
isBullish &&
isValePassed;
//
isBearish =
isBearish &&
isPeakPassed;
//
// Summarize Result ...
result = isBullish || isBearish;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+547
View File
@@ -0,0 +1,547 @@
//+------------------------------------------------------------------+
//| XKI_MTF_EA.mq5
//| SaherElm IT Center - Strategy using XKI
//| Author: Hadi Khazaee Asl
//+------------------------------------------------------------------+
#property strict
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
// Inputs
input string InpSymbol = "XAUUSDb";
input ENUM_TIMEFRAMES InpSignalTF = PERIOD_H1; // Signal timeframe (H1)
input int InpKiLength = 26; // KI length (XKI input)
input bool InpShowKI = true; // (XKI input)
input int InpCalcLastBars = 1500; // (XKI input)
input bool InpUseRSI = true; // Use RSI confirmation
input int InpRSIPeriod = 14;
input int InpRSIPrice = PRICE_CLOSE;
input bool InpUseH4Filter = true; // Confirm with H4
input bool InpUseD1Filter = false; // Confirm with D1
input bool InpRequireBothFilters = false; // If true, require BOTH H4 and D1 agreement; else either
input double InpFixedLot = 0.10; // Fixed lot size
input double InpRiskATRMult = 0.0; // Add ATR padding to stop (0=disabled)
input int InpATRPeriod = 14;
input double InpRR = 2.0; // Reward:Risk target
input bool InpTrailByKI = true; // Trail stop to KI
input int InpSlippagePoints = 20; // Max slippage in points
input int InpMaxSpreadPoints = 200; // Max allowed spread in points
input bool InpAvoidAsianSession = true; // Avoid 22:00–06:00 server time
input int InpAsianStartHour = 22;
input int InpAsianEndHour = 6;
input bool InpAvoidNewsWindow = false; // Placeholder flag
input int InpNewsWindowMinutes = 60; // Skip trades within +/- minutes
input int InpBarsLookbackSignal = 2; // Lookback bars for signal (e.g., last closed bar)
// Magic number and comments
input int InpMagic = 260126;
input string InpOrderComment = "XKI_MTF_EA";
// iCustom indicator path (relative to Indicators folder if compiled there)
string g_xkiIndicatorPath = "x-saherelm.x121.xki"; // the compiled name; adjust if different
// Buffers indices as per the indicator
#define KI_BUFFER_INDEX 0
#define KI_COLOR_IDX_BUFFER_INDEX 1
#define KI_STATE_BUFFER_INDEX 2
// States from indicator
#define BULLISH_STATE 1
#define NEUTURAL_STATE 0
#define BEARISH_STATE -1
// Globals
int g_digits;
double g_point;
MqlTick g_tick;
int g_atrHandleH1 = INVALID_HANDLE;
int g_atrHandleH4 = INVALID_HANDLE;
int g_atrHandleD1 = INVALID_HANDLE;
int g_rsiHandleH1 = INVALID_HANDLE;
int g_rsiHandleH4 = INVALID_HANDLE;
int g_rsiHandleD1 = INVALID_HANDLE;
//+------------------------------------------------------------------+
// OnInit
//+------------------------------------------------------------------+
int OnInit()
{
//
g_digits = (int)SymbolInfoInteger(InpSymbol, SYMBOL_DIGITS);
g_point = SymbolInfoDouble(InpSymbol, SYMBOL_POINT);
if (!SymbolInfoTick(InpSymbol, g_tick))
{
Print("Failed to get tick for symbol: ", InpSymbol);
return INIT_FAILED;
}
// Quick validation
if (InpKiLength < 5)
{
Print("Invalid KI length: ", InpKiLength);
return INIT_PARAMETERS_INCORRECT;
}
//
GetOrCreateATRHandle(InpSymbol, InpSignalTF, InpATRPeriod);
if (InpUseH4Filter)
GetOrCreateATRHandle(InpSymbol, PERIOD_H4, InpATRPeriod);
if (InpUseD1Filter)
GetOrCreateATRHandle(InpSymbol, PERIOD_D1, InpATRPeriod);
//
GetOrCreateRSIHandle(InpSymbol, InpSignalTF, InpRSIPeriod, InpRSIPrice);
if (InpUseH4Filter)
GetOrCreateRSIHandle(InpSymbol, PERIOD_H4, InpRSIPeriod, InpRSIPrice);
if (InpUseD1Filter)
GetOrCreateRSIHandle(InpSymbol, PERIOD_D1, InpRSIPeriod, InpRSIPrice);
//
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
// OnDeinit
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//
if (g_atrHandleH1 != INVALID_HANDLE)
{
IndicatorRelease(g_atrHandleH1);
g_atrHandleH1 = INVALID_HANDLE;
}
if (g_atrHandleH4 != INVALID_HANDLE)
{
IndicatorRelease(g_atrHandleH4);
g_atrHandleH4 = INVALID_HANDLE;
}
if (g_atrHandleD1 != INVALID_HANDLE)
{
IndicatorRelease(g_atrHandleD1);
g_atrHandleD1 = INVALID_HANDLE;
}
//
if (g_rsiHandleH1 != INVALID_HANDLE)
{
IndicatorRelease(g_rsiHandleH1);
g_rsiHandleH1 = INVALID_HANDLE;
}
if (g_rsiHandleH4 != INVALID_HANDLE)
{
IndicatorRelease(g_rsiHandleH4);
g_rsiHandleH4 = INVALID_HANDLE;
}
if (g_rsiHandleD1 != INVALID_HANDLE)
{
IndicatorRelease(g_rsiHandleD1);
g_rsiHandleD1 = INVALID_HANDLE;
}
}
//+------------------------------------------------------------------+
// OnTick
//+------------------------------------------------------------------+
void OnTick()
{
if (_Symbol != InpSymbol)
return;
// Basic trading safety
if (!SymbolInfoTick(InpSymbol, g_tick))
return;
double spreadPoints = GetSpread(InpSymbol);
if (spreadPoints > InpMaxSpreadPoints)
return;
if (InpAvoidAsianSession)
{
//
MqlDateTime now = GetCurrentTime();
int hr = now.hour;
if (IsHourInRange(hr, InpAsianStartHour, InpAsianEndHour))
return;
}
if (InpAvoidNewsWindow)
{
// Placeholder: implement your own calendar integration
// Skip trading in a window near news. Here we simply return.
return;
}
// Only process on new bar of signal timeframe
static datetime lastSignalBarTime = 0;
datetime currentSignalBarTime = GetLastClosedBarTime(InpSymbol, InpSignalTF);
if (currentSignalBarTime == 0 || currentSignalBarTime == lastSignalBarTime)
return;
lastSignalBarTime = currentSignalBarTime;
// Get signal state and KI on signal TF (last closed bar)
int signalBarShift = InpBarsLookbackSignal; // 1=last closed, 2=previous
int stateSignal;
double kiSignal, closeSignal;
if (!GetXKIStateAndKI(InpSymbol, InpSignalTF, signalBarShift, stateSignal, kiSignal))
return;
closeSignal = iClose(InpSymbol, InpSignalTF, signalBarShift);
// RSI confirmation
if (InpUseRSI)
{
double rsi = GetRSIValue(InpSymbol, InpSignalTF, InpRSIPeriod, InpRSIPrice, signalBarShift);
if (rsi == EMPTY_VALUE)
return;
if (stateSignal == BULLISH_STATE && rsi <= 50.0)
return;
if (stateSignal == BEARISH_STATE && rsi >= 50.0)
return;
}
// Higher timeframe agreement
bool agreesH4 = true, agreesD1 = true;
if (InpUseH4Filter)
agreesH4 = HigherTFAgrees(InpSymbol, PERIOD_H4, signalBarShift, stateSignal);
if (InpUseD1Filter)
agreesD1 = HigherTFAgrees(InpSymbol, PERIOD_D1, signalBarShift, stateSignal);
bool filterOK = true;
if (InpUseH4Filter || InpUseD1Filter)
{
if (InpRequireBothFilters)
filterOK = (agreesH4 && agreesD1);
else
filterOK = ((InpUseH4Filter && agreesH4) || (InpUseD1Filter && agreesD1));
}
if (!filterOK)
return;
// Neutral or invalid skip
if (stateSignal == NEUTURAL_STATE)
return;
// Ensure no open positions for this symbol/magic
if (HasOpenPosition(InpSymbol, InpMagic))
return;
// Prepare trade params
double atrPad = 0.0;
if (InpRiskATRMult > 0.0)
{
double atr = GetATRValue(InpSymbol, InpSignalTF, InpATRPeriod, signalBarShift);
if (atr != EMPTY_VALUE && atr > 0)
atrPad = atr * InpRiskATRMult;
}
double sl, tp;
bool isBuy = (stateSignal == BULLISH_STATE);
if (isBuy)
{
sl = kiSignal - atrPad;
tp = closeSignal + (closeSignal - sl) * InpRR;
PlaceOrder(InpSymbol, ORDER_TYPE_BUY, InpFixedLot, sl, tp);
}
else if (stateSignal == BEARISH_STATE)
{
sl = kiSignal + atrPad;
tp = closeSignal - (sl - closeSignal) * InpRR;
PlaceOrder(InpSymbol, ORDER_TYPE_SELL, InpFixedLot, sl, tp);
}
// After placement, trailing handled in OnTimer or OnTick below
if (InpTrailByKI)
TrailStopsByKI();
}
//+------------------------------------------------------------------+
// Utilities
//+------------------------------------------------------------------+
//
// Create or reuse an ATR handle for the given TF ...
int GetOrCreateATRHandle(
string symbol,
ENUM_TIMEFRAMES tf,
int period //
)
{
int h = g_atrHandleH1;
if (tf == PERIOD_H4)
h = g_atrHandleH4;
else if (tf == PERIOD_D1)
h = g_atrHandleD1;
if (h == INVALID_HANDLE)
{
h = iATR(symbol, tf, period);
if (h == INVALID_HANDLE)
Print("Failed to create ATR handle: ", symbol, " ", EnumToString(tf), " period=", period);
}
return h;
}
//
// Read ATR value for a specific bar shift (1=last closed bar) ...
double GetATRValue(
string symbol,
ENUM_TIMEFRAMES tf,
int period,
int shift //
)
{
int h = GetOrCreateATRHandle(symbol, tf, period);
if (h == INVALID_HANDLE)
return EMPTY_VALUE;
//
double buff[];
//
// Copy exactly one value at 'shift' ...
int copied = CopyBuffer(h, 0, shift, 1, buff);
if (copied != 1 || !MathIsValidNumber(buff[0]))
return EMPTY_VALUE;
//
return buff[0];
}
//
// Create or reuse an RSI handle for the given TF ...
int GetOrCreateRSIHandle(
string symbol,
ENUM_TIMEFRAMES tf,
int period,
int appliedPrice //
)
{
//
int h = g_rsiHandleH1;
if (tf == PERIOD_H4)
h = g_rsiHandleH4;
else if (tf == PERIOD_D1)
h = g_rsiHandleD1;
if (h == INVALID_HANDLE)
{
h = iRSI(symbol, tf, period, appliedPrice);
if (h == INVALID_HANDLE)
Print("Failed to create RSI handle: ", symbol, " ", EnumToString(tf), " period=", period, " price=", appliedPrice);
}
return h;
}
//
// Read RSI value for a specific bar shift (1=last closed bar) ..
double GetRSIValue(
string symbol,
ENUM_TIMEFRAMES tf,
int period,
int appliedPrice,
int shift //
)
{
int h = GetOrCreateRSIHandle(symbol, tf, period, appliedPrice);
if (h == INVALID_HANDLE)
return EMPTY_VALUE;
double buff[];
int copied = CopyBuffer(h, 0, shift, 1, buff);
if (copied != 1 || !MathIsValidNumber(buff[0]))
return EMPTY_VALUE;
return buff[0];
}
datetime GetLastClosedBarTime(string symbol, ENUM_TIMEFRAMES tf)
{
datetime times[];
if (CopyTime(symbol, tf, 0, 3, times) <= 1)
return 0;
// times[0] is current open bar time; last closed is times[1]
return times[1];
}
bool IsHourInRange(int hr, int startHr, int endHr)
{
// Handles wrap-around (e.g., 22 -> 6)
if (startHr <= endHr)
return (hr >= startHr && hr < endHr);
else
return (hr >= startHr || hr < endHr);
}
bool GetXKIStateAndKI(string symbol, ENUM_TIMEFRAMES tf, int shift, int &stateOut, double &kiOut)
{
// Prepare indicator handle for this TF
static int handleH1 = INVALID_HANDLE;
static int handleH4 = INVALID_HANDLE;
static int handleD1 = INVALID_HANDLE;
int handleRef = handleH1;
if (tf == PERIOD_H4)
handleRef = handleH4;
else if (tf == PERIOD_D1)
handleRef = handleD1;
if (handleRef == INVALID_HANDLE)
{
handleRef = iCustom(symbol, tf, g_xkiIndicatorPath,
InpKiLength, InpShowKI, InpCalcLastBars);
if (handleRef == INVALID_HANDLE)
{
Print("Failed to create XKI handle for TF: ", EnumToString(tf));
return false;
}
}
double kiBuff[];
double stateBuff[];
if (CopyBuffer(handleRef, KI_BUFFER_INDEX, shift, 1, kiBuff) != 1)
return false;
if (CopyBuffer(handleRef, KI_STATE_BUFFER_INDEX, shift, 1, stateBuff) != 1)
return false;
kiOut = kiBuff[0];
stateOut = (int)stateBuff[0];
if (!MathIsValidNumber(kiOut))
return false;
return true;
}
bool HigherTFAgrees(string symbol, ENUM_TIMEFRAMES tf, int shift, int signalState)
{
int stateHTF;
double kiHTF;
if (!GetXKIStateAndKI(symbol, tf, shift, stateHTF, kiHTF))
return false;
if (signalState == BULLISH_STATE)
return (stateHTF == BULLISH_STATE);
if (signalState == BEARISH_STATE)
return (stateHTF == BEARISH_STATE);
return false;
}
bool HasOpenPosition(string symbol, int magic)
{
for (int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if (ticket == 0)
continue;
if (PositionSelectByTicket(ticket))
{
string sym = PositionGetString(POSITION_SYMBOL);
long mg = (long)PositionGetInteger(POSITION_MAGIC);
if (sym == symbol && mg == magic)
return true;
}
}
return false;
}
void PlaceOrder(string symbol, ENUM_ORDER_TYPE type, double lots, double sl, double tp)
{
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
double price = 0.0;
if (!SymbolInfoTick(symbol, g_tick))
return;
if (type == ORDER_TYPE_BUY)
price = g_tick.ask;
else if (type == ORDER_TYPE_SELL)
price = g_tick.bid;
// Normalize SL/TP
sl = NormalizeDouble(sl, g_digits);
tp = NormalizeDouble(tp, g_digits);
price = NormalizeDouble(price, g_digits);
req.action = TRADE_ACTION_DEAL;
req.symbol = symbol;
req.volume = lots;
req.type = type;
req.price = price;
req.sl = sl;
req.tp = tp;
req.deviation = InpSlippagePoints;
req.magic = InpMagic;
req.comment = InpOrderComment;
if (!OrderSend(req, res))
Print("OrderSend failed: ", res.retcode);
}
void TrailStopsByKI()
{
// Trail per position using current signal TF KI
for (int i = 0; i < PositionsTotal(); i++)
{
ulong ticket = PositionGetTicket(i);
if (ticket == 0)
continue;
if (!PositionSelectByTicket(ticket))
continue;
string sym = PositionGetString(POSITION_SYMBOL);
long mg = (long)PositionGetInteger(POSITION_MAGIC);
if (sym != InpSymbol || mg != InpMagic)
continue;
ENUM_POSITION_TYPE ptype = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double sl = PositionGetDouble(POSITION_SL);
double priceOpen = PositionGetDouble(POSITION_PRICE_OPEN);
// Use last closed bar KI for stability
int shift = 1;
int state;
double ki;
if (!GetXKIStateAndKI(sym, InpSignalTF, shift, state, ki))
continue;
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
double newSL = sl;
if (ptype == POSITION_TYPE_BUY)
{
double proposedSL = NormalizeDouble(ki, g_digits);
if (proposedSL > sl)
newSL = proposedSL; // only move up
}
else if (ptype == POSITION_TYPE_SELL)
{
double proposedSL = NormalizeDouble(ki, g_digits);
if (proposedSL < sl || sl == 0.0)
newSL = proposedSL; // only move down (or set if none)
}
if (newSL != sl && newSL != 0.0)
{
req.action = TRADE_ACTION_SLTP;
req.symbol = sym;
req.sl = newSL;
req.tp = PositionGetDouble(POSITION_TP);
req.magic = InpMagic;
if (!OrderSend(req, res))
Print("Trail SLTP failed: ", res.retcode);
}
}
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -0,0 +1,708 @@
//+------------------------------------------------------------------+
//| TrendPullbackPro.mq5|
//| Trend-following pullback EA with risk & management |
//+------------------------------------------------------------------+
#property copyright "Hadi Strategy"
#property link ""
#property version "1.10"
#property strict
//--- Inputs: risk & money management
input double InpRiskPerTradePercent = 1.0; // Total risk per trade (% of balance)
input int InpMagicNumber = 123456; // Magic number
input double InpStopBufferPoints = 10; // Extra buffer beyond swing high/low (points)
//--- Inputs: indicators
input ENUM_TIMEFRAMES InpTF = PERIOD_CURRENT; // Signal timeframe
input int InpFastEMAPeriod = 20;
input int InpSlowEMAPeriod = 50;
input int InpRSIPeriod = 14;
input double InpRSILowZoneMin = 40; // Uptrend pullback zone min
input double InpRSILowZoneMax = 50; // Uptrend pullback zone max
input double InpRSIHighZoneMin = 50; // Downtrend pullback zone min
input double InpRSIHighZoneMax = 60; // Downtrend pullback zone max
//--- Inputs: partial TP and R multiples
input bool InpUsePartialTP = true;
input double InpPartialCloseAtR = 1.0; // R at which to take partial profit
input double InpPartialClosePercent = 50.0; // % of volume to close at partial TP
input double InpFinalTargetR = 3.0; // Final target R for runner
input bool InpUseBreakEven = true;
input double InpBreakEvenRMultiple = 1.0; // Move SL to BE at this R (runner)
//--- Inputs: trailing stop
input bool InpUseEMATrailing = true;
input double InpTrailStartR = 1.0; // Start trailing after this R
input double InpTrailOffsetPoints = 5; // Extra buffer beyond EMA (points)
//--- Inputs: spread & time filters
input bool InpUseSpreadFilter = true;
input double InpMaxSpreadPoints = 30; // Max allowed spread (in points)
input bool InpUseTimeFilter = false;
input int InpSessionStartHour = 8; // Trading session start (server time)
input int InpSessionEndHour = 22; // Trading session end (server time)
input bool InpAvoidRolloverHour = true;
input int InpRolloverHour = 23; // Avoid new entries at this hour
//--- constants
#define NO_TREND 0
#define UPTREND 1
#define DOWNTREND -1
#define PARTIAL_COMMENT "TrendPullbackEA_Partial"
#define RUNNER_COMMENT "TrendPullbackEA_Runner"
//--- Global indicator handles
int rsi_handle;
int ema_fast_handle;
int ema_slow_handle;
//--- Tick storage
MqlTick last_tick;
//+------------------------------------------------------------------+
//| OnInit |
//+------------------------------------------------------------------+
int OnInit()
{
rsi_handle = iRSI(_Symbol, InpTF, InpRSIPeriod, PRICE_CLOSE);
if(rsi_handle == INVALID_HANDLE)
{
Print("Error creating RSI handle. Error: ", GetLastError());
return(INIT_FAILED);
}
ema_fast_handle = iMA(_Symbol, InpTF, InpFastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(ema_fast_handle == INVALID_HANDLE)
{
Print("Error creating fast EMA handle. Error: ", GetLastError());
return(INIT_FAILED);
}
ema_slow_handle = iMA(_Symbol, InpTF, InpSlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
if(ema_slow_handle == INVALID_HANDLE)
{
Print("Error creating slow EMA handle. Error: ", GetLastError());
return(INIT_FAILED);
}
SymbolInfoTick(_Symbol, last_tick);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| OnDeinit |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(rsi_handle);
IndicatorRelease(ema_fast_handle);
IndicatorRelease(ema_slow_handle);
}
//+------------------------------------------------------------------+
//| OnTick |
//+------------------------------------------------------------------+
void OnTick()
{
if(!SymbolInfoTick(_Symbol, last_tick))
return;
// Run main logic once per bar on signal timeframe
static datetime last_bar_time = 0;
datetime cur_bar_time = iTime(_Symbol, InpTF, 0);
if(cur_bar_time == last_bar_time)
return;
last_bar_time = cur_bar_time;
ManageOpenPositions();
// Avoid new entries if no time/spread conditions
if(!CanOpenNewTrades())
return;
CheckOpenSignals();
}
//+------------------------------------------------------------------+
//| Check if we can open new trades (time & spread) |
//+------------------------------------------------------------------+
bool CanOpenNewTrades()
{
// Spread filter
if(InpUseSpreadFilter)
{
double spread_points = (SymbolInfoDouble(_Symbol, SYMBOL_ASK) - SymbolInfoDouble(_Symbol, SYMBOL_BID))
/ SymbolInfoDouble(_Symbol, SYMBOL_POINT);
if(spread_points > InpMaxSpreadPoints)
{
//Print("Spread too high: ", spread_points, " > ", InpMaxSpreadPoints);
return(false);
}
}
// Time filter
if(InpUseTimeFilter)
{
datetime now = TimeCurrent();
MqlDateTime dt;
TimeToStruct(now, dt);
// avoid rollover hour
if(InpAvoidRolloverHour && dt.hour == InpRolloverHour)
return(false);
// session window
bool inSession = (dt.hour >= InpSessionStartHour && dt.hour < InpSessionEndHour);
if(!inSession)
return(false);
}
return(true);
}
//+------------------------------------------------------------------+
//| Check for new entry signals |
//+------------------------------------------------------------------+
void CheckOpenSignals()
{
if(HasOpenPosition())
return;
int trend = GetTrendDirection();
if(trend == NO_TREND)
return;
double rsi_value;
if(!GetRSI(1, rsi_value))
return;
MqlRates rates[];
if(CopyRates(_Symbol, InpTF, 0, 3, rates) < 3)
return;
// rates[0] current, [1] closed 1, [2] closed 2
MqlRates candle = rates[1];
MqlRates prev = rates[2];
bool longSignal = false;
bool shortSignal = false;
if(trend == UPTREND)
{
if(rsi_value >= InpRSILowZoneMin && rsi_value <= InpRSILowZoneMax)
{
if(IsBullishPattern(candle, prev))
longSignal = true;
}
}
else if(trend == DOWNTREND)
{
if(rsi_value >= InpRSIHighZoneMin && rsi_value <= InpRSIHighZoneMax)
{
if(IsBearishPattern(candle, prev))
shortSignal = true;
}
}
if(longSignal)
OpenTrade(ORDER_TYPE_BUY, candle);
else if(shortSignal)
OpenTrade(ORDER_TYPE_SELL, candle);
}
//+------------------------------------------------------------------+
//| Manage open positions (partial TP, BE, trailing) |
//+------------------------------------------------------------------+
void ManageOpenPositions()
{
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
for(int i = PositionsTotal()-1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(!PositionSelectByTicket(ticket))
continue;
if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber)
continue;
if(PositionGetString(POSITION_SYMBOL) != _Symbol)
continue;
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
double price_open = PositionGetDouble(POSITION_PRICE_OPEN);
string comment = PositionGetString(POSITION_COMMENT);
MqlTick tick;
SymbolInfoTick(_Symbol, tick);
double current_price = (type == POSITION_TYPE_BUY ? tick.bid : tick.ask);
double riskPoints;
if(type == POSITION_TYPE_BUY)
riskPoints = (price_open - sl) / point;
else
riskPoints = (sl - price_open) / point;
if(riskPoints <= 0)
continue;
double profitPoints;
if(type == POSITION_TYPE_BUY)
profitPoints = (current_price - price_open) / point;
else
profitPoints = (price_open - current_price) / point;
double rMultiple = profitPoints / riskPoints;
// 1) Partial TP logic for "partial" leg
if(InpUsePartialTP && comment == PARTIAL_COMMENT)
{
if(rMultiple >= InpPartialCloseAtR)
{
// Close this position fully (it's the partial leg)
ClosePosition(ticket);
continue;
}
}
// 2) Break-even & trailing for runner leg
if(comment == RUNNER_COMMENT)
{
// Break-even
if(InpUseBreakEven && rMultiple >= InpBreakEvenRMultiple)
{
if(type == POSITION_TYPE_BUY && sl < price_open)
ModifyPositionSL(ticket, price_open);
else if(type == POSITION_TYPE_SELL && sl > price_open)
ModifyPositionSL(ticket, price_open);
}
// EMA trailing after a certain R
if(InpUseEMATrailing && rMultiple >= InpTrailStartR)
{
double emaFast;
if(!GetEMA(ema_fast_handle, 1, emaFast))
continue;
double newSL;
double offset = InpTrailOffsetPoints * point;
if(type == POSITION_TYPE_BUY)
{
newSL = emaFast - offset;
if(newSL > sl && newSL < current_price) // only tighten SL
ModifyPositionSL(ticket, newSL);
}
else
{
newSL = emaFast + offset;
if(newSL < sl && newSL > current_price)
ModifyPositionSL(ticket, newSL);
}
}
// Optionally: ensure TP aligns with final target R
// If user wants to rely only on trailing, they can disable or adjust final R.
// We keep TP as set at entry.
}
}
}
//+------------------------------------------------------------------+
//| Get trend direction from EMAs |
//+------------------------------------------------------------------+
int GetTrendDirection()
{
double ema_fast[3], ema_slow[3];
if(CopyBuffer(ema_fast_handle, 0, 0, 3, ema_fast) < 3)
return NO_TREND;
if(CopyBuffer(ema_slow_handle, 0, 0, 3, ema_slow) < 3)
return NO_TREND;
double fast = ema_fast[1];
double slow = ema_slow[1];
if(fast > slow)
return UPTREND;
else if(fast < slow)
return DOWNTREND;
return NO_TREND;
}
//+------------------------------------------------------------------+
//| Get RSI value at bar index |
//+------------------------------------------------------------------+
bool GetRSI(int index, double &value)
{
double buffer[1];
int copied = CopyBuffer(rsi_handle, 0, index, 1, buffer);
if(copied != 1)
return false;
value = buffer[0];
return true;
}
//+------------------------------------------------------------------+
//| Get EMA value from handle |
//+------------------------------------------------------------------+
bool GetEMA(int handle, int index, double &value)
{
double buffer[1];
int copied = CopyBuffer(handle, 0, index, 1, buffer);
if(copied != 1)
return false;
value = buffer[0];
return true;
}
//+------------------------------------------------------------------+
//| Bullish pattern: engulfing + pin-bar-ish |
//+------------------------------------------------------------------+
bool IsBullishPattern(const MqlRates &c, const MqlRates &prev)
{
double bodyC = MathAbs(c.close - c.open);
double bodyP = MathAbs(prev.close - prev.open);
double rangeC = c.high - c.low;
if(rangeC <= 0)
return false;
// Basic bullish: close > open
if(c.close <= c.open)
return false;
// Engulfing body: current body >= previous body, and covers its open/close
bool engulfing = (bodyC >= bodyP && c.open <= prev.close && c.close >= prev.open);
// Pin-bar-ish: long lower wick
double lowerWick = MathMin(c.open, c.close) - c.low;
bool longLowerWick = (lowerWick >= rangeC * 0.4); // tweak
if(engulfing || longLowerWick)
return true;
return false;
}
//+------------------------------------------------------------------+
//| Bearish pattern: engulfing + pin-bar-ish |
//+------------------------------------------------------------------+
bool IsBearishPattern(const MqlRates &c, const MqlRates &prev)
{
double bodyC = MathAbs(c.close - c.open);
double bodyP = MathAbs(prev.close - prev.open);
double rangeC = c.high - c.low;
if(rangeC <= 0)
return false;
// Basic bearish: close < open
if(c.close >= c.open)
return false;
// Engulfing body
bool engulfing = (bodyC >= bodyP && c.open >= prev.close && c.close <= prev.open);
// Pin-bar-ish: long upper wick
double upperWick = c.high - MathMax(c.open, c.close);
bool longUpperWick = (upperWick >= rangeC * 0.4); // tweak
if(engulfing || longUpperWick)
return true;
return false;
}
//+------------------------------------------------------------------+
//| Check if there is already an open position |
//+------------------------------------------------------------------+
bool HasOpenPosition()
{
for(int i = PositionsTotal()-1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(!PositionSelectByTicket(ticket))
continue;
if(PositionGetInteger(POSITION_MAGIC) != InpMagicNumber)
continue;
if(PositionGetString(POSITION_SYMBOL) == _Symbol)
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Calculate lot size based on total risk % |
//+------------------------------------------------------------------+
double CalculateTotalVolume(double stopLossPrice, ENUM_ORDER_TYPE type)
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double riskMoney = balance * InpRiskPerTradePercent / 100.0;
double entryPrice = (type == ORDER_TYPE_BUY ? last_tick.ask : last_tick.bid);
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
if(tick_size <= 0 || tick_value <= 0)
return(0.0);
double slDistance = (type == ORDER_TYPE_BUY ? entryPrice - stopLossPrice : stopLossPrice - entryPrice);
if(slDistance <= 0)
return(0.0);
double moneyPerPointPerLot = tick_value / tick_size * point;
double stopPoints = slDistance / point;
double volume = riskMoney / (stopPoints * moneyPerPointPerLot);
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double lotStep= SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
volume = MathFloor(volume / lotStep) * lotStep;
if(volume < minLot)
volume = 0.0;
if(volume > maxLot)
volume = maxLot;
return(volume);
}
//+------------------------------------------------------------------+
//| Open trade: split into partial + runner |
//+------------------------------------------------------------------+
void OpenTrade(ENUM_ORDER_TYPE type, const MqlRates &signalCandle)
{
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick))
return;
double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double entryPrice = (type == ORDER_TYPE_BUY ? tick.ask : tick.bid);
double slPrice;
if(type == ORDER_TYPE_BUY)
slPrice = signalCandle.low - InpStopBufferPoints * point;
else
slPrice = signalCandle.high + InpStopBufferPoints * point;
if(slPrice <= 0)
return;
double totalVolume = CalculateTotalVolume(slPrice, type);
if(totalVolume <= 0)
{
Print("Calculated total volume <= 0, skipping trade.");
return;
}
double slDistance = (type == ORDER_TYPE_BUY ? entryPrice - slPrice : slPrice - entryPrice);
// final TP at FinalTargetR
double finalTPDistance = slDistance * InpFinalTargetR;
double runnerTP;
if(type == ORDER_TYPE_BUY)
runnerTP = entryPrice + finalTPDistance;
else
runnerTP = entryPrice - finalTPDistance;
// partial volume
double partialVolume = totalVolume;
double runnerVolume = 0.0;
if(InpUsePartialTP && InpPartialClosePercent > 0 && InpPartialClosePercent < 100)
{
partialVolume = totalVolume * (InpPartialClosePercent / 100.0);
runnerVolume = totalVolume - partialVolume;
}
else
{
// no partial: everything is runner
partialVolume = 0.0;
runnerVolume = totalVolume;
}
// normalized volumes
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
partialVolume = MathFloor(partialVolume / lotStep) * lotStep;
runnerVolume = MathFloor(runnerVolume / lotStep) * lotStep;
if(partialVolume < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
partialVolume = 0.0;
if(runnerVolume < SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN))
runnerVolume = 0.0;
// Partial TP price at PartialCloseAtR
double partialTPPrice = 0.0;
if(InpUsePartialTP && partialVolume > 0 && InpPartialCloseAtR > 0)
{
double partialTPDist = slDistance * InpPartialCloseAtR;
if(type == ORDER_TYPE_BUY)
partialTPPrice = entryPrice + partialTPDist;
else
partialTPPrice = entryPrice - partialTPDist;
}
// 1) Open partial leg
if(partialVolume > 0.0)
{
SendOrder(type, partialVolume, slPrice, partialTPPrice, PARTIAL_COMMENT);
}
// 2) Open runner leg
if(runnerVolume > 0.0)
{
SendOrder(type, runnerVolume, slPrice, runnerTP, RUNNER_COMMENT);
}
}
//+------------------------------------------------------------------+
//| Send market order |
//+------------------------------------------------------------------+
bool SendOrder(ENUM_ORDER_TYPE type, double volume, double sl, double tp, string comment)
{
if(volume <= 0.0)
return(false);
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick))
return(false);
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.magic = InpMagicNumber;
request.symbol = _Symbol;
request.volume = volume;
request.type = type;
request.deviation = 20; // points
request.type_filling= ORDER_FILLING_FOK;
request.price = (type == ORDER_TYPE_BUY ? tick.ask : tick.bid);
request.sl = sl;
request.tp = tp;
request.comment = comment;
if(!OrderSend(request, result))
{
Print("OrderSend failed. Error: ", GetLastError());
return(false);
}
if(result.retcode != TRADE_RETCODE_DONE)
{
Print("OrderSend retcode: ", result.retcode);
return(false);
}
Print("Opened ", (type == ORDER_TYPE_BUY ? "BUY" : "SELL"),
" ticket #", result.order, " vol=", DoubleToString(volume,2),
" SL=", DoubleToString(sl,_Digits)," TP=", DoubleToString(tp,_Digits),
" comment=", comment);
return(true);
}
//+------------------------------------------------------------------+
//| Modify SL for position |
//+------------------------------------------------------------------+
bool ModifyPositionSL(ulong ticket, double newSL)
{
if(!PositionSelectByTicket(ticket))
return(false);
string sym = PositionGetString(POSITION_SYMBOL);
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
double tp = PositionGetDouble(POSITION_TP);
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_SLTP;
request.magic = InpMagicNumber;
request.symbol = sym;
request.volume = volume;
request.type = (ENUM_ORDER_TYPE)type;
request.price = price;
request.sl = newSL;
request.tp = tp;
if(!OrderSend(request, result))
{
Print("ModifyPositionSL OrderSend failed. Error: ", GetLastError());
return(false);
}
if(result.retcode != TRADE_RETCODE_DONE)
{
Print("ModifyPositionSL retcode: ", result.retcode);
return(false);
}
Print("Modified SL for ticket #", ticket, " to ", DoubleToString(newSL,_Digits));
return(true);
}
//+------------------------------------------------------------------+
//| Close position |
//+------------------------------------------------------------------+
bool ClosePosition(ulong ticket)
{
if(!PositionSelectByTicket(ticket))
return(false);
string sym = PositionGetString(POSITION_SYMBOL);
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double price = 0.0;
MqlTick tick;
if(!SymbolInfoTick(sym, tick))
return(false);
if(type == POSITION_TYPE_BUY)
price = tick.bid;
else
price = tick.ask;
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.magic = InpMagicNumber;
request.symbol = sym;
request.volume = volume;
request.type = (type == POSITION_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY);
request.price = price;
request.deviation = 20;
request.type_filling= ORDER_FILLING_FOK;
request.comment = "Close";
if(!OrderSend(request, result))
{
Print("ClosePosition OrderSend failed. Error: ", GetLastError());
return(false);
}
if(result.retcode != TRADE_RETCODE_DONE)
{
Print("ClosePosition retcode: ", result.retcode);
return(false);
}
Print("Closed ticket #", ticket);
return(true);
}
//+------------------------------------------------------------------+
Binary file not shown.
+525
View File
@@ -0,0 +1,525 @@
//+------------------------------------------------------------------+
//| XRR_Pullback.mq5 |
//| Author: Hadi (for XAUUSD,M15) |
//+------------------------------------------------------------------+
#property strict
#property version "0.1"
#property description "M15 pullback EA: Major zone (HH/LL), minor same-direction zone, pullback entry, SL under minor, TP at 2R, 1% risk."
//------------------------------- Inputs -----------------------------
input string Inp_Symbol = "XAUUSD";
input ENUM_TIMEFRAMES Inp_WorkTF = PERIOD_M15;
// Zone detection params
input int Inp_MajorLookbackBars = 400; // bars to scan for HH/LL major zone
input int Inp_MinorWindowBars = 80; // window to find first same-direction minor zone post-major
input int Inp_ZonePadPoints = 50; // padding around zones (points)
// Confirmation / filters
input bool Inp_UseHTFConfluence = true;
input ENUM_TIMEFRAMES Inp_HTF = PERIOD_H1; // confluence timeframe
input int Inp_HTFShiftBars = 3; // HTF confirmation window
input bool Inp_UseEngulfingConfirm = true;
input bool Inp_UseRSIDivergence = false;
input int Inp_RSI_Period = 14;
input bool Inp_UseVolumeSpike = false;
input double Inp_VolSpikeFactor = 1.5; // vs 20-bar average
// Risk management
input double Inp_RiskPercent = 1.0; // 1% per trade
input bool Inp_UseATRforSL = false;
input int Inp_ATR_Period = 14;
input double Inp_ATR_Mult = 1.5;
input double Inp_MinSLPoints = 200; // floor SL (points)
input double Inp_R_MultipleTP = 2.0; // fixed R:R=1:2
// Risk-free (optional)
input bool Inp_MoveToBEatTP1 = true;
input double Inp_TP1_R = 1.0; // move to BE at 1R
input double Inp_BE_OffsetPoints = 10; // lock-in small +offset
// Sessions
input bool Inp_UseSessionFilter = true;
input int Inp_LondonOpenHour = 8; // broker time
input int Inp_LondonCloseHour = 17;
input int Inp_NYOpenHour = 13;
input int Inp_NYCloseHour = 21;
input bool Inp_AllowNYOverlapOnly = false;
// Entry placement
input bool Inp_UseLimitAtZone = true; // limit order at minor zone
input int Inp_MaxSlippagePoints = 100;
input int Inp_MinRetestWickPoints = 30;
// Safety / engine
input int Inp_MinBarsLoaded = 600;
input int Inp_SignalCoolOffBars = 20; // avoid rapid re-entries
input bool Inp_OnePositionOnly = true;
//------------------------------- Structures -------------------------
struct Zone
{
bool isValid;
double priceLow;
double priceHigh;
int barIndex; // starting bar index of zone
bool isSupply; // true: resistance (HH), false: support (LL)
};
struct MinorZone
{
bool isValid;
double priceLow;
double priceHigh;
int barIndex;
bool isSupply; // same direction as major
};
datetime lastSignalTimeBuy = 0;
datetime lastSignalTimeSell = 0;
//
int atrHandler = INVALID_HANDLE;
//------------------------------- Helpers ----------------------------
int DigitsAdjust()
{
return (int)SymbolInfoInteger(Inp_Symbol, SYMBOL_DIGITS);
}
double PointAdjust()
{
return SymbolInfoDouble(Inp_Symbol, SYMBOL_POINT);
}
double TickValue()
{
double v;
SymbolInfoDouble(Inp_Symbol, SYMBOL_TRADE_TICK_VALUE, v);
return v;
}
double TickSize()
{
double s;
SymbolInfoDouble(Inp_Symbol, SYMBOL_TRADE_TICK_SIZE, s);
return s;
}
bool IsSessionAllowed()
{
if (!Inp_UseSessionFilter)
return true;
MqlDateTime t;
TimeToStruct(TimeCurrent(), t);
int hour = t.hour;
bool london = (hour >= Inp_LondonOpenHour && hour < Inp_LondonCloseHour);
bool ny = (hour >= Inp_NYOpenHour && hour < Inp_NYCloseHour);
if (Inp_AllowNYOverlapOnly)
return (london && ny);
return (london || ny);
}
bool EngulfingBearish(int shift)
{
double o0 = iOpen(Inp_Symbol, Inp_WorkTF, shift), c0 = iClose(Inp_Symbol, Inp_WorkTF, shift);
double o1 = iOpen(Inp_Symbol, Inp_WorkTF, shift + 1), c1 = iClose(Inp_Symbol, Inp_WorkTF, shift + 1);
return (c0 < o0 && c1 > o1 && o0 < c1 && c0 < o1 && (o0 - o1) > 0 && (c1 - c0) > 0 && (o1 < c0)); // rough engulfing
}
bool EngulfingBullish(int shift)
{
double o0 = iOpen(Inp_Symbol, Inp_WorkTF, shift), c0 = iClose(Inp_Symbol, Inp_WorkTF, shift);
double o1 = iOpen(Inp_Symbol, Inp_WorkTF, shift + 1), c1 = iClose(Inp_Symbol, Inp_WorkTF, shift + 1);
return (c0 > o0 && c1 < o1 && o0 > c1 && c0 > o1 && (o0 - o1) > 0 && (c0 - c1) > 0 && (o1 > c0)); // rough engulfing inverse
}
bool VolumeSpike(int shift)
{
if (!Inp_UseVolumeSpike)
return true;
double avg = 0;
int n = 20;
for (int i = shift + 1; i < shift + 1 + n; i++)
avg += (double)iVolume(Inp_Symbol, Inp_WorkTF, i);
avg /= n;
double v0 = (double)iVolume(Inp_Symbol, Inp_WorkTF, shift);
return (v0 >= avg * Inp_VolSpikeFactor);
}
bool HTFConfluence(bool wantSupply)
{
if (!Inp_UseHTFConfluence)
return true;
// Simple HTF direction: last HTF candle close vs open
double o = iOpen(Inp_Symbol, Inp_HTF, Inp_HTFShiftBars), c = iClose(Inp_Symbol, Inp_HTF, Inp_HTFShiftBars);
bool htfDown = (c < o), htfUp = (c > o);
return wantSupply ? htfDown : htfUp;
}
//------------------------------- Zone detection ---------------------
Zone FindMajorZone()
{
Zone z;
z.isValid = false;
z.isSupply = false;
z.priceLow = 0;
z.priceHigh = 0;
z.barIndex = -1;
int bars = iBars(Inp_Symbol, Inp_WorkTF);
if (bars < Inp_MinBarsLoaded)
return z;
// Highest high / lowest low over lookback
double hh = -DBL_MAX, ll = DBL_MAX;
int hhBar = -1, llBar = -1;
for (int i = 1; i <= Inp_MajorLookbackBars; i++)
{
double h = iHigh(Inp_Symbol, Inp_WorkTF, i), l = iLow(Inp_Symbol, Inp_WorkTF, i);
if (h > hh)
{
hh = h;
hhBar = i;
}
if (l < ll)
{
ll = l;
llBar = i;
}
}
// Decide which one is closest to current action: use most recent extreme
if (hhBar < llBar)
{
z.isSupply = true;
z.isValid = true;
z.barIndex = hhBar;
z.priceLow = hh - Inp_ZonePadPoints * PointAdjust();
z.priceHigh = hh + Inp_ZonePadPoints * PointAdjust();
}
else
{
z.isSupply = false;
z.isValid = true;
z.barIndex = llBar;
z.priceLow = ll - Inp_ZonePadPoints * PointAdjust();
z.priceHigh = ll + Inp_ZonePadPoints * PointAdjust();
}
return z;
}
MinorZone FindFirstMinorSameDirection(const Zone &major)
{
MinorZone mz;
mz.isValid = false;
mz.isSupply = major.isSupply;
mz.priceLow = 0;
mz.priceHigh = 0;
mz.barIndex = -1;
if (!major.isValid)
return mz;
// Scan forward from major's bar toward current for first reaction zone aligned with major
int start = major.barIndex - 1;
int end = MathMax(1, start - Inp_MinorWindowBars);
// Heuristic: supply minor = bearish impulse followed by base; demand minor = bullish impulse followed by base
for (int i = start; i >= end; i--)
{
double o = iOpen(Inp_Symbol, Inp_WorkTF, i), c = iClose(Inp_Symbol, Inp_WorkTF, i);
double h = iHigh(Inp_Symbol, Inp_WorkTF, i), l = iLow(Inp_Symbol, Inp_WorkTF, i);
bool bearImpulse = (c < o && (o - c) > (h - l) * 0.5);
bool bullImpulse = (c > o && (c - o) > (h - l) * 0.5);
if (major.isSupply && bearImpulse)
{
// Base zone from next candle tight range
double h1 = iHigh(Inp_Symbol, Inp_WorkTF, i - 1), l1 = iLow(Inp_Symbol, Inp_WorkTF, i - 1);
mz.isValid = true;
mz.barIndex = i - 1;
mz.priceLow = l1 - Inp_ZonePadPoints * PointAdjust();
mz.priceHigh = h1 + Inp_ZonePadPoints * PointAdjust();
break;
}
if (!major.isSupply && bullImpulse)
{
double h1 = iHigh(Inp_Symbol, Inp_WorkTF, i - 1), l1 = iLow(Inp_Symbol, Inp_WorkTF, i - 1);
mz.isValid = true;
mz.barIndex = i - 1;
mz.priceLow = l1 - Inp_ZonePadPoints * PointAdjust();
mz.priceHigh = h1 + Inp_ZonePadPoints * PointAdjust();
break;
}
}
return mz;
}
//------------------------------- Signal logic -----------------------
bool PriceRetestedZone(const MinorZone &mz, bool supply, int shift = 0)
{
if (!mz.isValid)
return false;
double high = iHigh(Inp_Symbol, Inp_WorkTF, shift), low = iLow(Inp_Symbol, Inp_WorkTF, shift);
// For supply: retest when high touches zone; for demand: retest when low touches zone
if (supply)
return (high >= mz.priceLow && high <= mz.priceHigh && (high - iClose(Inp_Symbol, Inp_WorkTF, shift)) * 1.0 / PointAdjust() >= Inp_MinRetestWickPoints);
else
return (low <= mz.priceHigh && low >= mz.priceLow && (iClose(Inp_Symbol, Inp_WorkTF, shift) - low) * 1.0 / PointAdjust() >= Inp_MinRetestWickPoints);
}
bool ConfirmAtZone(bool supply)
{
int shift = 0;
if (Inp_UseEngulfingConfirm)
{
if (supply)
{
if (!EngulfingBearish(shift))
return false;
}
else
{
if (!EngulfingBullish(shift))
return false;
}
}
if (!VolumeSpike(shift))
return false;
if (!HTFConfluence(supply))
return false;
// Optional: RSI divergence could be added here if enabled.
return true;
}
//------------------------------- Risk & orders -----------------------
double CalcPositionSize(double sl_points)
{
double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * (Inp_RiskPercent / 100.0);
double tickValue = TickValue();
double tickSize = TickSize();
// Convert SL points to quoted ticks
double ticks = sl_points * PointAdjust() / tickSize;
if (ticks <= 0.0)
return 0.0;
double lots = riskMoney / (ticks * tickValue);
// Normalize to symbol step
double minLot = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_MIN);
double lotStep = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_STEP);
double maxLot = SymbolInfoDouble(Inp_Symbol, SYMBOL_VOLUME_MAX);
lots = MathFloor(lots / lotStep) * lotStep;
lots = MathMax(minLot, MathMin(lots, maxLot));
return lots;
}
bool PlaceEntry(const MinorZone &mz, bool supply)
{
double bid = SymbolInfoDouble(Inp_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(Inp_Symbol, SYMBOL_ASK);
double point = PointAdjust();
// SL beneath/above minor zone (or ATR-based)
double sl, entry, tp;
double sl_points;
if (supply)
{
entry = Inp_UseLimitAtZone ? mz.priceLow : bid; // sell near zone top/low
double baseSL = mz.priceHigh + Inp_ZonePadPoints * point;
if (Inp_UseATRforSL)
{
//
double atrs[];
CopyBuffer(atrHandler, MAIN_LINE, 0, 1, atrs);
double atr = atrs[0];
baseSL = MathMax(baseSL, entry + (atr * Inp_ATR_Mult));
}
sl = baseSL;
sl_points = (sl - entry) / point;
sl_points = MathMax(sl_points, Inp_MinSLPoints);
tp = entry - (sl_points * point * Inp_R_MultipleTP);
// Position sizing
double lots = CalcPositionSize(sl_points);
if (lots <= 0)
return false;
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
req.action = TRADE_ACTION_DEAL;
req.symbol = Inp_Symbol;
req.type = ORDER_TYPE_SELL;
req.volume = lots;
req.price = Inp_UseLimitAtZone ? entry : bid;
req.sl = sl;
req.tp = tp;
req.deviation = Inp_MaxSlippagePoints;
bool ok = OrderSend(req, res);
if (ok)
{
lastSignalTimeSell = TimeCurrent();
}
return ok;
}
else
{
entry = Inp_UseLimitAtZone ? mz.priceHigh : ask; // buy near zone top/high
double baseSL = mz.priceLow - Inp_ZonePadPoints * point;
if (Inp_UseATRforSL)
{
//
double atrs[];
CopyBuffer(atrHandler, MAIN_LINE, 0, 1, atrs);
double atr = atrs[0];
baseSL = MathMin(baseSL, entry - (atr * Inp_ATR_Mult));
}
sl = baseSL;
sl_points = (entry - sl) / point;
sl_points = MathMax(sl_points, Inp_MinSLPoints);
tp = entry + (sl_points * point * Inp_R_MultipleTP);
double lots = CalcPositionSize(sl_points);
if (lots <= 0)
return false;
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
req.action = TRADE_ACTION_DEAL;
req.symbol = Inp_Symbol;
req.type = ORDER_TYPE_BUY;
req.volume = lots;
req.price = Inp_UseLimitAtZone ? entry : ask;
req.sl = sl;
req.tp = tp;
req.deviation = Inp_MaxSlippagePoints;
bool ok = OrderSend(req, res);
if (ok)
{
lastSignalTimeBuy = TimeCurrent();
}
return ok;
}
}
//------------------------------- Position management ----------------
void ManageOpenPositions()
{
int total = PositionsTotal();
double point = PointAdjust();
for (int i = 0; i < total; i++)
{
string sym = PositionGetSymbol(i);
if (sym != Inp_Symbol)
continue;
if (!PositionSelect(sym))
continue;
long type = (long)PositionGetInteger(POSITION_TYPE);
double price = PositionGetDouble(POSITION_PRICE_OPEN);
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
double current = (type == POSITION_TYPE_BUY) ? SymbolInfoDouble(sym, SYMBOL_BID) : SymbolInfoDouble(sym, SYMBOL_ASK);
// Risk-free move to BE at TP1 (= 1R)
if (Inp_MoveToBEatTP1 && tp > 0 && sl > 0)
{
double rDist = MathAbs(tp - price) / Inp_R_MultipleTP;
bool hitTP1 = (type == POSITION_TYPE_BUY ? (current >= price + rDist) : (current <= price - rDist));
if (hitTP1)
{
double newSL = (type == POSITION_TYPE_BUY ? price + Inp_BE_OffsetPoints * point : price - Inp_BE_OffsetPoints * point);
if ((type == POSITION_TYPE_BUY && newSL > sl) || (type == POSITION_TYPE_SELL && newSL < sl))
{
MqlTradeRequest req;
MqlTradeResult res;
ZeroMemory(req);
ZeroMemory(res);
req.action = TRADE_ACTION_SLTP;
req.symbol = sym;
req.position = (ulong)PositionGetInteger(POSITION_TICKET);
req.sl = newSL;
req.tp = tp;
OrderSend(req, res);
}
}
}
}
}
//------------------------------- Engine ------------------------------
bool CoolOffOk(bool supply)
{
datetime last = supply ? lastSignalTimeSell : lastSignalTimeBuy;
if (last == 0)
return true;
// Convert bars to seconds approximate using last M15 duration
int seconds = Inp_SignalCoolOffBars * 15 * 60;
return (TimeCurrent() - last) >= seconds;
}
void TrySignal()
{
if (!IsSessionAllowed())
return;
Zone major = FindMajorZone();
if (!major.isValid)
return;
MinorZone minor = FindFirstMinorSameDirection(major);
if (!minor.isValid)
return;
// Only act on retest + confirmation
bool retest = PriceRetestedZone(minor, major.isSupply, 0);
if (!retest)
return;
if (!ConfirmAtZone(major.isSupply))
return;
if (Inp_OnePositionOnly && PositionsTotal() > 0)
return;
if (!CoolOffOk(major.isSupply))
return;
PlaceEntry(minor, major.isSupply);
}
//------------------------------- Standard events --------------------
int OnInit()
{
//
if (Symbol() != Inp_Symbol)
{
SymbolSelect(Inp_Symbol, true);
}
//
atrHandler = iATR(Inp_Symbol, Inp_WorkTF, Inp_ATR_Period);
return (INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
void OnTick()
{
static datetime lastBarTime = 0;
MqlRates rates[];
int copied = CopyRates(Inp_Symbol, Inp_WorkTF, 0, Inp_MinBarsLoaded, rates);
if (copied < Inp_MinBarsLoaded)
return;
datetime curBarTime = rates[0].time;
if (curBarTime != lastBarTime)
{
// New bar on M15: evaluate signal
TrySignal();
lastBarTime = curBarTime;
}
// Manage open positions continuously
ManageOpenPositions();
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,288 @@
//+------------------------------------------------------------------+
//| ZigzagColor.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
#property indicator_type1 DRAW_COLOR_ZIGZAG
#property indicator_width1 3
#property indicator_color1 clrAqua, clrMagenta
//--- input parameters
input int InpDepth =12; // Depth
input int InpDeviation=5; // Deviation
input int InpBackstep =3; // Back Step
//--- indicator buffers
double ZigzagPeakBuffer[];
double ZigzagBottomBuffer[];
double HighMapBuffer[];
double LowMapBuffer[];
double ColorBuffer[];
int ExtRecalc=3; // recounting's depth
enum EnSearchMode
{
Extremum=0, // searching for the first extremum
Peak=1, // searching for the next ZigZag peak
Bottom=-1 // searching for the next ZigZag bottom
};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ZigzagPeakBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ZigzagBottomBuffer,INDICATOR_DATA);
SetIndexBuffer(2,ColorBuffer,INDICATOR_COLOR_INDEX);
SetIndexBuffer(3,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(4,LowMapBuffer,INDICATOR_CALCULATIONS);
//--- set accuracy
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- name for DataWindow and indicator subwindow label
string short_name=StringFormat("ZigZagColor(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
PlotIndexSetString(0,PLOT_LABEL,short_name);
//--- set an empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
}
//+------------------------------------------------------------------+
//| ZigZag calculation |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total<100)
return(0);
//---
int i,start=0;
int extreme_counter=0,extreme_search=Extremum;
int shift,back=0,last_high_pos=0,last_low_pos=0;
double val=0,res=0;
double cur_low=0,cur_high=0,last_high=0,last_low=0;
//--- initializing
if(prev_calculated==0)
{
ArrayInitialize(ZigzagPeakBuffer,0.0);
ArrayInitialize(ZigzagBottomBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
//--- start calculation from bar number InpDepth
start=InpDepth-1;
}
//--- ZigZag was already calculated before
if(prev_calculated>0)
{
i=rates_total-1;
//--- searching for the third extremum from the last uncompleted bar
while(extreme_counter<ExtRecalc && i>rates_total -100)
{
res=(ZigzagPeakBuffer[i]+ZigzagBottomBuffer[i]);
//---
if(res!=0)
extreme_counter++;
i--;
}
i++;
start=i;
//--- what type of exremum we search for
if(LowMapBuffer[i]!=0)
{
cur_low=LowMapBuffer[i];
extreme_search=Peak;
}
else
{
cur_high=HighMapBuffer[i];
extreme_search=Bottom;
}
//--- clear indicator values
for(i=start+1; i<rates_total && !IsStopped(); i++)
{
ZigzagPeakBuffer[i] =0.0;
ZigzagBottomBuffer[i]=0.0;
LowMapBuffer[i] =0.0;
HighMapBuffer[i] =0.0;
}
}
//--- searching for high and low extremes
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
//--- low
val=Lowest(low,InpDepth,shift);
if(val==last_low)
val=0.0;
else
{
last_low=val;
if((low[shift]-val)>(InpDeviation*_Point))
val=0.0;
else
{
for(back=InpBackstep; back>=1; back--)
{
res=LowMapBuffer[shift-back];
//---
if((res!=0) && (res>val))
LowMapBuffer[shift-back]=0.0;
}
}
}
if(low[shift]==val)
LowMapBuffer[shift]=val;
else
LowMapBuffer[shift]=0.0;
//--- high
val=Highest(high,InpDepth,shift);
if(val==last_high)
val=0.0;
else
{
last_high=val;
if((val-high[shift])>(InpDeviation*_Point))
val=0.0;
else
{
for(back=InpBackstep; back>=1; back--)
{
res=HighMapBuffer[shift-back];
//---
if((res!=0) && (res<val))
HighMapBuffer[shift-back]=0.0;
}
}
}
if(high[shift]==val)
HighMapBuffer[shift]=val;
else
HighMapBuffer[shift]=0.0;
}
//--- set last values
if(extreme_search==0) // undefined values
{
last_low=0;
last_high=0;
}
else
{
last_low=cur_low;
last_high=cur_high;
}
//--- final selection of extreme points for ZigZag
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
res=0.0;
switch(extreme_search)
{
case Extremum:
if(last_low==0 && last_high==0)
{
if(HighMapBuffer[shift]!=0)
{
last_high=high[shift];
last_high_pos=shift;
extreme_search=-1;
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
res=1;
}
if(LowMapBuffer[shift]!=0)
{
last_low=low[shift];
last_low_pos=shift;
extreme_search=1;
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
res=1;
}
}
break;
case Peak:
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low &&
HighMapBuffer[shift]==0.0)
{
ZigzagBottomBuffer[last_low_pos]=0.0;
last_low_pos=shift;
last_low=LowMapBuffer[shift];
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
last_high=HighMapBuffer[shift];
last_high_pos=shift;
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
extreme_search=Bottom;
res=1;
}
break;
case Bottom:
if(HighMapBuffer[shift]!=0.0 &&
HighMapBuffer[shift]>last_high &&
LowMapBuffer[shift]==0.0)
{
ZigzagPeakBuffer[last_high_pos]=0.0;
last_high_pos=shift;
last_high=HighMapBuffer[shift];
ZigzagPeakBuffer[shift]=last_high;
ColorBuffer[shift]=0;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
last_low=LowMapBuffer[shift];
last_low_pos=shift;
ZigzagBottomBuffer[shift]=last_low;
ColorBuffer[shift]=1;
extreme_search=Peak;
}
break;
default:
return(rates_total);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Get highest value for range |
//+------------------------------------------------------------------+
double Highest(const double&array[],int count,int start)
{
double res=array[start];
//---
for(int i=start-1; i>start-count && i>=0; i--)
if(res<array[i])
res=array[i];
//---
return(res);
}
//+------------------------------------------------------------------+
//| Get lowest value for range |
//+------------------------------------------------------------------+
double Lowest(const double&array[],int count,int start)
{
double res=array[start];
//---
for(int i=start-1; i>start-count && i>=0; i--)
if(res>array[i])
res=array[i];
//---
return(res);
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,383 @@
//+------------------------------------------------------------------+
//| ZigZag Analyzer.mq5|
//| Copyright 2025, MetaQuotes Ltd.|
//| https://www.mql5.com/en/users/lynnchris|
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com/en/users/lynnchris"
#property version "1.0"
#property strict
//
#include "../Libraries/x-saherelm.common.lib.mq5"
// Input parameters
input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT; // Timeframe to analyze
input int ZZ_Depth = 12; // ZigZag depth
input int ZZ_Deviation = 5; // ZigZag deviation
input int ZZ_Backstep = 3; // ZigZag backstep
input int LookBackBars = 500; // Bars to search for pivots
input int ExtendFutureBars = 100; // Bars to extend trendlines into the future
// Global indicator handle for ZigZag
int zzHandle;
// Arrays for ZigZag data and pivot storage
double zzBuffer[];
bool pivotIsPeak[];
double pivotPrices[];
datetime pivotTimes[];
// Variable to detect new bars
datetime lastBarTime = 0;
//+------------------------------------------------------------------+
//| Initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//
zzHandle = iCustom(
_Symbol,
InpTimeFrame,
"x-saherelm.xzg",
"",
ZZ_Depth,
ZZ_Deviation,
ZZ_Backstep,
X_PRICE_HIGH,
X_PRICE_LOW,
"",
false,
false,
true,
159,
159 //
);
if (zzHandle == INVALID_HANDLE)
{
Print("Error creating ZigZag handle");
return (INIT_FAILED);
}
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete(0, "Downtrend_HighLine");
ObjectDelete(0, "Downtrend_LowLine");
ObjectDelete(0, "Major_Resistance");
ObjectDelete(0, "Major_Support");
ObjectDelete(0, "Minor_Resistance");
ObjectDelete(0, "Minor_Support");
IndicatorRelease(zzHandle);
}
//+------------------------------------------------------------------+
//| Tick function |
//+------------------------------------------------------------------+
void OnTick()
{
datetime currentBarTime = iTime(_Symbol, InpTimeFrame, 0);
if (currentBarTime == lastBarTime)
return;
lastBarTime = currentBarTime;
// Remove previous objects
ObjectDelete(0, "Downtrend_HighLine");
ObjectDelete(0, "Downtrend_LowLine");
ObjectDelete(0, "Major_Resistance");
ObjectDelete(0, "Major_Support");
ObjectDelete(0, "Minor_Resistance");
ObjectDelete(0, "Minor_Support");
if (CopyBuffer(zzHandle, 0, 0, LookBackBars, zzBuffer) <= 0)
{
Print("Failed to copy ZigZag data");
return;
}
ArraySetAsSeries(zzBuffer, true);
DrawZigZagTrendlines();
DrawSupportResistance();
}
//+------------------------------------------------------------------+
//| Draw ZigZag-based Trendlines |
//+------------------------------------------------------------------+
void DrawZigZagTrendlines()
{
double highPrices[10], lowPrices[10];
datetime highTimes[10], lowTimes[10];
int highCount = 0, lowCount = 0;
// Extract swing points from the ZigZag buffer
for (int i = 0; i < LookBackBars - 1; i++)
{
if (zzBuffer[i] != 0)
{
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && highCount < 10)
{
highPrices[highCount] = zzBuffer[i];
highTimes[highCount] = iTime(_Symbol, InpTimeFrame, i);
highCount++;
}
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && lowCount < 10)
{
lowPrices[lowCount] = zzBuffer[i];
lowTimes[lowCount] = iTime(_Symbol, InpTimeFrame, i);
lowCount++;
}
}
}
// Exclude the most recent swing if possible
int usedHighCount = (highCount >= 4) ? highCount - 1 : highCount;
int usedLowCount = (lowCount >= 4) ? lowCount - 1 : lowCount;
double mHigh = 0, bHigh = 0, mLow = 0, bLow = 0;
bool validHigh = false, validLow = false;
// Regression for highs
if (usedHighCount >= 3)
{
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
for (int i = 0; i < usedHighCount; i++)
{
double t = (double)highTimes[i];
double p = highPrices[i];
sumT += t;
sumP += p;
sumTP += t * p;
sumT2 += t * t;
}
int N = usedHighCount;
double denominator = N * sumT2 - sumT * sumT;
if (denominator != 0)
{
mHigh = (N * sumTP - sumT * sumP) / denominator;
bHigh = (sumP - mHigh * sumT) / N;
}
else
bHigh = sumP / N;
validHigh = true;
}
// Regression for lows
if (usedLowCount >= 3)
{
double sumT = 0, sumP = 0, sumTP = 0, sumT2 = 0;
for (int i = 0; i < usedLowCount; i++)
{
double t = (double)lowTimes[i];
double p = lowPrices[i];
sumT += t;
sumP += p;
sumTP += t * p;
sumT2 += t * t;
}
int N = usedLowCount;
double denominator = N * sumT2 - sumT * sumT;
if (denominator != 0)
{
mLow = (N * sumTP - sumT * sumP) / denominator;
bLow = (sumP - mLow * sumT) / N;
}
else
bLow = sumP / N;
validLow = true;
}
// Define time limits for trendlines
datetime pastTime = iTime(_Symbol, InpTimeFrame, LookBackBars - 1);
datetime futureTime = lastBarTime + ExtendFutureBars * PeriodSeconds();
// Draw trendlines if both regressions are valid
if (validHigh && validLow)
{
// When slopes have the same sign, use average slope
if (mHigh * mLow > 0)
{
double mParallel = (mHigh + mLow) / 2.0;
double bHighParallel = highPrices[0] - mParallel * (double)highTimes[0];
double bLowParallel = lowPrices[0] - mParallel * (double)lowTimes[0];
datetime highStartTime = pastTime;
double highStartPrice = mParallel * (double)highStartTime + bHighParallel;
double highEndPrice = mParallel * (double)futureTime + bHighParallel;
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
Print("Failed to create High Trendline");
else
{
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
}
datetime lowStartTime = pastTime;
double lowStartPrice = mParallel * (double)lowStartTime + bLowParallel;
double lowEndPrice = mParallel * (double)futureTime + bLowParallel;
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
Print("Failed to create Low Trendline");
else
{
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
}
}
else
{
datetime highStartTime = pastTime;
double highStartPrice = mHigh * (double)highStartTime + bHigh;
double highEndPrice = mHigh * (double)futureTime + bHigh;
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
Print("Failed to create High Trendline");
else
{
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
}
datetime lowStartTime = pastTime;
double lowStartPrice = mLow * (double)lowStartTime + bLow;
double lowEndPrice = mLow * (double)futureTime + bLow;
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
Print("Failed to create Low Trendline");
else
{
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
}
}
}
else
{
if (validHigh)
{
datetime highStartTime = pastTime;
double highStartPrice = mHigh * (double)highStartTime + bHigh;
double highEndPrice = mHigh * (double)futureTime + bHigh;
if (!ObjectCreate(0, "Downtrend_HighLine", OBJ_TREND, 0, highStartTime, highStartPrice, futureTime, highEndPrice))
Print("Failed to create High Trendline");
else
{
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_HighLine", OBJPROP_RAY_RIGHT, true);
}
}
if (validLow)
{
datetime lowStartTime = pastTime;
double lowStartPrice = mLow * (double)lowStartTime + bLow;
double lowEndPrice = mLow * (double)futureTime + bLow;
if (!ObjectCreate(0, "Downtrend_LowLine", OBJ_TREND, 0, lowStartTime, lowStartPrice, futureTime, lowEndPrice))
Print("Failed to create Low Trendline");
else
{
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_COLOR, clrGreen);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_LEFT, true);
ObjectSetInteger(0, "Downtrend_LowLine", OBJPROP_RAY_RIGHT, true);
}
}
}
}
//+------------------------------------------------------------------+
//| Draw Support and Resistance Levels |
//+------------------------------------------------------------------+
void DrawSupportResistance()
{
double confirmedHighs[10], confirmedLows[10];
int confHighCount = 0, confLowCount = 0;
for (int i = 0; i < LookBackBars - 1; i++)
{
if (zzBuffer[i] != 0)
{
if (iHigh(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confHighCount < 10)
{
confirmedHighs[confHighCount] = zzBuffer[i];
confHighCount++;
}
else if (iLow(_Symbol, InpTimeFrame, i) == zzBuffer[i] && confLowCount < 10)
{
confirmedLows[confLowCount] = zzBuffer[i];
confLowCount++;
}
}
}
int usedHighCount = (confHighCount >= 4) ? confHighCount - 1 : confHighCount;
int usedLowCount = (confLowCount >= 4) ? confLowCount - 1 : confLowCount;
double majorResistance = -1e9, majorSupport = 1e9;
double minorResistance = -1e9, minorSupport = 1e9;
double tempHigh = -1e9, tempLow = -1e9;
for (int i = 0; i < usedHighCount; i++)
{
if (confirmedHighs[i] > majorResistance)
{
tempHigh = majorResistance;
majorResistance = confirmedHighs[i];
}
else if (confirmedHighs[i] > tempHigh)
{
tempHigh = confirmedHighs[i];
}
}
if (tempHigh > -1e9)
minorResistance = tempHigh;
for (int i = 0; i < usedLowCount; i++)
{
if (confirmedLows[i] < majorSupport)
{
tempLow = majorSupport;
majorSupport = confirmedLows[i];
}
else if (confirmedLows[i] < tempLow)
{
tempLow = confirmedLows[i];
}
}
if (tempLow < 1e9)
minorSupport = tempLow;
if (usedHighCount > 0)
{
if (!ObjectCreate(0, "Major_Resistance", OBJ_HLINE, 0, 0, majorResistance))
Print("Failed to create Major Resistance");
else
ObjectSetInteger(0, "Major_Resistance", OBJPROP_COLOR, clrMagenta);
if (minorResistance > -1e9 && minorResistance < majorResistance)
{
if (!ObjectCreate(0, "Minor_Resistance", OBJ_HLINE, 0, 0, minorResistance))
Print("Failed to create Minor Resistance");
else
ObjectSetInteger(0, "Minor_Resistance", OBJPROP_COLOR, clrFuchsia);
}
}
if (usedLowCount > 0)
{
if (!ObjectCreate(0, "Major_Support", OBJ_HLINE, 0, 0, majorSupport))
Print("Failed to create Major Support");
else
ObjectSetInteger(0, "Major_Support", OBJPROP_COLOR, clrAqua);
if (minorSupport < 1e9 && minorSupport > majorSupport)
{
if (!ObjectCreate(0, "Minor_Support", OBJ_HLINE, 0, 0, minorSupport))
Print("Failed to create Minor Support");
else
ObjectSetInteger(0, "Minor_Support", OBJPROP_COLOR, clrBlue);
}
}
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,208 @@
//
// Draw Market Analysis ...
// has = iStructure.pvAnalysis.IsValid();
// if (has)
// {
// //
// XBoxZone iBox;
// XCBoxObject *iBoxObj;
//
// poiDrawer.RemoveDraws();
// //
// has = iStructure.pvAnalysis.HasSupportBox(iBox);
// if (has)
// {
// //
// iBox.to = iBar.time;
// poiDrawer.DrawBox(
// iBox,
// iBoxObj,
// true,
// iBox.type //
// );
// }
// //
// ZeroMemory(iBoxObj);
// has = iStructure.pvAnalysis.HasResistanceBox(iBox);
// if (has)
// {
// //
// iBox.to = iBar.time;
// poiDrawer.DrawBox(
// iBox,
// iBoxObj,
// true,
// iBox.type //
// );
// }
// }
// //
// // Draw Zones ...
// has = HasChild(iStructure.supports);
// if (has) {
// //
// CArrayObj *iSupportObjs;
// poiDrawer.DrawBoxes(
// iStructure.supports,
// iSupportObjs,
// true //
// );
// }
// //
// has = HasChild(iStructure.resistances);
// if (has) {
// //
// CArrayObj *iResistanceObjs;
// poiDrawer.DrawBoxes(
// iStructure.resistances,
// iResistanceObjs,
// true //
// );
// }
//
// Detecte Fibo Section Changes ...
// //
// has = fimaHelper.IsFiboSectionChanged(iDir, iBar.Index());
// has = has &&
// IsXBullish(iDir) &&
// fimaHelper.IsValeOverLast(iBar.Index());
// //
// has = fimaHelper.IsFiboSectionChanged(iDir, iBar.Index());
// has = has &&
// IsXBearish(iDir) &&
// fimaHelper.IsPeakUnderLast(iBar.Index());
// //
// has = fimaHelper.HasFiboPush(iDir, iBar.Index(), 5);
// //
// XBoxZone fimaZones[];
// int fimaZonesCount = fimaHelper.DetectXFIMAZones(
// fimaZones,
// iBar.Index(),
// true, // Only Valid Zones ...
// 50, // Number of Zones ...
// 4, // Shadow Multiplier ...
// 1, // Strength ...
// 7, // Validation Length ...
// 500 // Loopback ..
// );
//
// XPivot fimaPivots[];
// int fimaPivotsCount = fimaHelper.DetecteXFIMAPivots(
// fimaPivots,
// iBar.Index(),
// 50, // Number of Pivots ...
// 7, // Validation Length ...
// 500 // Loopback ...
// );
// //
// has = IsValidSize(fimaZonesCount);
// if (has)
// {
// //
// // Draw Detected Zones ...
// for (int i = 0; i < fimaZonesCount; i++)
// {
// //
// XCBoxObject *iObj;
// has = poiDrawer.DrawBox(
// fimaZones[i],
// iObj,
// true, // Ignore At ...
// fimaZones[i].type // Specified Name ...
// );
// if (has)
// {
// zoneObjects.Add(iObj);
// }
// }
// }
// //
// has = IsValidSize(fimaPivotsCount);
// if (has)
// {
// //
// // Draw Detected Pivots ...
// for (int i = 0; i < fimaPivotsCount; i++)
// {
// //
// XCBarArrowObject *iObj;
// has = poiDrawer.DrawPivot(
// fimaPivots[i],
// iObj);
// if (has)
// {
// pivotObjects.Add(iObj);
// }
// }
// }
//
// Detect DecisionBars ...
// XOHCL decisionBars[];
// int decisionBarsCount = 0;
// ENUM_X_DIRECTION decisionBarDirs[];
// decisionBarsCount = fimaHelper.DetectXFIMAPOIBars(
// decisionBars,
// decisionBarDirs,
// iBar.Index(),
// X_DIRECTION_ALL, // For Dir ...
// 300 // Required Number of Bars ...
// );
// decisionBarsCount = fimaHelper.DetectXFIMAReversalPOIBars(
// decisionBars,
// decisionBarDirs,
// iBar.Index(),
// true, // Force Touch Boundary ...
// X_DIRECTION_ALL, // For Dir ...
// 300 // Required Number of Bars ...
// );
// decisionBarsCount = fimaHelper.DetectXFIMAContinuationalPOIBars(
// decisionBars,
// decisionBarDirs,
// iBar.Index(),
// true,
// X_DIRECTION_ALL, // For Dir ...
// 300 // Required Number of Bars ...
// );
// //
// has = IsValidSize(decisionBarsCount);
// if (has)
// {
// //
// for (int i = 0; i < decisionBarsCount; i++)
// {
// //
// XCBarArrowObject *iObj;
// has = poiDrawer.DrawBarArrow(
// decisionBars[i],
// iObj,
// IsXBullish(decisionBarDirs[i]) ? X_PRICE_LOW : X_PRICE_HIGH,
// 159,
// IsXBullish(decisionBarDirs[i]) ? clrAqua : clrMagenta,
// 5,
// IsXBullish(decisionBarDirs[i]) ? ANCHOR_TOP : ANCHOR_BOTTOM,
// "XOHCL_" + ToXString(TimeToSeconds(decisionBars[i].time)),
// true, // Ignore Bar Tag ...
// 5 // Threshold ...
// );
// if (has)
// {
// barObjects.Add(iObj);
// }
// }
// }
@@ -0,0 +1,76 @@
if (result)
{
//
XOHCL tmpBar;
int tmpIDX = -1;
bool has = false;
double upper = 0;
double lower = 0;
int length = zone.GetAge();
//
// Support ...
tmpIDX = bar.FindLowestIndex(length, MODE_LOW);
if (IsValidIndex(tmpIDX))
{
//
if (tmpBar.Init(symbol, period, tmpIDX))
{
//
lower = iLow(symbol, period, tmpIDX);
upper = bar.FindLowest(length, MODE_CLOSE);
if (upper <= lower)
{
upper = tmpBar.GetDown();
}
//
has = support.Init(
symbol,
period,
upper,
lower,
tmpBar.time,
bar.time,
X_DIRECTION_BULLISH,
ToXString(X_BAR_PATTERN_SUPPORT) //
);
//
tmpBar.Clean();
}
}
//
// Resistance ...
tmpIDX = bar.FindHighestIndex(length, MODE_HIGH);
if (IsValidIndex(tmpIDX))
{
//
if (tmpBar.Init(symbol, period, tmpIDX))
{
//
upper = iHigh(symbol, period, tmpIDX);
lower = bar.FindHighest(length, MODE_CLOSE);
if (upper <= lower)
{
upper = tmpBar.GetUp();
}
//
has = resistance.Init(
symbol,
period,
upper,
lower,
tmpBar.time,
bar.time,
X_DIRECTION_BEARISH,
ToXString(X_BAR_PATTERN_RESISTANCE) //
);
//
tmpBar.Clean();
}
}
}
@@ -0,0 +1,765 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: XFIMAPV
// Description: Integrates All Requirements inside
// this indicator for analyse Markets Based on OM1 ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMA Indicator"
#property icon "../Images/SaherElm_Logo_Color.ico"
#property strict
//
// Definitions ...
//
#define ShortName "XFIMA"
//
// Imports ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// Inputs ...
//
// Calculation ...
input group "Calculation";
input int pvValidationLength = 7; // Peaks and Vales Validation Length
input int pvValidationCount = 2; // Recent Peak or Vale must under/over latests
input ENUM_X_PRICE peakPriceType = X_PRICE_HIGH; // Peak Calculated Price
input ENUM_X_PRICE valePriceType = X_PRICE_LOW; // Vale Calculated Price
//
// Presentation ...
input group "Presentation";
input bool showPV = true; // Show Peaks and Vales
input bool showHL = true; // Show Highs and Lows
input int startCalculationForLastBars = 1500; // Calculate Last n Bars
input int peakArrowCode = 159; // Peaks Arrow Code
input int highArrowCode = 159; // Highs Arrow Code
input int valeArrowCode = 159; // Vales Arrow Code
input int lowArrowCode = 159; // Lows Arrow Code
//
// Non Inputs ...
//
#define hideColorIDX 0
#define bullishColorIDX 1
#define bearishColorIDX 2
#define neuturalColorIDX 3
//
#define bullishState 1
#define neuturalState 0
#define bearishState -1
//
#define emptyValue 0.0
//
// Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 6
#property indicator_plots 4
//
// Plot Buffers ...
//
// PEAKS ...
//
#define peakBufferIndex 0
double peakBuffer[];
//
#define peakBufferPlotIndex 0
#property indicator_label1 "PEAK"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrMagenta
#property indicator_width1 3
//
// VALES ...
//
#define valeBufferIndex 1
double valeBuffer[];
//
#define valeBufferPlotIndex 1
#property indicator_label2 "VALE"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrAqua
#property indicator_width2 3
//
// HIGHS ...
//
#define highBufferIndex 2
double highBuffer[];
//
#define highBufferPlotIndex 2
#property indicator_label3 "HIGH"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrOrangeRed
#property indicator_width3 3
//
// LOWS ...
//
#define lowBufferIndex 3
double lowBuffer[];
//
#define lowBufferPlotIndex 3
#property indicator_label4 "LOW"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrYellow
#property indicator_width4 3
//
// Data Buffers ...
//
#define mLastBufferIndex 3
//
#define highRawBufferIndex mLastBufferIndex + 1
double highRawBuffer[];
//
#define lowRawBufferIndex mLastBufferIndex + 2
double lowRawBuffer[];
//
// Variables ...
//
int limit;
//
int maxLength;
//
int firstBarIndex;
//
// Event Handlers ...
/**
* Initialize Indicator ...
*
* @return ( int )
*/
int OnInit()
{
//
bool has = false;
//
// Validate Inputs ...
has = ValidateInputs();
if (!has)
{
return INIT_PARAMETERS_INCORRECT;
}
//
// because in some cases we may have more than one input for
// calculation and we must prevent any calculation
// untill we pass the biggest input length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Initial Requirements ...
has = InitRequirements();
if (!has)
{
return INIT_FAILED;
}
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Init Succeed ...
return INIT_SUCCEEDED;
//
}
/**
* De Initialize Indicator ...
*
* @param reason: Integer, De Initialization Reason ...
*/
void OnDeinit(const int reason)
{
//
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
// REASON_REMOVE 1 Program removed from a chart
// REASON_RECOMPILE 2 Program recompiled
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
// REASON_CHARTCLOSE 4 Chart closed
// REASON_PARAMETERS 5 Inputs changed by a user
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
// REASON_TEMPLATE 7 Another chart template applied
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
// REASON_CLOSE 9 Terminal closed
//
// De Initialize all Handlers and etc ...
}
/**
* Calculate Bars ...
*
* @param rates_total: Integer, Total Bars on Chart ...
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
* @param time: DateTime Array, History of Open Time ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param low: Double Array, History of Low Prices ...
* @param close: Double Array, History of Close Prices ...
* @param tick_volume: Long, History of Tick Volumes on Bar ...
* @param volume: Long, History of Trade Volumes ...
* @param spread: Double, History of Spread Price ...
*
* @return ( int )
*/
int OnCalculate(
const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[] //
)
{
//
// Prepare Buffers ...
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
//
// Validate Calculated Bars ...
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total
: (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
CalculateBuffers(
i,
prev_calculated,
rates_total,
//
open,
high,
close,
low,
tick_volume //
);
}
//
return rates_total;
}
//
// Custom Functions ...
/**
* Set Indicator Short Name and also we can define Buffers Labels ...
*/
void SetIndicatorName()
{
//
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
/**
* Validate Input Args for Initialization ...
*
* @return ( bool )
*/
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
IsXValid(peakPriceType) &&
IsXValid(valePriceType) &&
NotEmptyZero(pvValidationLength)
//
;
//
return result;
}
/**
* Extract Max Length of Inputs ...
*
* @return ( int )
*/
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(result, pvValidationLength);
//
return result;
}
/**
* Define Required Buffers ...
*/
void DefineBuffers()
{
//
// Plot Buffers ...
//
// PV ...
//
ENUM_DRAW_TYPE pvDrawType = showPV ? DRAW_ARROW : DRAW_NONE;
//
// PEAK ...
//
ArraySetAsSeries(peakBuffer, true);
SetIndexBuffer(peakBufferIndex, peakBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_SHOW_DATA, showPV);
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType);
//
PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode);
//
// VALE ...
//
ArraySetAsSeries(valeBuffer, true);
SetIndexBuffer(valeBufferIndex, valeBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_SHOW_DATA, showPV);
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType);
//
PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode);
//
// HL ...
//
ENUM_DRAW_TYPE hlDrawType = showHL ? DRAW_ARROW : DRAW_NONE;
//
// HIGH ...
//
ArraySetAsSeries(highBuffer, true);
SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(highBufferPlotIndex, PLOT_SHOW_DATA, showHL);
PlotIndexSetInteger(highBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType);
//
PlotIndexSetDouble(highBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(highBufferPlotIndex, PLOT_ARROW, highArrowCode);
//
// LOW ...
//
ArraySetAsSeries(lowBuffer, true);
SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_SHOW_DATA, showHL);
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType);
//
PlotIndexSetDouble(lowBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetInteger(lowBufferPlotIndex, PLOT_ARROW, lowArrowCode);
//
// Data Buffers ...
//
ArraySetAsSeries(lowRawBuffer, true);
SetIndexBuffer(lowRawBufferIndex, lowRawBuffer, INDICATOR_CALCULATIONS);
//
ArraySetAsSeries(highRawBuffer, true);
SetIndexBuffer(highRawBufferIndex, highRawBuffer, INDICATOR_CALCULATIONS);
}
/**
* Initial all Indicator Requirements ...
*
* @return ( false )
*
*/
bool InitRequirements()
{
//
bool result = true;
//
// Handlers ...
//
return result;
}
/**
* Calculate Custom Buffers ...
*
* @param barIndex: Integer, Represent Current Bar ...
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
* @param ratesTotal: Integer, Represents All Available Bars ...
* @param open: Double Array, History of Open Prices ...
* @param high: Double Array, History of High Prices ...
* @param close: Double Array, History of Close Prices ...
* @param low: Double Array, History of Low Prices ...
* @param tickVolume: Long, History of Tick Volumes on Bar ...
*/
void CalculateBuffers(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Calculate Bars Limit and First Bar Index ...
int barsLimit = startCalculationForLastBars > 0
? startCalculationForLastBars
: 0;
if (barsLimit == 0)
{
//
barsLimit = ratesTotal;
firstBarIndex = barsLimit - 1;
}
else
{
firstBarIndex = startCalculationForLastBars;
}
//
// bool canCalculate = true;
bool canCalculate =
barIndex <= barsLimit;
if (canCalculate)
{
//
// Calculate Values ...
CalculateValues(
barIndex,
prevCalculated,
ratesTotal,
open,
high,
close,
low,
tickVolume //
);
}
else
{
FillBuffersZero(barIndex);
}
}
/**
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
*
* @param barIndex: Integer ...
*/
void FillBuffersZero(int barIndex)
{
//
// TODO: Fill Buffers as Empty ...
lowBuffer[barIndex] = emptyValue;
highBuffer[barIndex] = emptyValue;
peakBuffer[barIndex] = emptyValue;
valeBuffer[barIndex] = emptyValue;
highRawBuffer[barIndex] = emptyValue;
lowRawBuffer[barIndex] = emptyValue;
}
/**
* Calculate Values ...
*
* @param barIndex: int, Specified Bar Index ...
* @param prevCalculated: int, Provides Previous Calculated Bars ...
* @param ratesTotal: int, Provides All Availabled Bars ...
* @param open: double Collection, Provides Open Prices Time Series ...
* @param high: double Collection, Provides High Prices Time Series ...
* @param close: double Collection, Provides Close Prices Time Series ...
* @param low: double Collection, Provides Low Prices Time Series ...
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
*/
void CalculateValues(
int barIndex,
const int prevCalculated,
const int ratesTotal,
const double &open[],
const double &high[],
const double &close[],
const double &low[],
const long &tickVolume[] //
)
{
//
// Common Requirements ...
//
FillBuffersZero(barIndex);
//
int lastBarIndex = barIndex + 1;
int maxBarIndex = startCalculationForLastBars > 0
? startCalculationForLastBars
: ratesTotal;
//
bool isFirstBar =
startCalculationForLastBars > 0
? barIndex == startCalculationForLastBars
: barIndex == firstBarIndex;
//
// Calculate Highs and Lows ...
XOHCL iBar;
bool has = iBar.Init(
_Symbol,
_Period,
barIndex //
);
if (!has)
{
return;
}
//
int lowestIDX = -1;
double iRawLow = iBar.FindLowest(
lowestIDX,
pvValidationLength,
valePriceType //
);
//
int highestIDX = -1;
double iRawHigh = iBar.FindHighest(
highestIDX,
pvValidationLength,
peakPriceType //
);
//
lowRawBuffer[barIndex] = iRawLow;
highRawBuffer[barIndex] = iRawHigh;
//
lowBuffer[barIndex] = iRawLow;
highBuffer[barIndex] = iRawHigh;
//
if (barIndex < firstBarIndex - (pvValidationLength + 1))
{
//
double tmp[];
ArrayCopy(
tmp,
lowRawBuffer,
0,
barIndex,
pvValidationLength //
);
double minLow = GetMin(tmp);
bool isLow = iRawLow < minLow;
lowBuffer[barIndex] =
isLow
? iRawLow
: lowBuffer[lastBarIndex];
//
XClean(tmp);
ArrayCopy(
tmp,
highRawBuffer,
0,
barIndex,
pvValidationLength //
);
double maxHigh = GetMax(tmp);
bool isHigh = iRawHigh > maxHigh;
highBuffer[barIndex] =
isHigh
? iRawHigh
: highBuffer[lastBarIndex];
//
// Cleanup Resources ...
XClean(tmp);
}
// //
// double iLow = emptyValue;
// // IsLow(iLow, barIndex);
// double iPLow = isFirstBar
// ? iLow
// : lowRawBuffer[lastBarIndex];
// //
// double iHigh = emptyValue;
// IsHigh(iHigh, barIndex);
// double iPHigh = isFirstBar
// ? iHigh
// : highRawBuffer[lastBarIndex];
// //
// // Clculate Values ...
// //
// lowRawBuffer[barIndex] = iLow;
// highRawBuffer[barIndex] = iHigh;
// //
// lowBuffer[barIndex] = NotEmptyZero(iLow)
// ? iLow
// : iPLow;
// highBuffer[barIndex] = NotEmptyZero(iHigh)
// ? iHigh
// : iPHigh;
// //
// double iP2Low =
// barIndex < maxBarIndex - 2
// ? lowBuffer[barIndex + 2]
// : emptyValue;
// double iP2High =
// barIndex < maxBarIndex - 2
// ? highBuffer[barIndex + 2]
// : emptyValue;
// //
// double mLowValues[];
// double iVale = emptyValue;
// if (NotEmptyZero(iPLow))
// {
// Add(iPLow, mLowValues);
// }
// if (NotEmptyZero(iP2Low))
// {
// Add(iP2Low, mLowValues);
// }
// bool isVale = iLow <= GetMin(mLowValues);
// iVale = isVale
// ? iLow
// : isFirstBar
// ? emptyValue
// : valeBuffer[lastBarIndex];
// valeBuffer[barIndex] = iVale;
// //
// double mHighValues[];
// double iPeak = emptyValue;
// if (NotEmptyZero(iPHigh))
// {
// Add(iPHigh, mHighValues);
// }
// if (NotEmptyZero(iP2High))
// {
// Add(iP2High, mHighValues);
// }
// bool isPeak = iHigh >= GetMax(mHighValues);
// iPeak = isPeak
// ? iHigh
// : isFirstBar
// ? emptyValue
// : peakBuffer[lastBarIndex];
// peakBuffer[barIndex] = iPeak;
// //
// bool has =
// NotEmptyZero(iLow) ||
// NotEmptyZero(iPLow) ||
// NotEmptyZero(iHigh) ||
// NotEmptyZero(iPHigh);
// if (has)
// {
// }
}
//
@@ -0,0 +1,295 @@
// //
// isBullish =
// //
// // Vales Same ...
// sameVales >= 7 &&
// //
// // PBar Patterns ...
// isBarPatternsPassed &&
// isPBarCloseOverFast &&
// //
// // Validate PullBack based on HK Bond ...
// isPullbackBullish &&
// pBar.close > pHKBondLower;
//
// poiDrawer.DrawPatternAnalysis(
// pBarAnalysis,
// structureDrawConfig.barAnalysisDrawConfig //
// );
// //
// if (IsValidSize(zonesCount))
// {
// //
// poiDrawer.DrawZones(
// zones,
// structureDrawConfig.drawConfig //
// );
// }
// //
// if (IsValidSize(affectedZonesCount))
// {
// //
// poiDrawer.DrawZones(
// affectedZones,
// structureDrawConfig.drawConfig //
// );
// }
//
// poiDrawer.DrawZones(
// affectedZonesBullish,
// structureDrawConfig.drawConfig //
// );
// //
// poiDrawer.DrawZones(
// affectedZonesBearish,
// structureDrawConfig.drawConfig //
// );
// //
// // Update POI Zones ...
// ENUM_X_DETECTOR_ZONE_ACTION zoneActions[];
// poiDetector.UpdateZones(
// iBar,
// zoneActions //
// // Validation Length ...
// // Required Zones ...
// // Loopback ...
// );
//
// Retrieve Conditions ...
// conditions.Clean();
// has = fimaHelper.GetConditions(
// conditions,
// barIndex,
// 10 // Loopback ...
// );
// if (!has)
// {
// //
// iBar.Clean();
// conditions.Clean();
// //
// return;
// }
//
// structure.Clean();
// poiDetector.AnalyseMarket(
// structure,
// structureConfig,
// barIndex //
// );
// poiDrawer.drawnObjects.Clear();
// poiDrawer.DrawMarketStructure(
// structure,
// structureDrawConfig //
// );
/**
* Check Bar Has Signal Based on Strategy X ...
*
* @param bar: XOHCL, reference to Bar ...
* @param zone: XBoxZone, reference to holds affected zone ...
* @param targets: XTarget, reference to detected Signal's Targets collections ...
* @param dir: ENUM_X_DIRECTION, detected Signal's direction ...
*
* @return ( bool )
*/
bool StrategyXHasSignal(
XOHCL &bar,
XBoxZone &zone,
XTarget &targets[],
ENUM_X_DIRECTION &dir //
)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Define Requirements ...
//
XOHCL pBar;
XOHCL p2Bar;
bool isBullish = false;
bool isBearish = false;
XOHCL continuationalBar;
XBoxZone continuationalZones[];
//
// Read PBar ...
result = bar.GetPreviousBar(pBar);
result = result &&
pBar.GetPreviousBar(p2Bar);
if (!result)
{
//
pBar.Clean();
p2Bar.Clean();
//
return result;
}
//
// Reading pBar Patterns ...
XPatternAnalysis pBarAnalysis;
poiDetector.AnalyseBarPatterns(
pBar,
pBarAnalysis,
structureConfig.barsAnalysisConfig //
);
//
// Check Continuational Pullback ...
bool isContinuationPullBack = poiDetector.IsContinuationPullbackPattern(
pBar,
zone,
continuationalZones,
dir,
continuationalBar,
3, // Continuational Length ...
true, // Force Continuational Loopback Has Zones ...
true, // Force Continuational Loopback Has Patterns ...
2, // Pullback Length ...
false // Force Pullback Break ...
);
//
// Do ...
//
isBullish =
//
IsXBullish(dir) &&
isContinuationPullBack &&
continuationalBar.GetUp() < pBar.GetDown() &&
true
// isPBarHasBullishPatterns
//
;
//
isBearish =
//
IsXBearish(dir) &&
isContinuationPullBack &&
continuationalBar.GetDown() > pBar.GetUp() &&
true
// isPBarHasBearishPatterns
//
;
//
// Validate ...
result = isBullish ||
isBearish;
if (result)
{
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
result = HasDirection(dir);
}
//
// Prepare Zone ...
if (result)
{
//
// zone.to = bar.time;
// poiDrawer.DrawZone(zone, structureDrawConfig.drawConfig);
//
// Draw Continuational Zones ...
UpdateToTime(continuationalZones, bar.time);
poiDrawer.DrawZones(continuationalZones, structureDrawConfig.drawConfig);
//
zone.Clean();
//
int idx = -1;
if (isBullish)
{
idx = GetHighestBelow(bar.GetDown(), continuationalZones);
}
else
{
idx = GetLowestAbove(bar.GetUp(), continuationalZones);
}
result = IsValidIndex(idx);
if (result)
{
zone = continuationalZones[idx];
}
//
if (zone.IsValid())
{
//
XPOIDrawConfig iConfig = structureDrawConfig.drawConfig;
iConfig.bullishColor = clrYellow;
iConfig.bearishColor = clrYellow;
poiDrawer.DrawZones(continuationalZones, iConfig);
}
//
// Manage Stops ...
if (result)
{
}
//
result = zone.IsValid();
}
//
// Prepare Targets ...
if (result)
{
}
//
// Cleanup ...
if (!result)
{
//
zone.Clean();
XClean(targets);
dir = X_DIRECTION_NONE;
}
pBar.Clean();
p2Bar.Clean();
continuationalBar.Clean();
XClean(continuationalZones);
//
return result;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,977 @@
`
//
// an Structure for Holds an Specified Symbols
// Positions Info ...
struct XTradeSymbolInfo
{
//
// Properties ...
//
string symbol; // Trading Symbol
//
int longs; // All Long Trades
int shorts; // All Short Trades
//
int trades; // All Trades
//
int losses; // All Loosing Trades
int profits; // All Winning Trades
//
datetime managedStart; // Managed Start Time
//
int managedSLs; // Managed SL(s)
int managedTPs; // Managed TP(s)
int managedTrades; // Managed Trades
//
double managedBalance; // Managed Start Balance
double managedProfits; // Managed Profit(s)
//
// Constructor ...
XTradeSymbolInfo()
{
Clean();
}
//
// Tools ...
//
// Cleanup ...
void Clean()
{
//
symbol = NULL;
//
longs = 0;
shorts = 0;
//
trades = 0;
//
losses = 0;
profits = 0;
//
managedStart = NULL;
//
managedSLs = 0;
managedTPs = 0;
managedTrades = 0;
//
managedBalance = 0;
managedProfits = 0;
//
ZeroMemory(this);
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result = IsSpecifiedValid(symbol);
//
return result;
}
//
bool IsSameAs(XTradeSymbolInfo &item)
{
//
bool result = false;
//
result = IsValid() &&
item.IsValid() &&
symbol == item.symbol;
//
return result;
}
//
string GetRestrictionDescription(
ENUM_XTRADE_RESTRICTION_PERIOD period //
)
{
//
string result = NULL;
//
if (!IsValid() ||
!HasRestrictions(period))
{
return result;
}
//
result +=
"-------------------" + "\n" +
"Restrictions: " + "\n" +
"-------------------" + "\n" +
"Symbol: " + ToXString(symbol) + "\n" +
"Period: " + ToXString(period) + "\n" +
"Start: " + ToFormatString(managedStart) + "\n" +
"Balance: " + ToXString(managedBalance) + "\n" +
"-------------------" + "\n" +
"Trades: " + ToXString(managedTrades) + "\n" +
"SL: " + ToXString(managedSLs) + "\n" +
"TP: " + ToXString(managedTPs) + "\n" +
"Profit: " + ToXString(managedProfits) + "\n" +
"";
//
return result;
}
};
//
void SetForceCloseTradesAt(
string _forceCloseAt //
)
{
forceCloseAt = _forceCloseAt;
}
//
void SetTradeSession(
string symbol,
string start,
string end,
string name = NULL //
)
{
//
// Validate Args ...
bool has = IsValid(end) &&
IsValid(start) &&
IsValid(symbol);
if (!has)
{
return;
}
//
// Create Session ...
//
XTradeSession session;
//
session.end = end;
session.name = name;
session.start = start;
//
int sessionIDX = -1;
has = FindSymbolSession(
sessionIDX,
symbol //
);
//
if (!has)
{
//
// Add New Symbol Session ...
//
XSymbolSessions iSymbolSession;
iSymbolSession.symbol = symbol;
//
AddTradingSession(
session,
iSymbolSession //
);
//
AddRef(
iSymbolSession,
sessions //
);
//
iSymbolSession.Clean();
}
else
{
//
// Update Trading Sessions of Exists Symbol Session ...
AddTradingSession(
session,
sessions[sessionIDX] //
);
}
//
// Cleanup Resources ...
session.Clean();
}
//
void SetTradeRestrictions(
ENUM_XTRADE_RESTRICTION_PERIOD _period,
int _maxAllowedTPs,
int _maxAllowedSLs,
int _maxAllowedTrades //
)
{
//
// Normalizing Args ...
_maxAllowedTPs = NormalizeInt(_maxAllowedTPs, 0);
_maxAllowedSLs = NormalizeInt(_maxAllowedSLs, 0);
_maxAllowedTrades = NormalizeInt(_maxAllowedTrades, 0);
//
restrictionsPeriod = _period;
maxAllowedTPs = _maxAllowedTPs;
maxAllowedSLs = _maxAllowedSLs;
maxAllowedTrades = _maxAllowedTrades;
}
//
// Symbol Info ...
//
bool FindSymbolIndex(
int &index,
XTradeSymbolInfo &item //
)
{
//
bool result = false;
//
index = -1;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
result = HasChild(symbols);
if (!result)
{
return result;
}
//
index = FindIndex(
item,
symbols //
);
//
result = IsValidIndex(index);
//
return result;
}
//
bool FindSymbolIndex(
int &index,
string symbol //
)
{
//
bool result = false;
//
index = -1;
//
result = IsValid(symbol) &&
HasChild(symbols);
if (!result)
{
return result;
}
//
int count = ArraySize(symbols);
for (int i = 0; i < count; i++)
{
//
result = symbols[i].symbol == symbol;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//
void AddOrUpdateSymbolInfo(XTradeSymbolInfo &item)
{
//
bool has = item.IsValid();
if (!has)
{
return;
}
//
int index = -1;
bool isExists = FindSymbolIndex(
index,
item //
);
if (!isExists)
{
//
AddRef(
item,
symbols //
);
}
else
{
//
symbols[index].longs += item.longs;
symbols[index].shorts += item.shorts;
symbols[index].trades += item.trades;
symbols[index].losses += item.losses;
symbols[index].profits += item.profits;
symbols[index].managedSLs += item.managedSLs;
symbols[index].managedTPs += item.managedTPs;
symbols[index].managedTrades += item.managedTrades;
symbols[index].managedProfits += item.managedProfits;
//
// Handle Remove on Managed SL based On Managed TP ...
if (item.managedTPs > 0)
{
//
symbols[index].managedSLs -= item.managedTPs;
if (symbols[index].managedSLs < 0)
{
symbols[index].managedSLs = 0;
}
}
//
// Handle Remove on Managed TP based On Managed SL ...
if (item.managedSLs > 0)
{
//
symbols[index].managedTPs -= item.managedSLs;
if (symbols[index].managedTPs < 0)
{
symbols[index].managedTPs = 0;
}
}
}
}
//
void ResetSymbolsRestrictions()
{
//
bool has = HasChild(symbols);
if (has)
{
//
string prefix = "Protector: ";
//
datetime start = TimeCurrent();
double balance = trader.mAccount.GetBalance();
bool hasRestrictions = HasRestrictions(restrictionsPeriod);
if (!hasRestrictions)
{
//
balance = 0;
start = NULL;
}
//
int count = ArraySize(symbols);
for (int i = 0; i < count; i++)
{
//
XTradeSymbolInfo iInfo = symbols[i];
if (reportRestrictions)
{
//
string message = iInfo.GetRestrictionDescription(restrictionsPeriod);
alert.SendAlert(message);
}
SaveRestrictions(iInfo);
//
symbols[i].managedSLs = 0;
symbols[i].managedTPs = 0;
symbols[i].managedTrades = 0;
symbols[i].managedProfits = 0;
symbols[i].managedStart = start;
symbols[i].managedBalance = balance;
//
iInfo.Clean();
}
//
string message = prefix + "Reset Symbols Restrictions";
HandleReportProtector(message);
}
}
//
void HandleRestrictions()
{
//
bool isNewDay = timeTracker.IsNewDay();
bool isNewHour = timeTracker.IsNewHour();
bool isNewWeek = timeTracker.IsNewWeek();
bool isNewMonth = timeTracker.IsNewMonth();
//
// Reset Force Closed Flag on new Day Starts ...
if (isNewDay)
{
isForceCloseAtTime = false;
}
//
bool canResetRestrictions =
(
//
// Hourly ...
(isNewHour &&
restrictionsPeriod == XTRADE_RESTRICATION_HOURLY)
//
||
//
// Daily ...
(isNewDay &&
restrictionsPeriod == XTRADE_RESTRICATION_DAILY)
//
||
//
// Weekly ...
(isNewWeek &&
restrictionsPeriod == XTRADE_RESTRICATION_WEEKLY)
//
||
//
// Monthly ...
(isNewMonth &&
restrictionsPeriod == XTRADE_RESTRICATION_MONTHLY)
//
)
//
;
if (canResetRestrictions)
{
ResetSymbolsRestrictions();
}
}
//
bool SaveRestrictions(XTradeSymbolInfo &info)
{
//
bool result = false;
//
if (!mSaveRestrictions)
{
return result;
}
//
result = info.IsValid();
if (!result)
{
return result;
}
//
string filePath = GetRestrictionsFilePath(info.symbol);
result = IsValid(filePath);
if (!result)
{
return result;
}
//
string content = info.GetRestrictionDescription(restrictionsPeriod);
//
result = collector.Append(
filePath,
content //
);
//
return result;
}
//
// Symbol Session ...
//
bool FindSymbolSession(
int &index,
string symbol //
)
{
//
bool result = false;
//
index = -1;
//
result = IsValid(symbol) &&
HasChild(sessions);
if (!result)
{
return result;
}
//
int count = ArraySize(sessions);
for (int i = 0; i < count; i++)
{
//
result = sessions[i].symbol == symbol;
if (result)
{
//
index = i;
break;
}
}
//
result = IsValidIndex(index);
//
return result;
}
//
void AddTradingSession(
XTradeSession &session,
XSymbolSessions &symbolSession //
)
{
//
bool has = session.IsValid() &&
symbolSession.IsValid();
if (!has)
{
return;
}
//
// Check Session Exists in Symbol Session ...
bool isExists = false;
if (HasChild(symbolSession.sessions))
{
//
int count = ArraySize(symbolSession.sessions);
for (int i = 0; i < count; i++)
{
//
isExists = symbolSession.sessions[i].end == session.end &&
symbolSession.sessions[i].start == session.start;
if (isExists)
{
break;
}
}
}
//
if (!isExists)
{
//
AddRef(
session,
symbolSession.sessions //
);
}
}
/**
* Check Signal Execution Conditions ...
*
* @param signal: XSignal instance reference ...
* @param executionResult: ENUM_X_SIGNAL_EXECUTION_RESULT member reference ...
*
* @return ( bool )
*/
bool CheckSignal(
XSignal &signal,
ENUM_X_SIGNAL_EXECUTION_RESULT &executionResult //
)
{
//
bool result = false;
//
// Cleanup ...
executionResult = X_SIGNAL_EXECUTION_UNKNOWN;
//
// Validate Signal ...
result = signal.IsValid();
if (!result)
{
return result;
}
//
// Reporting Signal ...
if (reportSignals)
{
//
string message = signal.GetMessage("Provided");
alert.SendAlert(message);
}
//
SaveSignal(signal);
//
// Check Trade Permission ...
if (!allowTrade)
{
//
result = false;
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
//
return result;
}
//
bool isLong = IsLong(signal.type);
bool isShort = IsShort(signal.type);
//
bool isLongAndAllowed =
isLong &&
allowLongs;
//
bool isShortAndAllowed =
isShort &&
allowShorts;
//
result = isLongAndAllowed ||
isShortAndAllowed;
if (!result)
{
//
executionResult = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED;
//
return result;
}
//
// Check Symbol Info Exists or not ...
int symbolInfoIDX = -1;
bool isSymbolInfoExists = FindSymbolIndex(
symbolInfoIDX,
signal.symbol //
);
//
// Check Symbol Session Exists or not ...
int symbolSessionIDX = -1;
bool isSymbolSessionExists = FindSymbolSession(
symbolSessionIDX,
signal.symbol //
);
//
// Chack Trade Session Validating ...
if (isSymbolSessionExists)
{
//
result = sessions[symbolSessionIDX].CanTrade();
if (!result)
{
//
executionResult = X_SIGNAL_EXECUTION_FAILED_DELAY_NOT_PASSED;
//
return result;
}
}
//
// Check Trade Permissions Based on SL(s) Count ...
bool hasRestrictions = restrictionsPeriod != XTRADE_RESTRICATION_NONE;
if (hasRestrictions)
{
//
// Only Can Check Restrictions when
// Symbol Info Exists ...
if (isSymbolInfoExists)
{
//
bool isTPAllowed = maxAllowedTPs == 0
? true
: symbols[symbolInfoIDX].managedTPs < maxAllowedTPs;
bool isSLAllowed = maxAllowedSLs == 0
? true
: symbols[symbolInfoIDX].managedSLs < maxAllowedSLs;
bool isTradeAllowed = maxAllowedTrades == 0
? true
: symbols[symbolInfoIDX].managedTrades < maxAllowedTrades;
//
result = isTPAllowed &&
isSLAllowed &&
isTradeAllowed;
}
//
// Report Error ...
if (!result)
{
//
executionResult = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED;
//
return result;
}
}
//
return result;
}
/**
* Execute Specified Signal ...
*
* @param signal: XSignal instance reference ...
* @param conditions: XCATBEAStrategyConditions instance reference ...
*
* @return ( bool )
*/
bool Execute(XSignal &signal)
{
//
bool result = false;
//
result = signal.IsValid();
if (!result)
{
return result;
}
//
int idx = -1;
bool isExists = HasTrade(
idx,
signal //
);
result = !isExists;
if (!result)
{
return result;
}
//
ENUM_X_SIGNAL_EXECUTION_RESULT executionResult;
//
// Checking Signal For Execution ...
result = CheckSignal(
signal,
executionResult //
);
if (result)
{
//
result = trader.ExecuteSignal(
signal,
executionResult //
);
}
//
// Alert Signal Execution ...
if (reportTrades)
{
//
string executionMessage = ToString(executionResult);
//
string message = NULL;
if (result)
{
message = signal.GetMessage("Executed");
}
else
{
message = signal.GetMessage("Failed due (" + executionMessage + ")");
}
//
alert.SendAlert(message);
}
//
if (result)
{
//
// Create Symbol Info Struct ...
XTradeSymbolInfo iSymbolInfo;
//
iSymbolInfo.trades = 1;
iSymbolInfo.managedTrades = 1;
iSymbolInfo.symbol = signal.symbol;
//
bool isLong = IsLong(signal.type);
if (isLong)
{
iSymbolInfo.longs = 1;
}
else
{
iSymbolInfo.shorts = 1;
}
//
// Fill Balance for Restrications ...
bool hasRestrictions = HasRestrictions(restrictionsPeriod);
if (hasRestrictions)
{
//
// Read Balance ...
double balance = trader.mAccount.GetBalance();
iSymbolInfo.managedBalance = balance;
iSymbolInfo.managedStart = TimeCurrent();
}
//
AddOrUpdateSymbolInfo(iSymbolInfo);
//
// Create Trade Struct ...
XTradeInfo iTrade;
//
ulong positionID = trader.GetLastOpenPositionTicket();
double commission = trader.GetPositionCommission(positionID);
//
iTrade.signal = signal;
iTrade.positionID = positionID;
iTrade.commission = commission;
iTrade.signaledAt = signal.time;
iTrade.executedAt = TimeCurrent();
iTrade.conditions = signal.conditions;
//
AddRef(
iTrade,
trades //
);
}
//
return result;
}
/**
* Check Specified Symbol is Active for
* Analysing or Open Trades ...
*/
bool IsActiveSession(string symbol)
{
//
bool result = false;
//
// Validate Args ...
result = IsValid(symbol);
if (!result)
{
return result;
}
//
// TODO: Complete this ...
// //
// // Check Symbol Session Exists or not ...
// int symbolSessionIDX = -1;
// bool isSymbolSessionExists = FindSymbolSession(
// symbolSessionIDX,
// symbol //
// );
// //
// // Chack Trade Session Validating ...
// if (isSymbolSessionExists)
// {
// result = sessions[symbolSessionIDX].CanTrade();
// }
//
return result;
}
//
string forceCloseAt;
bool isForceCloseAtTime;
//
int maxAllowedTPs;
int maxAllowedSLs;
int maxAllowedTrades;
ENUM_XTRADE_RESTRICTION_PERIOD restrictionsPeriod;
XTradeSymbolInfo symbols[];
XSymbolSessions sessions[];
//
forceCloseAt = NULL;
isForceCloseAtTime = false;
//
maxAllowedTPs = 0;
maxAllowedSLs = 0;
maxAllowedTrades = 0;
restrictionsPeriod = XTRADE_RESTRICATION_NONE;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,379 @@
/**
* Create Bar Object ...
*
* @param bar: XOHCL instance Reference ...
* @param object: XCOHCLObject pointer Reference ..
* @param to: Datetime ...
*
* @return ( bool )
*/
bool CreateBar(
XOHCL &bar,
XCOHCLObject *&object,
datetime to = NULL //
)
{
//
bool result = false;
//
object = NULL;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
to = NormalizeTime(to);
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
int width = BarWidth();
//
color mBullishColor = BarBullishColor();
color mBearishColor = BarBearishColor();
//
bool fillBody = BarFillBody();
bool fillHighShadow = BarFillHighShadow();
bool fillLowShadow = BarFillLowShadow();
//
ENUM_LINE_STYLE bodyStyle = BarBodyStyle();
ENUM_LINE_STYLE highShadowStyle = BarHighShadowStyle();
ENUM_LINE_STYLE lowShadowStyle = BarLowShadowStyle();
//
object = new XCOHCLObject();
result = object.Create(
chartID,
window,
bar,
to,
prefix //
);
if (result)
{
//
// Apply Styling ...
//
object.BodyWidth(width);
object.LowShadowWidth(width);
object.HighShadowWidth(width);
//
object.BodyStyle(bodyStyle);
object.LowShadowStyle(lowShadowStyle);
object.HighShadowStyle(highShadowStyle);
//
bool isBullish = bar.IsBullish();
if (isBullish)
{
//
object.BodyColor(mBullishColor);
object.LowShadowColor(mBullishColor);
object.HighShadowColor(mBullishColor);
}
else
{
//
object.BodyColor(mBearishColor);
object.LowShadowColor(mBearishColor);
object.HighShadowColor(mBearishColor);
}
//
object.BodyFill(fillBody);
object.HighShadowFill(fillHighShadow);
object.LowShadowFill(fillLowShadow);
}
//
return result;
}
/**
* Create Bar Arrow Object ...
*
* @param bar: XOHCL instance Reference ...
* @param priceType: ENUM_X_PRICE member ...
* @param arrow: int, Arrow Code ...
* @param clr: color, Arro Color ...
* @param width: int, Arrow Width ...
* @param anchor: ENUM_ARROW_ANCHOR, anchor of Arrow ...
* @param name: string, name of Arrow ...
*
* @return ( bool )
*/
bool CreateBarArrow(
XOHCL &bar,
XCBarArrowObject *&object,
ENUM_X_PRICE priceType,
int arrow = 159,
color clr = clrYellow,
int width = 3,
ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM,
string name = NULL //
)
{
//
bool result = false;
//
object = NULL;
//
result = bar.IsValid();
if (!result)
{
return result;
}
//
string barTag = bar.GetTag(name);
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
color mBullishColor = BarBullishColor();
color mBearishColor = BarBearishColor();
//
prefix =
(IsValid(prefix)
? prefix + "_"
: prefix) +
barTag;
//
object = new XCBarArrowObject();
result = object
.CreateByBar(
chartID,
prefix,
window,
arrow,
bar,
priceType //
);
if (result)
{
//
object.ArrowColor(clr);
object.ArrowWidth(width);
}
//
return result;
}
/**
* Create Specific Box on Chart ...
*
* @param upper: Double ...
* @param lower: Double ...
* @param from: Datetime ...
* @param to: Datetime ...
* @param clr: Color ...
* @param width: Integer ...
* @param fill: Boolean ...
* @param style: ENUM_LINE_STYLE member ...
*
* @return ( bool )
*/
bool CreateBox(
XCBoxObject *&object,
string name,
double upper,
double lower,
datetime from,
datetime to,
datetime at,
color clr = clrYellowGreen,
int width = 1,
bool fill = false,
ENUM_LINE_STYLE style = STYLE_SOLID //
)
{
//
bool result = false;
//
object = NULL;
//
to = NormalizeTime(to);
//
string dateStr = ToFormatString(from) + "|" + ToFormatString(to);
string dateMD5 = ToMD5(dateStr);
if (!IsValid(name))
{
//
name = "XBox_" +
ToXString(upper) + "_" +
ToXString(lower) + "_" +
dateMD5;
}
//
result =
upper > 0 &&
lower > 0 &&
to > from &&
IsValid(to) &&
IsValid(name) &&
IsValid(from) &&
upper > lower;
if (!result)
{
return result;
}
//
string prefix = Prefix();
long chartID = ChartIdentification();
int window = SubWindowIdentification();
//
object = new XCBoxObject();
result = object.Create(
chartID,
window,
name,
upper,
lower,
from,
to,
at,
prefix //
);
//
if (!result)
{
return result;
}
//
object.BoxColor(clr);
object.BoxFill(fill);
object.BoxWidth(width);
object.BoxStyle(style);
//
return result;
}
/**
* Create Specific Box on Chart ...
*
* @param box: XBoxZone instance Reference ...
* @param clr: Color ...
* @param width: Integer ...
* @param fill: Boolean ...
* @param style: ENUM_LINE_STYLE member ...
*
* @return ( bool )
*/
bool CreateBox(
XBoxZone &box,
XCBoxObject *&object,
color clr = clrYellowGreen,
int width = 1,
bool fill = false,
ENUM_LINE_STYLE style = STYLE_SOLID //
)
{
//
bool result = false;
//
object = NULL;
//
result = box.IsValid();
if (!result)
{
return result;
}
//
string name = box.GetTag();
//
result = CreateBox(
object,
name,
box.upper,
box.lower,
box.from,
box.to,
box.at,
clr,
width,
fill,
style //
);
//
return result;
}
//
// Testing Draws ...
//
XFIMAMarketStructure pivots[];
//
XPivot pvPivots[];
XPivot hkPivots[];
XPivot maPivots[];
XPivot zgPivots[];
XPivot sarPivots[];
//
poiDetector.CollectZGPivots(zgPivots);
poiDetector.CollectMAPivots(maPivots);
poiDetector.CollectHKPivots(hkPivots);
poiDetector.CollectPVPivots(pvPivots);
poiDetector.CollectSARPivots(sarPivots);
//
// Merging All Pivots ...
Copy(pvPivots, pivots, false);
Copy(zgPivots, pivots, false);
Copy(maPivots, pivots, false);
Copy(hkPivots, pivots, false);
Copy(sarPivots, pivots, false);
//
if (HasChild(pivots))
{
poiDrawer.DrawPivots(pivots, iDrawConfig);
}
//
// Cleanup ...
XClean(pivots);
XClean(pvPivots);
XClean(hkPivots);
XClean(maPivots);
XClean(zgPivots);
XClean(sarPivots);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,699 @@
/**
* Check Market Conditions for Pattern Detection ...
*/
void DetectPatterns()
{
//
if (!eaIsNewBar)
{
return;
}
//
// Initialize 1 Indexed Bar ...
XOHCL cBar;
bool has = cBar.Init(
_Symbol,
_Period,
1 //
);
if (!has)
{
return;
}
//
// Do Analysis ...
//
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Define Detection Flags ...
//
bool detectPinned = false;
bool detectMomentum = false;
bool detectEngulfed = false;
bool detectTrueGaped = false;
//
bool detectStarPattern = false;
bool detectFlagPattern = false;
bool detectRisingPattern = false;
bool detectPiercingPattern = false;
bool detectSignalKeyBarPattern = false;
//
bool detectSwingTrend = false;
bool detectSwingTrendBreakes = false;
//
bool detectSupports = false;
bool detectResistance = false;
//
// XFIMA Patetrns ...
bool detectFIMAPatterns = true;
//
bool detectFIMAPVPatterns = false;
bool detectFIMAMAPatterns = false;
bool detectFIMASARPatterns = false;
bool detectFIMAZigZagPatterns = false;
//
bool analyseFIMAPVPivots = true;
bool analyseFIMAMAPivots = true;
bool analyseFIMASARPivots = true;
bool analyseFIMAZigZagPivots = true;
//
// Required Pivots ...
int numberOfRequiredPivots = 15;
//
// Checking Momentum Bar ...
if (detectMomentum)
{
//
bool isMomentum = fima2Signaller.poiDetector.IsMomentumBar(
cBar,
iDir //
);
bool isBullishMomentum = isMomentum &&
IsSpecifiedBullish(iDir);
bool isBearishMomentum = isMomentum &&
IsSpecifiedBearish(iDir);
if (isMomentum)
{
Print(ToXString(iDir), " Momentum Bar: ", cBar.time);
}
}
//
// Checking Engulfed Bar ...
if (detectEngulfed)
{
//
bool isEngulfed = fima2Signaller.poiDetector.IsEngulfedBar(
cBar,
iDir //
);
bool isBullishEngulfed = isEngulfed &&
IsSpecifiedBullish(iDir);
bool isBearishEngulfed = isEngulfed &&
IsSpecifiedBearish(iDir);
if (isEngulfed)
{
Print(ToXString(iDir), " Engulfed Bar: ", cBar.time);
}
}
//
// Checking TruGaped Bar ...
if (detectTrueGaped)
{
//
bool isTrueGaped = fima2Signaller.poiDetector.IsTrueGapedBar(
cBar,
iDir //
);
bool isBullishTrueGaped = isTrueGaped &&
IsSpecifiedBullish(iDir);
bool isBearishTrueGaped = isTrueGaped &&
IsSpecifiedBearish(iDir);
if (isTrueGaped)
{
Print(ToXString(iDir), " TrueGapped Bar: ", cBar.time);
}
}
//
// Checking Pinned Bar ...
if (detectPinned)
{
bool isPinned = fima2Signaller.poiDetector.IsPinnedBar(
cBar,
iDir //
);
bool isBullishPinned = isPinned &&
IsSpecifiedBullish(iDir);
bool isBearishPinned = isPinned &&
IsSpecifiedBearish(iDir);
if (isPinned)
{
Print(ToXString(iDir), " Pinned Bar: ", cBar.time);
}
}
//
// Checking Star Pattern ...
if (detectStarPattern)
{
bool isStarPattern = fima2Signaller.poiDetector.IsStartPattern(
cBar,
iDir //
);
bool isBullishStarPattern = isStarPattern &&
IsSpecifiedBullish(iDir);
bool isBearishStarPattern = isStarPattern &&
IsSpecifiedBearish(iDir);
if (isStarPattern)
{
Print(ToXString(iDir), " Star Pattern: ", cBar.time);
}
}
//
// Checking Piercing Pattern ...
if (detectPiercingPattern)
{
//
bool isPiercingPattern = fima2Signaller.poiDetector.IsPiercingPattern(
cBar,
iDir //
);
bool isBullishPiercingPattern = isPiercingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishPiercingPattern = isPiercingPattern &&
IsSpecifiedBearish(iDir);
if (isPiercingPattern)
{
Print(ToXString(iDir), " Piercing Pattern: ", cBar.time);
}
}
//
// Checking Rising Pattern ...
if (detectRisingPattern)
{
//
bool isRisingPattern = fima2Signaller.poiDetector.IsRisingPattern(
cBar,
iDir //
);
bool isBullishRisingPattern = isRisingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishRisingPattern = isRisingPattern &&
IsSpecifiedBearish(iDir);
if (isRisingPattern)
{
Print(ToXString(iDir), " Rising Pattern: ", cBar.time);
}
}
//
// Checking Flag Pattern ...
if (detectFlagPattern)
{
//
XOHCL swingBar;
bool isFlagPattern = fima2Signaller.poiDetector.IsFlagPattern(
cBar,
iDir,
swingBar //
);
bool isBullishFlagPattern = isFlagPattern &&
IsSpecifiedBullish(iDir);
bool isBearishFlagPattern = isFlagPattern &&
IsSpecifiedBearish(iDir);
if (isFlagPattern)
{
Print(ToXString(iDir), " Flag Pattern: ", cBar.time, ", Swing: ", swingBar.time);
}
swingBar.Clean();
}
//
// Detect SignalKey Bar Pattern ...
if (detectSignalKeyBarPattern)
{
//
bool isSignalKeyBar = fima2Signaller.poiDetector.IsSignalKeyBarPattern(
cBar,
iDir //
);
bool isBullishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBullish(iDir);
bool isBearishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBearish(iDir);
if (isSignalKeyBar)
{
Print(ToXString(iDir), " SignalKey Bar Pattern: ", cBar.time);
}
}
//
// Detect Swing Trend ...
if (detectSwingTrend)
{
//
XOHCL swings[];
bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend(
cBar,
iDir,
swings //
);
bool hasBullishSwingTrend = hasSwingTrend &&
IsSpecifiedBullish(iDir);
bool hasBearishSwingTrend = hasSwingTrend &&
IsSpecifiedBearish(iDir);
if (hasSwingTrend)
{
//
Print(ToXString(iDir), " Swing Trend: ", cBar.time);
//
CChartObjectTrend *iObj;
has = fima2Signaller.poiDrawer.DrawSwingTrend(
swings,
iDir,
iObj,
true // Ray Right ...
);
if (has)
{
eaDraws.Add(iObj);
}
}
SpecifiedClean(swings);
}
//
// Swing Trend Breakes ...
if (detectSwingTrendBreakes)
{
//
XOHCL swings[];
bool hasSwingTrend = fima2Signaller.poiDetector.HasSwingTrend(
cBar,
iDir,
swings //
);
bool hasBullishSwingTrend = hasSwingTrend &&
IsSpecifiedBullish(iDir);
bool hasBearishSwingTrend = hasSwingTrend &&
IsSpecifiedBearish(iDir);
if (hasSwingTrend)
{
//
if (!HasDirection(trendDir))
{
trendDir = iDir;
}
}
//
// Breaked Detection ...
if (trendDir != iDir)
{
//
Print("Trend Dir Breaked to: ", ToXString(iDir));
trendDir = iDir;
}
//
SpecifiedClean(swings);
}
//
// Detect Supports ...
if (detectSupports)
{
//
XOHCL support;
bool hasSupport = fima2Signaller.poiDetector.HasSupport(
cBar,
support //
);
if (hasSupport)
{
//
XBoxZone supportBox;
has = ToSupportBox(support, supportBox);
if (has)
{
//
// Draw Box ...
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
supportBox,
iObj //
);
if (has)
{
eaDraws.Add(iObj);
}
//
ZeroMemory(iObj);
}
//
supportBox.Clean();
}
support.Clean();
}
//
// Detect Resistance ...
if (detectResistance)
{
//
XOHCL resistance;
bool hasResistance = fima2Signaller.poiDetector.HasResistance(
cBar,
resistance //
);
if (hasResistance)
{
//
XBoxZone resistanceBox;
has = ToResistanceBox(resistance, resistanceBox);
if (has)
{
//
// Draw Box ...
XCBoxObject *iObj;
has = fima2Signaller.poiDrawer.DrawBox(
resistanceBox,
iObj //
);
if (has)
{
eaDraws.Add(iObj);
}
//
ZeroMemory(iObj);
}
//
resistanceBox.Clean();
}
resistance.Clean();
}
//
// Detecting FIMA Patterns ...
if (detectFIMAPatterns)
{
//
// Check For PV Pivots ...
if (detectFIMAPVPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractPVPivots(
pivots, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
10 // Validation Length ...
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Check for MA Patterns ...
if (detectFIMAMAPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractMAPivots(
pivots, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
0 // Validation Length ...
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Check for SAR Pivots ...
if (detectFIMASARPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractSARPivots(
pivots, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500 // Max Allowed Loopback ...
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Check for ZigZag Pivots ...
if (detectFIMAZigZagPatterns)
{
//
XPivot pivots[];
int pivotsCount = fima2Signaller.poiDetector.ExtractZigZagPivots(
pivots,
cBar.Index(),
numberOfRequiredPivots,
1500 //
);
has = IsValidSize(pivotsCount);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
int drawnPivotsCount = fima2Signaller.poiDrawer.DrawPivots(
pivots,
drawnPivots //
);
has = IsValidSize(drawnPivotsCount);
if (has)
{
//
AddObjects(
drawnPivots,
eaDraws //
);
//
// Print("Pivots Extracted ...");
}
//
ZeroMemory(drawnPivots);
}
}
//
// Analysers ...
//
// Analyse Based on PV ...
if (analyseFIMAPVPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalysePVPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
10 // Validation Length ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(pvAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
pvAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA PV Pivots Analysed ...");
}
}
}
//
// Analyse Based on MA ...
if (analyseFIMAMAPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalyseMAPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500, // Max Allowed Loopback ...
0 // Validation Length ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(maAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
maAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA MA Pivots Analysed ...");
}
}
}
//
// Analyse Based on SAR ...
if (analyseFIMASARPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalyseSARPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500 // Max Allowed Loopback ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(sarAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
sarAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA Sar Pivots Analysed ...");
}
}
}
//
// Analyse Based on ZigZag ...
if (analyseFIMAZigZagPivots)
{
//
XPivotAnalysis analysis;
has = fima2Signaller.poiDetector.AnalyseZigZagPivots(
analysis, // Result ...
cBar.Index(), // Bar Index ...
numberOfRequiredPivots, // Required Number of Pivots ...
1500 // Max Allowed Loopback ...
);
if (has)
{
//
// Draw Analysis ...
DestroyObject(zigzagAnalysisObject);
has = fima2Signaller.poiDrawer.DrawPivotAnalysis(
analysis,
zigzagAnalysisObject,
true // Draw Pivots ...
);
if (has)
{
//
// eaDraws.Add(iObj);
//
// Print("FIMA ZigZag Pivots Analysed ...");
}
}
}
}
//
cBar.Clean();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,567 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Library
// -------------------------------------------------
// Name: XCXFIMAEALib ...
// Description: XFIMAEA Library ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMAEA Library"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
#include "../Classes/x-saherelm.xfima.parser.class.mq5"
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
//
// Definitions ...
/**
* XFIMA Base Market Structure ...
* AnalyseMarket result ...
**/
struct XFIMAMarketStructure
{
//
XOHCL bar; // Spacified Start Bar for Analysing ...
XPatternAnalysis barAnalysis; // Structure Bar Pattern Analysis ...
//
XPivotAnalysis pvAnalysis; // PV Pivot Analysis Result ...
XPivotAnalysis zgAnalysis; // ZG Pivot Analysis Result ...
//
XPatternAnalysis barsAnalysis[]; // Anaysed Bars ...
//
// Constructor ...
XFIMAMarketStructure()
{
Clean();
}
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
bar.Clean();
barAnalysis.Clean();
//
pvAnalysis.Clean();
zgAnalysis.Clean();
XClean(barsAnalysis);
//
ZeroMemory(this);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result = bar.IsValid() &&
barAnalysis.IsValid();
//
return result;
}
//
// Collectors ...
/**
* Collect Required Zones from Structure ...
*
* @param dest: XBoxZone, reference collection to holds result ...
* @param forDir: ENUM_X_DIRECTION, Specified Collectiong ones Direction ...
* @param containsOB: bool, Contains OB Zones ...
* @param containsFVG: bool, Contains FVG Zones ...
*
* @return ( int )
*/
int CollectZones(
XBoxZone &dest[],
ENUM_X_DIRECTION forDir = X_DIRECTION_NONE,
bool containsOB = false,
bool containsFVG = false //
)
{
//
int result = 0;
//
// Prepare ...
XClean(dest);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
bool canCollectBullish =
IsXBullish(forDir) ||
!HasDirection(forDir);
//
bool canCollectBearish =
IsXBearish(forDir) ||
!HasDirection(forDir);
//
int count = 0;
XBoxZone tmpBox;
//
// Check Analysis ...
//
// XPV ...
has = pvAnalysis.IsValid();
if (has)
{
//
// Support ...
tmpBox.Clean();
has = pvAnalysis.HasSupportBox(tmpBox);
if (has && canCollectBullish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
//
// Resistance ...
tmpBox.Clean();
has = pvAnalysis.HasResistanceBox(tmpBox);
if (has && canCollectBearish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
}
//
// XZG ...
has = zgAnalysis.IsValid();
if (has)
{
//
// Support ...
tmpBox.Clean();
has = zgAnalysis.HasSupportBox(tmpBox);
if (has && canCollectBullish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
//
// Resistance ...
tmpBox.Clean();
has = zgAnalysis.HasResistanceBox(tmpBox);
if (has && canCollectBearish)
{
//
AddIfNotExists(
tmpBox,
dest //
);
}
}
//
// Bar Patterns ...
has = HasChild(barsAnalysis);
if (has)
{
//
count = ArraySize(barsAnalysis);
for (int i = 0; i < count; i++)
{
//
// Support ...
has = barsAnalysis[i].IsSupport();
if (has && canCollectBullish)
{
//
AddIfNotExists(
barsAnalysis[i].support,
dest //
);
}
//
// Resistance ...
has = barsAnalysis[i].IsResistance();
if (has && canCollectBearish)
{
//
AddIfNotExists(
barsAnalysis[i].resistance,
dest //
);
}
//
// OB ...
if (containsOB)
{
//
has = barsAnalysis[i].IsOB();
if (has)
{
//
has = (canCollectBullish && barsAnalysis[i].ob.IsBullish()) ||
(canCollectBearish && barsAnalysis[i].ob.IsBearish());
if (has)
{
//
AddIfNotExists(
barsAnalysis[i].ob,
dest //
);
}
}
}
//
// FVG ...
if (containsFVG)
{
has = barsAnalysis[i].IsFVG();
if (has)
{
//
has = (canCollectBullish && barsAnalysis[i].fvg.IsBullish()) ||
(canCollectBearish && barsAnalysis[i].fvg.IsBearish());
if (has)
{
//
AddIfNotExists(
barsAnalysis[i].fvg,
dest //
);
}
}
}
}
}
//
result = ArraySize(dest);
has = IsValidSize(result);
if (has)
{
//
// Update To Time ...
// and also we Can Validate Zones Here ...
datetime cTime = TimeCurrent();
for (int i = 0; i < result; i++)
{
dest[i].to = cTime;
}
}
//
// Cleanup ...
tmpBox.Clean();
//
return result;
}
//
};
struct XFIMAMarketStructureConfig
{
//
// Props ...
//
// Detector Flags ...
//
bool analysePVPivots; // Analyse PV Pivots ...
bool analyseZGPivots; // Analyse ZG Pivots ...
//
bool analyseBarPatterns; // Analyse Bar Patterns ...
//
// Detector Configs ...
//
int loopback; // Max Allowed Looping Back Length ...
int requiredPivots; // Required Extracted Pivots for Analysis ...
//
int pvPivotsValidationLength; // PV Pivots Validation Length ...
double maCrossValidationDiffMultiplier; // a Point Distance to Validate MA Crosses ...
//
XPatternAnalysisConfig barsAnalysisConfig; // Bars Analyser Config ...
//
// Constructor ...
XFIMAMarketStructureConfig()
{
Clean();
}
//
// Tools ...
/**
* This function fulfills the will of the developer
*/
void Clean()
{
//
// Detector Flags ...
analysePVPivots = false;
analyseZGPivots = false;
analyseBarPatterns = false;
//
// Configure Detectors ...
loopback = 0;
requiredPivots = 0;
pvPivotsValidationLength = 0;
maCrossValidationDiffMultiplier = 0;
//
barsAnalysisConfig.Clean();
//
ZeroMemory(this);
}
/**
* Default Configurations ...
*/
void Default()
{
//
// Detector Flags ...
analysePVPivots = true;
analyseZGPivots = true;
analyseBarPatterns = true;
//
// Configure Detectors ...
loopback = 200;
requiredPivots = 10;
pvPivotsValidationLength = 5;
maCrossValidationDiffMultiplier = 4;
//
barsAnalysisConfig.Default();
barsAnalysisConfig.FullPattern();
}
/**
* No Draw Abilioty ...
*/
void Off()
{
//
// Detector Flags ...
analysePVPivots = false;
analyseZGPivots = false;
analyseBarPatterns = false;
}
/**
* Full Draw Abilioty ...
*/
void Full()
{
//
// Detector Flags ...
analysePVPivots = true;
analyseZGPivots = true;
analyseBarPatterns = true;
}
//
};
/**
* Configure Market Structure Drawer ...
**/
struct XFIMAMarketStructureDrawerConfig
{
//
// Props ...
//
bool drawPVAnalysis;
bool drawZGAnalysis;
bool drawBarsAnalysis;
//
XPOIDrawConfig drawConfig;
XPivotAnalysisDrawConfig pivotAnalysisDrawConfig;
XPatternAnalysisDrawConfig barAnalysisDrawConfig;
//
// Constructor ...
XFIMAMarketStructureDrawerConfig()
{
Clean();
}
//
// Tools ...
/**
* This function fulfills the will of the developer
*/
void Clean()
{
//
// Drawing Flags ...
//
drawPVAnalysis = false;
drawZGAnalysis = false;
drawBarsAnalysis = false;
//
// Drawing Configs ...
drawConfig.Clean();
barAnalysisDrawConfig.Clean();
pivotAnalysisDrawConfig.Clean();
//
ZeroMemory(this);
}
/**
* Default Configurations ...
*/
void Default()
{
//
// Drawing Flags ...
//
drawPVAnalysis = true;
drawZGAnalysis = true;
drawBarsAnalysis = true;
//
// Drawing Configs ...
drawConfig.Default();
pivotAnalysisDrawConfig.Default();
//
barAnalysisDrawConfig.Default();
barAnalysisDrawConfig.Full();
XClean(barAnalysisDrawConfig.allowedDrawZones);
Add(
X_BAR_PATTERN_SUPPORT,
barAnalysisDrawConfig.allowedDrawZones);
Add(
X_BAR_PATTERN_RESISTANCE,
barAnalysisDrawConfig.allowedDrawZones);
}
/**
* No Draw Abilioty ...
*/
void Off()
{
//
// Drawing Flags ...
//
drawPVAnalysis = false;
drawZGAnalysis = false;
drawBarsAnalysis = false;
//
// Drawing Configs ...
barAnalysisDrawConfig.Off();
pivotAnalysisDrawConfig.Off();
}
/**
* Full Draw Abilioty ...
*/
void Full()
{
//
// Drawing Flags ...
//
drawPVAnalysis = false;
drawZGAnalysis = false;
drawBarsAnalysis = false;
//
// Drawing Configs ...
barAnalysisDrawConfig.Full();
pivotAnalysisDrawConfig.Full();
}
void ApplyDrawConfig()
{
//
barAnalysisDrawConfig.drawConfig = drawConfig;
barAnalysisDrawConfig.ConfigureQuarterDraws();
pivotAnalysisDrawConfig.drawConfig = drawConfig;
}
void ApplyDrawConfig(XPOIDrawConfig &_drawConfig)
{
//
drawConfig = _drawConfig;
ApplyDrawConfig();
}
//
};
//
@@ -0,0 +1,694 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Library
// -------------------------------------------------
// Name: XCXFIMAEALib ...
// Description: XFIMAEA Library ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMAEA Library"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
//
// Definitions ...
/**
* Configure Market Structure Detection ...
**/
struct XFIMAPatternDetectorConfig
{
//
// Props ...
//
bool detectSwingTrend;
//
bool detectStarPattern;
bool detectFlagPattern;
bool detectRisingPattern;
bool detectPiercingPattern;
bool detectSignalKeyBarPattern;
//
bool detectPinned;
bool detectMomentum;
bool detectEngulfed;
bool detectTrueGaped;
//
bool analyseFIMAPVPivots;
bool analyseFIMAZigZagPivots;
//
bool detectMACrosses;
double validMACrossDiffMultiplier;
//
bool detectHKSwitches;
bool detectSARSwitches;
//
// Configs ...
//
// Trending ...
int trendingNumberOfSwings;
int trendingSwingShoulders;
//
// Support and Resistance ...
int zonesRequiredNumber;
int zonesValidationLength;
double zonesMinAlloweStrength;
int zonesBreakValidationLength;
double zonesBarShadowMultiplier;
int zonesMaxAllowedLoopbackLength;
//
// TrueGap ...
double truwGapApprovedPointMultiplier;
//
// Flag Pattern ...
int flagPatternMinimumPullbackBars;
//
// Momentum Bar ...
int momentumBarRangeLength;
double momentumBarApprovedMultiplier;
//
// Pinned Bar ...
double pinnedBaarShadowApprovedMultiplier;
double pinnedBarMinimumPinBarRangeMultiplier;
bool pinnedBarForceDirection;
//
// SignalKey Bar ...
double signalKeyBarShadowApprovedMultiplier;
double signalKeyBarMinimumPinBarRangeMultiplier;
bool signalKeyBarForceDirection;
//
// Analyser ...
int pvPivotsValidationLength;
int numberOfRequiredPivotsForAnalysis;
int maxAllowedLoopbackLengthForAnalysis;
//
// Constructor ...
XFIMAPatternDetectorConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
detectSwingTrend = false;
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
analyseFIMAPVPivots = false;
detectPiercingPattern = false;
analyseFIMAZigZagPivots = false;
detectSignalKeyBarPattern = false;
//
detectMACrosses = false;
validMACrossDiffMultiplier = 0;
//
detectHKSwitches = false;
detectSARSwitches = false;
//
zonesRequiredNumber = 0;
zonesValidationLength = 0;
zonesMinAlloweStrength = 0;
zonesBarShadowMultiplier = 0;
zonesBreakValidationLength = 0;
zonesMaxAllowedLoopbackLength = 0;
//
trendingNumberOfSwings = 0;
trendingSwingShoulders = 0;
momentumBarRangeLength = 0;
pvPivotsValidationLength = 0;
pinnedBarForceDirection = false;
momentumBarApprovedMultiplier = 0;
signalKeyBarForceDirection = false;
truwGapApprovedPointMultiplier = 0;
flagPatternMinimumPullbackBars = 0;
numberOfRequiredPivotsForAnalysis = 0;
pinnedBaarShadowApprovedMultiplier = 0;
maxAllowedLoopbackLengthForAnalysis = 0;
signalKeyBarShadowApprovedMultiplier = 0;
pinnedBarMinimumPinBarRangeMultiplier = 0;
signalKeyBarMinimumPinBarRangeMultiplier = 0;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = true;
validMACrossDiffMultiplier = 1;
//
detectHKSwitches = true;
detectSARSwitches = true;
//
// Trending ...
trendingNumberOfSwings = 3;
trendingSwingShoulders = 11;
//
// Support and Resistance ...
zonesRequiredNumber = 25;
zonesValidationLength = 21;
zonesMinAlloweStrength = 2;
zonesBarShadowMultiplier = 4;
zonesBreakValidationLength = 3;
zonesMaxAllowedLoopbackLength = 200;
//
// TrueGap ...
truwGapApprovedPointMultiplier = 1;
//
// Flag Pattern ...
flagPatternMinimumPullbackBars = 3;
//
// Momentum Bar ...
momentumBarRangeLength = 3;
momentumBarApprovedMultiplier = 2;
//
// Pinned Bar ...
pinnedBaarShadowApprovedMultiplier = 3;
pinnedBarMinimumPinBarRangeMultiplier = 4;
pinnedBarForceDirection = false;
//
// SignalKey Bar ...
signalKeyBarShadowApprovedMultiplier = 3;
signalKeyBarMinimumPinBarRangeMultiplier = 4;
signalKeyBarForceDirection = false;
//
// Length ...
pvPivotsValidationLength = 10;
numberOfRequiredPivotsForAnalysis = 50;
maxAllowedLoopbackLengthForAnalysis = 1500;
}
/**
* Full Detection Model ...
*/
void FullDetect()
{
//
// Patterns ...
detectStarPattern = true;
detectFlagPattern = true;
detectRisingPattern = true;
detectPiercingPattern = true;
detectSignalKeyBarPattern = true;
//
// Bars ...
detectPinned = true;
detectMomentum = true;
detectEngulfed = true;
detectTrueGaped = true;
//
// Analysers ...
analyseFIMAPVPivots = true;
analyseFIMAZigZagPivots = true;
//
detectMACrosses = true;
detectHKSwitches = true;
detectSARSwitches = true;
}
/**
* Default Config, by turn off all detecting flags ...
*/
void OffDetectors()
{
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = false;
detectHKSwitches = false;
detectSARSwitches = false;
}
//
};
/**
* XFIMA Base Market Structure ...
* AnalyseMarket result ...
**/
struct XFIMAMarketStructure
{
//
XOHCL bar;
//
XBoxZone obs[];
XBoxZone fvgs[];
XBoxZone supports[];
XBoxZone resistances[];
//
XPivot pinBars[];
XPivot engulfBars[];
XPivot trueGapBars[];
XPivot momentumBars[];
//
XBoxZone flagPatterns[];
XBoxZone starPatterns[];
XBoxZone risingPatterns[];
XBoxZone piercingPatterns[];
XBoxZone signalKeyBarPatterns[];
//
// Analysis ...
XPivotAnalysis pvAnalysis;
XPivotAnalysis zigzagAnalysis;
//
ENUM_X_DIRECTION pinnedDir;
ENUM_X_DIRECTION momentumDir;
ENUM_X_DIRECTION engulfedDir;
ENUM_X_DIRECTION trueGapedDir;
//
XOHCL flagSwing;
ENUM_X_DIRECTION flagPatternDir;
//
XOHCL trendSwings[];
ENUM_X_DIRECTION trendDir;
//
ENUM_X_DIRECTION starPatternDir;
ENUM_X_DIRECTION risingPatternDir;
ENUM_X_DIRECTION piercingPatternDir;
ENUM_X_DIRECTION signalKeyBarPatternDir;
//
ENUM_X_DIRECTION maCrossDir;
XPivot maCrosses[];
//
ENUM_X_DIRECTION hkSwitchDir;
XPivot hkSwitches[];
//
ENUM_X_DIRECTION sarSwitchDir;
XPivot sarSwitches[];
//
// Constructor ...
XFIMAMarketStructure()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
bar.Clean();
flagSwing.Clean();
//
pvAnalysis.Clean();
zigzagAnalysis.Clean();
//
trendDir = X_DIRECTION_NONE;
pinnedDir = X_DIRECTION_NONE;
momentumDir = X_DIRECTION_NONE;
engulfedDir = X_DIRECTION_NONE;
trueGapedDir = X_DIRECTION_NONE;
flagPatternDir = X_DIRECTION_NONE;
starPatternDir = X_DIRECTION_NONE;
risingPatternDir = X_DIRECTION_NONE;
piercingPatternDir = X_DIRECTION_NONE;
signalKeyBarPatternDir = X_DIRECTION_NONE;
//
maCrossDir = X_DIRECTION_NONE;
SpecifiedClean(maCrosses);
//
hkSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(hkSwitches);
//
sarSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(sarSwitches);
//
SpecifiedClean(obs);
SpecifiedClean(fvgs);
SpecifiedClean(pinBars);
SpecifiedClean(supports);
SpecifiedClean(engulfBars);
SpecifiedClean(resistances);
SpecifiedClean(trueGapBars);
SpecifiedClean(momentumBars);
SpecifiedClean(flagPatterns);
SpecifiedClean(starPatterns);
SpecifiedClean(risingPatterns);
SpecifiedClean(piercingPatterns);
SpecifiedClean(signalKeyBarPatterns);
//
SpecifiedClean(trendSwings);
//
ZeroMemory(this);
}
//
// Checker Functions ...
//
};
/**
* Configure Market Structure Drawer ...
**/
struct XFIMAMarketStructureDrawerConfig
{
//
// Props ...
//
bool drawOB; // Current Order Block ...
bool drawFVG; // Current Fair Value Gap ...
//
bool drawSupport; // Detected Supports ...
bool drawResistance; // Detected Resistances ...
//
bool drawSwingTrend; // Swing Trend ...
bool swingTrendRayLeft; // Ray Left Swing Trend ...
bool swingTrendRayRight; // Ray Right Swing Trend ...
//
// Draw Current Detected Patterns ...
//
bool drawPinned;
bool drawMomentum;
bool drawEngulfed;
bool drawTrueGaped;
//
bool drawStarPattern;
bool drawFlagPattern;
bool drawRisingPattern;
bool drawPiercingPattern;
bool drawSignalKeyBarPattern;
//
// Draw Recently Zones ...
bool drawRecentPatterns;
bool drawFakeBreakedZone;
bool drawRecentlyTestedZones;
bool drawRecentlyBreakedZones;
//
// Draw Analysis Pivots ...
//
// XPV ...
bool drawFIMAPVPivotsAnalysis;
bool drawFIMAPVPivotsAnalysisZones;
bool drawFIMAPVPivotsAnalysisTrends;
bool drawFIMAPVPivotsAnalysisPivots;
//
// XSAR ...
bool drawFIMASARPivotsAnalysis;
bool drawFIMASARPivotsAnalysisZones;
bool drawFIMASARPivotsAnalysisTrends;
bool drawFIMASARPivotsAnalysisPivots;
//
// XZIGZAG ...
bool drawFIMAZigZagPivotsAnalysis;
bool drawFIMAZigZagPivotsAnalysisZones;
bool drawFIMAZigZagPivotsAnalysisTrends;
bool drawFIMAZigZagPivotsAnalysisPivots;
//
// Constructor ...
XFIMAMarketStructureDrawerConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
drawOB = false;
drawFVG = false;
drawPinned = false;
drawMomentum = false;
drawSupport = false;
drawEngulfed = false;
drawTrueGaped = false;
drawResistance = false;
drawSwingTrend = false;
drawStarPattern = false;
drawFlagPattern = false;
swingTrendRayLeft = false;
drawRisingPattern = false;
swingTrendRayRight = false;
drawPiercingPattern = false;
drawSignalKeyBarPattern = false;
//
drawRecentPatterns = false;
drawFakeBreakedZone = false;
drawRecentlyTestedZones = false;
drawRecentlyBreakedZones = false;
//
drawFIMAPVPivotsAnalysis = false;
drawFIMAPVPivotsAnalysisZones = false;
drawFIMAPVPivotsAnalysisTrends = false;
drawFIMAPVPivotsAnalysisPivots = false;
//
drawFIMASARPivotsAnalysis = false;
drawFIMASARPivotsAnalysisZones = false;
drawFIMASARPivotsAnalysisTrends = false;
drawFIMASARPivotsAnalysisPivots = false;
//
drawFIMAZigZagPivotsAnalysis = false;
drawFIMAZigZagPivotsAnalysisZones = false;
drawFIMAZigZagPivotsAnalysisTrends = false;
drawFIMAZigZagPivotsAnalysisPivots = false;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
drawPiercingPattern = true;
swingTrendRayLeft = false;
swingTrendRayRight = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
/**
* Configure for Full Drawing ...
*/
void FullDraw()
{
//
Default();
//
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
swingTrendRayLeft = true;
swingTrendRayRight = true;
drawPiercingPattern = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
//
};
Binary file not shown.
@@ -0,0 +1,792 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Library
// -------------------------------------------------
// Name: XCXFIMAEALib ...
// Description: XFIMAEA Library ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMAEA Library"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
#include "../../Helpers/x-saherelm.xfima.helper.mq5"
#include "../../Libraries/x-saherelm.x-pivot.analysis.lib.mq5"
//
// Definitions ...
/**
* Configure Market Structure Detection ...
**/
struct XFIMAPatternDetectorConfig
{
//
// Props ...
//
// Flags ...
//
bool detectSupport;
bool detectResistance;
//
bool detectSwingTrend;
//
bool detectOB;
bool detectFVG;
//
bool detectStarPattern;
bool detectFlagPattern;
bool detectRisingPattern;
bool detectPiercingPattern;
bool detectSignalKeyBarPattern;
//
bool detectPinned;
bool detectMomentum;
bool detectEngulfed;
bool detectTrueGaped;
//
bool analyseFIMAPVPivots;
bool analyseFIMASARPivots;
bool analyseFIMAZigZagPivots;
//
bool detectMACrosses;
double validMACrossDiffMultiplier;
//
bool detectHKSwitches;
bool detectSARSwitches;
//
// Configs ...
//
// OB / FVG ...
int obLoopback;
int fvgLoopback;
//
// Trending ...
int trendingNumberOfSwings;
int trendingSwingShoulders;
//
int recentlyPatternsMaxLookupLength;
int recentlyPatternsMaxAllowedCollecting;
//
// Support and Resistance ...
int recentlyZonesMaxLookupLength;
int supportAndResistanceValidationLength;
int minAllowdSupportAndResistanceStrength;
int supportAndResistanceMaxAllowedLoopback;
int supportAndResistanceBreakeValidationLength;
//
// TrueGap ...
double truwGapApprovedPointMultiplier;
//
// Flag Pattern ...
int flagPatternMinimumPullbackBars;
//
// Momentum Bar ...
int momentumBarRangeLength;
double momentumBarApprovedMultiplier;
//
// Pinned Bar ...
double pinnedBaarShadowApprovedMultiplier;
double pinnedBarMinimumPinBarRangeMultiplier;
bool pinnedBarForceDirection;
//
// SignalKey Bar ...
double signalKeyBarShadowApprovedMultiplier;
double signalKeyBarMinimumPinBarRangeMultiplier;
bool signalKeyBarForceDirection;
//
// Analyser ...
int pvPivotsValidationLength;
int numberOfRequiredPivotsForAnalysis;
int maxAllowedLoopbackLengthForAnalysis;
//
// Constructor ...
XFIMAPatternDetectorConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
detectOB = false;
detectFVG = false;
detectSupport = false;
detectResistance = false;
detectSwingTrend = false;
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
analyseFIMAPVPivots = false;
analyseFIMASARPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = false;
validMACrossDiffMultiplier = 0;
//
detectHKSwitches = false;
detectSARSwitches = false;
//
obLoopback = 0;
fvgLoopback = 0;
trendingNumberOfSwings = 0;
trendingSwingShoulders = 0;
recentlyZonesMaxLookupLength = 0;
recentlyPatternsMaxLookupLength = 0;
recentlyPatternsMaxAllowedCollecting = 0;
supportAndResistanceValidationLength = 0;
minAllowdSupportAndResistanceStrength = 0;
supportAndResistanceMaxAllowedLoopback = 0;
supportAndResistanceBreakeValidationLength = 0;
truwGapApprovedPointMultiplier = 0;
flagPatternMinimumPullbackBars = 0;
momentumBarRangeLength = 0;
momentumBarApprovedMultiplier = 0;
pinnedBaarShadowApprovedMultiplier = 0;
pinnedBarMinimumPinBarRangeMultiplier = 0;
pinnedBarForceDirection = false;
signalKeyBarShadowApprovedMultiplier = 0;
signalKeyBarMinimumPinBarRangeMultiplier = 0;
signalKeyBarForceDirection = false;
pvPivotsValidationLength = 0;
numberOfRequiredPivotsForAnalysis = 0;
maxAllowedLoopbackLengthForAnalysis = 0;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
//
// OB / FVG ...
detectOB = false;
detectFVG = false;
//
// Support and Resistances ...
detectSupport = false;
detectResistance = false;
detectSwingTrend = false;
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMASARPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = true;
validMACrossDiffMultiplier = 1;
//
detectHKSwitches = true;
detectSARSwitches = true;
//
// OB / FVg ...
obLoopback = 5;
fvgLoopback = 5;
//
// Trending ...
trendingNumberOfSwings = 3;
trendingSwingShoulders = 11;
//
// Support and Resistance ...
recentlyZonesMaxLookupLength = 100;
recentlyPatternsMaxLookupLength = 50;
recentlyPatternsMaxAllowedCollecting = 20;
supportAndResistanceValidationLength = 100;
minAllowdSupportAndResistanceStrength = 1;
supportAndResistanceMaxAllowedLoopback = 1500;
supportAndResistanceBreakeValidationLength = 4;
//
// TrueGap ...
truwGapApprovedPointMultiplier = 1;
//
// Flag Pattern ...
flagPatternMinimumPullbackBars = 3;
//
// Momentum Bar ...
momentumBarRangeLength = 3;
momentumBarApprovedMultiplier = 2;
//
// Pinned Bar ...
pinnedBaarShadowApprovedMultiplier = 3;
pinnedBarMinimumPinBarRangeMultiplier = 4;
pinnedBarForceDirection = false;
//
// SignalKey Bar ...
signalKeyBarShadowApprovedMultiplier = 3;
signalKeyBarMinimumPinBarRangeMultiplier = 4;
signalKeyBarForceDirection = false;
//
// Length ...
pvPivotsValidationLength = 10;
numberOfRequiredPivotsForAnalysis = 50;
maxAllowedLoopbackLengthForAnalysis = 1500;
}
/**
* Full Detection Model ...
*/
void FullDetect()
{
//
// OB / FVG ...
detectOB = true;
detectFVG = true;
//
// Support and Resistances ...
detectSupport = true;
detectResistance = true;
detectSwingTrend = true;
//
// Patterns ...
detectStarPattern = true;
detectFlagPattern = true;
detectRisingPattern = true;
detectPiercingPattern = true;
detectSignalKeyBarPattern = true;
//
// Bars ...
detectPinned = true;
detectMomentum = true;
detectEngulfed = true;
detectTrueGaped = true;
//
// Analysers ...
analyseFIMAPVPivots = true;
analyseFIMASARPivots = true;
analyseFIMAZigZagPivots = true;
//
detectMACrosses = true;
detectHKSwitches = true;
detectSARSwitches = true;
}
/**
* Default Config, by turn off all detecting flags ...
*/
void OffDetectors()
{
//
// OB / FVG ...
detectOB = false;
detectFVG = false;
//
// Support and Resistances ...
detectSupport = false;
detectResistance = false;
detectSwingTrend = false;
//
// Patterns ...
detectStarPattern = false;
detectFlagPattern = false;
detectRisingPattern = false;
detectPiercingPattern = false;
detectSignalKeyBarPattern = false;
//
// Bars ...
detectPinned = false;
detectMomentum = false;
detectEngulfed = false;
detectTrueGaped = false;
//
// Analysers ...
analyseFIMAPVPivots = false;
analyseFIMASARPivots = false;
analyseFIMAZigZagPivots = false;
//
detectMACrosses = false;
detectHKSwitches = false;
detectSARSwitches = false;
}
//
};
/**
* XFIMA Base Market Structure ...
* AnalyseMarket result ...
**/
struct XFIMAMarketStructure
{
//
XOHCL bar;
//
XBoxZone ob;
XBoxZone fvg;
XBoxZone support;
XBoxZone resistance;
//
XBoxZone obs[];
XBoxZone fvgs[];
XBoxZone supports[];
XBoxZone resistances[];
//
XPivot pinBars[];
XPivot engulfBars[];
XPivot trueGapBars[];
XPivot momentumBars[];
//
XBoxZone flagPatterns[];
XBoxZone starPatterns[];
XBoxZone risingPatterns[];
XBoxZone piercingPatterns[];
XBoxZone signalKeyBarPatterns[];
//
// Previous Support or Resistance based on current ...
//
// Current Support is Touched => Prev Support;
// Current Resistance is Touched => Prev Resistance;
XBoxZone fakeBreakedZone;
//
XBoxZone recentlyTestedZones[];
XBoxZone recentlyBreakedZones[];
//
// Analysis ...
XPivotAnalysis pvAnalysis;
XPivotAnalysis sarAnalysis;
XPivotAnalysis zigzagAnalysis;
//
ENUM_X_DIRECTION pinnedDir;
ENUM_X_DIRECTION momentumDir;
ENUM_X_DIRECTION engulfedDir;
ENUM_X_DIRECTION trueGapedDir;
//
XOHCL flagSwing;
ENUM_X_DIRECTION flagPatternDir;
//
XOHCL trendSwings[];
ENUM_X_DIRECTION trendDir;
//
ENUM_X_DIRECTION starPatternDir;
ENUM_X_DIRECTION risingPatternDir;
ENUM_X_DIRECTION piercingPatternDir;
ENUM_X_DIRECTION signalKeyBarPatternDir;
//
ENUM_X_DIRECTION maCrossDir;
XPivot maCrosses[];
//
ENUM_X_DIRECTION hkSwitchDir;
XPivot hkSwitches[];
//
ENUM_X_DIRECTION sarSwitchDir;
XPivot sarSwitches[];
//
// Constructor ...
XFIMAMarketStructure()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
ob.Clean();
fvg.Clean();
support.Clean();
resistance.Clean();
//
fakeBreakedZone.Clean();
//
bar.Clean();
flagSwing.Clean();
//
pvAnalysis.Clean();
sarAnalysis.Clean();
zigzagAnalysis.Clean();
//
trendDir = X_DIRECTION_NONE;
pinnedDir = X_DIRECTION_NONE;
momentumDir = X_DIRECTION_NONE;
engulfedDir = X_DIRECTION_NONE;
trueGapedDir = X_DIRECTION_NONE;
flagPatternDir = X_DIRECTION_NONE;
starPatternDir = X_DIRECTION_NONE;
risingPatternDir = X_DIRECTION_NONE;
piercingPatternDir = X_DIRECTION_NONE;
signalKeyBarPatternDir = X_DIRECTION_NONE;
//
maCrossDir = X_DIRECTION_NONE;
SpecifiedClean(maCrosses);
//
hkSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(hkSwitches);
//
sarSwitchDir = X_DIRECTION_NONE;
SpecifiedClean(sarSwitches);
//
SpecifiedClean(obs);
SpecifiedClean(fvgs);
SpecifiedClean(pinBars);
SpecifiedClean(supports);
SpecifiedClean(engulfBars);
SpecifiedClean(resistances);
SpecifiedClean(trueGapBars);
SpecifiedClean(momentumBars);
SpecifiedClean(flagPatterns);
SpecifiedClean(starPatterns);
SpecifiedClean(risingPatterns);
SpecifiedClean(piercingPatterns);
SpecifiedClean(signalKeyBarPatterns);
//
SpecifiedClean(trendSwings);
SpecifiedClean(recentlyTestedZones);
SpecifiedClean(recentlyBreakedZones);
//
ZeroMemory(this);
}
//
// Checker Functions ...
//
};
/**
* Configure Market Structure Drawer ...
**/
struct XFIMAMarketStructureDrawerConfig
{
//
// Props ...
//
bool drawOB; // Current Order Block ...
bool drawFVG; // Current Fair Value Gap ...
//
bool drawSupport; // Detected Supports ...
bool drawResistance; // Detected Resistances ...
//
bool drawSwingTrend; // Swing Trend ...
bool swingTrendRayLeft; // Ray Left Swing Trend ...
bool swingTrendRayRight; // Ray Right Swing Trend ...
//
// Draw Current Detected Patterns ...
//
bool drawPinned;
bool drawMomentum;
bool drawEngulfed;
bool drawTrueGaped;
//
bool drawStarPattern;
bool drawFlagPattern;
bool drawRisingPattern;
bool drawPiercingPattern;
bool drawSignalKeyBarPattern;
//
// Draw Recently Zones ...
bool drawRecentPatterns;
bool drawFakeBreakedZone;
bool drawRecentlyTestedZones;
bool drawRecentlyBreakedZones;
//
// Draw Analysis Pivots ...
//
// XPV ...
bool drawFIMAPVPivotsAnalysis;
bool drawFIMAPVPivotsAnalysisZones;
bool drawFIMAPVPivotsAnalysisTrends;
bool drawFIMAPVPivotsAnalysisPivots;
//
// XSAR ...
bool drawFIMASARPivotsAnalysis;
bool drawFIMASARPivotsAnalysisZones;
bool drawFIMASARPivotsAnalysisTrends;
bool drawFIMASARPivotsAnalysisPivots;
//
// XZIGZAG ...
bool drawFIMAZigZagPivotsAnalysis;
bool drawFIMAZigZagPivotsAnalysisZones;
bool drawFIMAZigZagPivotsAnalysisTrends;
bool drawFIMAZigZagPivotsAnalysisPivots;
//
// Constructor ...
XFIMAMarketStructureDrawerConfig()
{
Clean();
}
//
// Tools ...
/**
* Cleanup Model ...
*/
void Clean()
{
//
drawOB = false;
drawFVG = false;
drawPinned = false;
drawMomentum = false;
drawSupport = false;
drawEngulfed = false;
drawTrueGaped = false;
drawResistance = false;
drawSwingTrend = false;
drawStarPattern = false;
drawFlagPattern = false;
swingTrendRayLeft = false;
drawRisingPattern = false;
swingTrendRayRight = false;
drawPiercingPattern = false;
drawSignalKeyBarPattern = false;
//
drawRecentPatterns = false;
drawFakeBreakedZone = false;
drawRecentlyTestedZones = false;
drawRecentlyBreakedZones = false;
//
drawFIMAPVPivotsAnalysis = false;
drawFIMAPVPivotsAnalysisZones = false;
drawFIMAPVPivotsAnalysisTrends = false;
drawFIMAPVPivotsAnalysisPivots = false;
//
drawFIMASARPivotsAnalysis = false;
drawFIMASARPivotsAnalysisZones = false;
drawFIMASARPivotsAnalysisTrends = false;
drawFIMASARPivotsAnalysisPivots = false;
//
drawFIMAZigZagPivotsAnalysis = false;
drawFIMAZigZagPivotsAnalysisZones = false;
drawFIMAZigZagPivotsAnalysisTrends = false;
drawFIMAZigZagPivotsAnalysisPivots = false;
//
ZeroMemory(this);
}
/**
* Default Model ...
*/
void Default()
{
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
drawPiercingPattern = true;
swingTrendRayLeft = false;
swingTrendRayRight = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
/**
* Configure for Full Drawing ...
*/
void FullDraw()
{
//
Default();
//
drawOB = true;
drawFVG = true;
drawPinned = true;
drawMomentum = true;
drawSupport = true;
drawEngulfed = true;
drawTrueGaped = true;
drawResistance = true;
drawSwingTrend = true;
drawStarPattern = true;
drawFlagPattern = true;
drawRisingPattern = true;
swingTrendRayLeft = true;
swingTrendRayRight = true;
drawPiercingPattern = true;
drawSignalKeyBarPattern = true;
//
drawRecentPatterns = true;
drawFakeBreakedZone = true;
drawRecentlyTestedZones = true;
drawRecentlyBreakedZones = true;
//
drawFIMAPVPivotsAnalysis = true;
drawFIMAPVPivotsAnalysisZones = true;
drawFIMAPVPivotsAnalysisTrends = true;
drawFIMAPVPivotsAnalysisPivots = true;
//
drawFIMASARPivotsAnalysis = true;
drawFIMASARPivotsAnalysisZones = true;
drawFIMASARPivotsAnalysisTrends = true;
drawFIMASARPivotsAnalysisPivots = true;
//
drawFIMAZigZagPivotsAnalysis = true;
drawFIMAZigZagPivotsAnalysisZones = true;
drawFIMAZigZagPivotsAnalysisTrends = true;
drawFIMAZigZagPivotsAnalysisPivots = true;
}
//
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,495 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class
// -------------------------------------------------
// Name: XCXFIMAPoiDetector ...
// Description: XFIMA POI Detector Class ...
//
//
// Maintainer:
// ------------
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
//
//////////////////////////////////////////////////////
//
// Global Properties ...
#property library
#property copyright "Copyright 2023, SaherElm IT Center"
#property link "https://saherelm.ir"
#property version "1.00"
#property description "SaherElm XFIMA POI Detector Class"
#property strict
//
// Imports ...
#include "../../Classes/x-saherelm.base.class.mq5"
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
#include "../../Classes/x-saherelm.x-market.pattern.class.mq5"
#include "../Libraries/x-saherelm.xfima.lib.mq5"
//
// Implementation ...
class XCXFIMAPOIDetector : public XCMarketPatternDetector
{
//
// Public ...
public:
//
// Props ...
XCBarAnalyser *barAnalyser; // Bar Analyser ...
XCXFIMAHelper *fimaHelper; // XFIMA Helper ...
//
// Constructor ...
XCXFIMAPOIDetector(
XCXFIMAHelper *_fimaHelper //
) : XCMarketPatternDetector()
{
//
barAnalyser = new XCBarAnalyser();
fimaHelper = _fimaHelper;
}
//
// Deconstructor ...
~XCXFIMAPOIDetector()
{
Destroy();
}
//
// Actions and Tools ...
//
// Pivot Analysors ...
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
*
* @return ( bool )
*/
bool AnalysePVPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractPVPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength, // Max Allowed Loopback ...
validationLength // Validation Length ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XPV",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
* @param validationLength: int, Specified Pivots Validation Length ignore if <= 0 ...
*
* @return ( bool )
*/
bool AnalyseMAPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500,
int validationLength = 0 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractMAPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength, // Max Allowed Loopback ...
validationLength // Validation Length ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XMA",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( bool )
*/
bool AnalyseSARPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractSARPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength // Max Allowed Loopback ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XSAR",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Analyse Market based on Specified Kind of Pivots ...
*
* @param analysis: XPivotAnalysis, reference to hold result ...
* @param barIndex: int, Bar Index ...
* @param requiredNumberOFPivots: int, Specified which Number of Pivots must be Extracted ...
* @param maxAllowedLoopbackLength: int, Specified Maximum Loopback Length for Pivot Extraction ...
*
* @return ( bool )
*/
bool AnalyseZigZagPivots(
XPivotAnalysis &analysis,
int barIndex = 0,
int requiredNumberOFPivots = 50,
int maxAllowedLoopbackLength = 1500 //
)
{
//
bool result = false;
//
// Prepare ...
analysis.Clean();
//
// Reading Pivots ...
XPivot pivots[];
int count = fimaHelper.ExtractZigZagPivots(
pivots, // Result ...
barIndex, // Bar Index ...
requiredNumberOFPivots, // Required Number of Pivots ...
maxAllowedLoopbackLength // Max Allowed Loopback ...
);
result = IsValidSize(count);
if (!result)
{
//
SpecifiedClean(pivots);
return result;
}
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
//
// Initialize Analysis ...
result = analysis.Init(
"XFIMA_XZG",
symbol,
period,
pivots //
);
//
// Cleanup Resources ...
if (!result)
{
analysis.Clean();
}
SpecifiedClean(pivots);
//
return result;
}
/**
* Destroy ...
*/
void Destroy()
{
//
delete barAnalyser;
ZeroMemory(barAnalyser);
}
//
// Testers ...
/**
* Analyse Market based on Specified Bar ...
*
* @param structure: XFIMAMarketStructure, reference to holds result ...
* @param config: XFIMAMarketStructureConfig, reference to Configure Detector ...
* @param barIndex: int, Bar Index ...
*/
void AnalyseMarket(
XFIMAMarketStructure &structure,
XFIMAMarketStructureConfig &config,
int barIndex = 0 //
)
{
//
// Prepare ...
structure.Clean();
//
// Normalize ...
barIndex = NormalizeInt(barIndex, 0);
//
bool has = false;
//
string symbol = fimaHelper.GetSymbol();
ENUM_TIMEFRAMES period = fimaHelper.GetPeriod();
has = structure.bar.Init(
symbol,
period,
barIndex //
);
if (!has)
{
//
structure.Clean();
return;
}
//
// Reading Bar Patterns ...
XOHCL iBar;
XPatternAnalysis iPatternAnalysis;
for (int i = barIndex; i < barIndex + config.loopback; i++)
{
//
// Cleanup ...
iBar.Clean();
iPatternAnalysis.Clean();
//
// Initialize Indexed Bar ...
//
has = structure.bar.BarAt(i, iBar);
if (!has)
{
break;
}
//
// Analyse Indexed Bar ...
has = AnalyseBarPatterns(iBar, iPatternAnalysis, config.barsAnalysisConfig);
if (has)
{
//
AddRef(
iPatternAnalysis,
structure.barsAnalysis //
);
//
if (i == barIndex)
{
structure.barAnalysis = iPatternAnalysis;
}
}
//
// Check Satisfied ...
has = ArraySize(structure.barsAnalysis) >= config.requiredPivots;
if (has)
{
break;
}
}
//
// Handle Pivot Analysis ...
//
// XPV ...
if (config.analysePVPivots)
{
//
// Reading Pivots ...
has = AnalysePVPivots(
structure.pvAnalysis,
barIndex,
config.requiredPivots,
config.loopback,
config.pvPivotsValidationLength //
);
if (!has)
{
structure.pvAnalysis.Clean();
}
}
//
// XZG ...
if (config.analyseZGPivots)
{
//
// Reading Pivots ...
has = AnalyseZigZagPivots(
structure.zgAnalysis,
barIndex,
config.requiredPivots,
config.loopback //
);
if (!has)
{
structure.zgAnalysis.Clean();
}
}
//
// Cleanup ...
iBar.Clean();
iPatternAnalysis.Clean();
}
//
// Protected ...
protected:
//
// Props ...
//
// Private ...
private:
//
//
};
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,826 @@
/**
* Analyse Market based on Specified Bar ...
*
* @param forBar: XOHCL, reference Specified Bar for Analyse Market ...
* @param structure: XFIMAMarketStructure, reference to holds result ...
* @param config: XFIMAPatternDetectorConfig, reference to Configure Detector ...
*/
void AnalyseMarket(
XOHCL &forBar,
XFIMAMarketStructure &structure,
XFIMAPatternDetectorConfig &config //
)
{
//
// Prepare ...
structure.Clean();
//
// Validate ...
if (!forBar.IsValid())
{
return;
}
//
// Do Analysis ...
//
structure.bar = forBar;
//
int idx = -1;
bool has = false;
int maxAllowedCollecting = 50;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
// Detecting POI Based on Config ...
//
// Order Block ...
if (config.detectOB)
{
//
bool isOB = HasOB(
forBar,
iDir,
structure.ob,
config.obLoopback //
);
bool isBullishOB = isOB &&
IsSpecifiedBullish(iDir);
bool isBearishOB = isOB &&
IsSpecifiedBearish(iDir);
if (!isOB)
{
structure.ob.Clean();
}
//
// Detect Touches ...
if (isOB)
{
//
AddIfNotExists(
structure.ob,
obs,
maxAllowedCollecting //
);
//
XOHCL pBar;
bool has = forBar.GetPreviousBar(pBar);
if (has)
{
//
structure.isOBTouched =
isBullishOB
? pBar.low < structure.ob.upper
: pBar.high > structure.ob.lower;
}
//
pBar.Clean();
}
}
//
// Fair Value Gap ...
if (config.detectFVG)
{
//
bool isFVG = HasFVG(
forBar,
iDir,
structure.fvg,
config.fvgLoopback //
);
bool isBullishFVG = isFVG &&
IsSpecifiedBullish(iDir);
bool isBearishFVG = isFVG &&
IsSpecifiedBearish(iDir);
if (!isFVG)
{
structure.fvg.Clean();
}
//
// Detect Touches ...
if (isFVG)
{
//
AddIfNotExists(
structure.fvg,
fvgs,
maxAllowedCollecting //
);
//
XOHCL pBar;
bool has = forBar.GetPreviousBar(pBar);
if (has)
{
//
structure.isFVGTouched =
isBullishFVG
? pBar.low < structure.fvg.upper
: pBar.high > structure.fvg.lower;
}
//
pBar.Clean();
}
}
//
// Checking Momentum Bar ...
if (config.detectMomentum)
{
//
bool isMomentum = IsMomentumBar(
forBar,
iDir,
config.momentumBarRangeLength,
config.momentumBarApprovedMultiplier //
);
bool isBullishMomentum = isMomentum &&
IsSpecifiedBullish(iDir);
bool isBearishMomentum = isMomentum &&
IsSpecifiedBearish(iDir);
if (isMomentum)
{
structure.momentumDir = iDir;
}
}
//
// Checking Engulfed Bar ...
if (config.detectEngulfed)
{
//
bool isEngulfed = IsEngulfedBar(
forBar,
iDir //
);
bool isBullishEngulfed = isEngulfed &&
IsSpecifiedBullish(iDir);
bool isBearishEngulfed = isEngulfed &&
IsSpecifiedBearish(iDir);
if (isEngulfed)
{
structure.engulfedDir = iDir;
}
}
//
// Checking TruGaped Bar ...
if (config.detectTrueGaped)
{
//
bool isTrueGaped = IsTrueGapedBar(
forBar,
iDir,
config.truwGapApprovedPointMultiplier //
);
bool isBullishTrueGaped = isTrueGaped &&
IsSpecifiedBullish(iDir);
bool isBearishTrueGaped = isTrueGaped &&
IsSpecifiedBearish(iDir);
if (isTrueGaped)
{
structure.trueGapedDir = iDir;
}
}
//
// Checking Pinned Bar ...
if (config.detectPinned)
{
//
bool isPinned = IsPinnedBar(
forBar,
iDir,
config.pinnedBaarShadowApprovedMultiplier,
config.pinnedBarMinimumPinBarRangeMultiplier,
config.pinnedBarForceDirection //
);
bool isBullishPinned = isPinned &&
IsSpecifiedBullish(iDir);
bool isBearishPinned = isPinned &&
IsSpecifiedBearish(iDir);
if (isPinned)
{
structure.pinnedDir = iDir;
}
}
//
// Checking Star Pattern ...
if (config.detectStarPattern)
{
//
bool isStarPattern = IsStartPattern(
forBar,
iDir //
);
bool isBullishStarPattern = isStarPattern &&
IsSpecifiedBullish(iDir);
bool isBearishStarPattern = isStarPattern &&
IsSpecifiedBearish(iDir);
if (isStarPattern)
{
structure.starPatternDir = iDir;
}
}
//
// Checking Piercing Pattern ...
if (config.detectPiercingPattern)
{
//
bool isPiercingPattern = IsPiercingPattern(
forBar,
iDir //
);
bool isBullishPiercingPattern = isPiercingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishPiercingPattern = isPiercingPattern &&
IsSpecifiedBearish(iDir);
if (isPiercingPattern)
{
structure.piercingPatternDir = iDir;
}
}
//
// Checking Rising Pattern ...
if (config.detectRisingPattern)
{
//
bool isRisingPattern = IsRisingPattern(
forBar,
iDir //
);
bool isBullishRisingPattern = isRisingPattern &&
IsSpecifiedBullish(iDir);
bool isBearishRisingPattern = isRisingPattern &&
IsSpecifiedBearish(iDir);
if (isRisingPattern)
{
structure.risingPatternDir = iDir;
}
}
//
// Checking Flag Pattern ...
if (config.detectFlagPattern)
{
//
XOHCL swingBar;
bool isFlagPattern = IsFlagPattern(
forBar,
iDir,
swingBar,
config.flagPatternMinimumPullbackBars //
);
bool isBullishFlagPattern = isFlagPattern &&
IsSpecifiedBullish(iDir);
bool isBearishFlagPattern = isFlagPattern &&
IsSpecifiedBearish(iDir);
if (isFlagPattern)
{
//
structure.flagSwing = swingBar;
structure.flagPatternDir = iDir;
}
swingBar.Clean();
}
//
// Detect SignalKey Bar Pattern ...
if (config.detectSignalKeyBarPattern)
{
//
bool isSignalKeyBar = IsSignalKeyBarPattern(
forBar,
iDir,
config.signalKeyBarShadowApprovedMultiplier,
config.signalKeyBarMinimumPinBarRangeMultiplier,
config.signalKeyBarForceDirection //
);
bool isBullishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBullish(iDir);
bool isBearishSignalKeyBar = isSignalKeyBar &&
IsSpecifiedBearish(iDir);
if (isSignalKeyBar)
{
structure.signalKeyBarPatternDir = iDir;
}
}
//
// Detect Swing Trend ...
if (config.detectSwingTrend)
{
//
XOHCL swings[];
bool hasSwingTrend = HasSwingTrend(
forBar,
iDir,
swings,
config.trendingNumberOfSwings,
config.trendingSwingShoulders //
);
bool hasBullishSwingTrend = hasSwingTrend &&
IsSpecifiedBullish(iDir);
bool hasBearishSwingTrend = hasSwingTrend &&
IsSpecifiedBearish(iDir);
if (hasSwingTrend)
{
//
Copy(
swings,
structure.trendSwings //
);
structure.trendDir = iDir;
}
SpecifiedClean(swings);
}
//
// Detect Supports ...
if (config.detectSupport)
{
//
XOHCL support;
bool hasSupport = HasSupport(
forBar,
support,
config.supportAndResistanceValidationLength,
config.supportAndResistanceMaxAllowedLoopback //
);
if (hasSupport)
{
//
XBoxZone supportBox;
has = ToSupportBox(support, supportBox);
//
// Validate Zone Strength if Provided ...
if (config.minAllowdSupportAndResistanceStrength > 0)
{
//
has = has &&
ValidateStrength(
supportBox,
config.minAllowdSupportAndResistanceStrength //
);
}
//
if (has)
{
//
AddIfNotExists(
supportBox,
supports,
maxAllowedCollecting //
);
//
structure.support = supportBox;
}
//
// Check for Support Touches ...
XOHCL pBar;
has = has &&
forBar.GetPreviousBar(pBar);
if (has)
{
structure.isSupportTouched = pBar.low < supportBox.upper;
}
//
pBar.Clean();
supportBox.Clean();
}
support.Clean();
}
//
// Detect Resistance ...
if (config.detectResistance)
{
//
XOHCL resistance;
bool hasResistance = HasResistance(
forBar,
resistance,
config.supportAndResistanceValidationLength,
config.supportAndResistanceMaxAllowedLoopback //
);
if (hasResistance)
{
//
XBoxZone resistanceBox;
has = ToResistanceBox(resistance, resistanceBox);
//
// Validate Zone Strength if Provided ...
if (config.minAllowdSupportAndResistanceStrength > 0)
{
//
has = has &&
ValidateStrength(
resistanceBox,
config.minAllowdSupportAndResistanceStrength //
);
}
//
if (has)
{
//
AddIfNotExists(
resistanceBox,
resistances,
maxAllowedCollecting //
);
//
structure.resistance = resistanceBox;
}
//
// Check for Resistance Touches ...
XOHCL pBar;
has = has &&
forBar.GetPreviousBar(pBar);
if (has)
{
structure.isResistanceTouched = pBar.high > resistanceBox.upper;
}
//
pBar.Clean();
resistanceBox.Clean();
}
resistance.Clean();
}
//
// Analysers ...
//
// Analyse Based on PV ...
if (config.analyseFIMAPVPivots)
{
//
XPivotAnalysis analysis;
has = AnalysePVPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
config.pvPivotsValidationLength // Validation Length ...
);
if (has)
{
structure.pvAnalysis = analysis;
}
}
//
// Analyse Based on MA ...
if (config.analyseFIMAMAPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseMAPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis, // Max Allowed Loopback ...
config.pvPivotsValidationLength // Validation Length ...
);
if (has)
{
structure.maAnalysis = analysis;
}
}
//
// Analyse Based on SAR ...
if (config.analyseFIMASARPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseSARPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
);
if (has)
{
structure.sarAnalysis = analysis;
}
}
//
// Analyse Based on ZigZag ...
if (config.analyseFIMAZigZagPivots)
{
//
XPivotAnalysis analysis;
has = AnalyseZigZagPivots(
analysis, // Result ...
forBar.Index(), // Bar Index ...
config.numberOfRequiredPivotsForAnalysis, // Required Number of Pivots ...
config.maxAllowedLoopbackLengthForAnalysis // Max Allowed Loopback ...
);
if (has)
{
structure.zigzagAnalysis = analysis;
}
}
//
// COMPLEX Actions ...
//
// Lockup For Previous Zone ...
has = structure.isSupportTouched ||
structure.isResistanceTouched;
if (has)
{
//
if (structure.isSupportTouched)
{
//
idx = GetYoungestBefore(
structure.support.from,
supports //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = supports[idx];
}
}
else if (structure.isResistanceTouched)
{
//
idx = GetYoungestBefore(
structure.resistance.from,
resistances //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = resistances[idx];
}
}
}
//
// Detect Recently Tested Zones ...
if ((config.detectSupport ||
config.detectResistance) &&
config.recentlyTestedZonesMaxLookup > 0)
{
//
XOHCL iBar;
int idx = -1;
bool has = false;
//
int start = forBar.Index() + 1;
int end = start + config.recentlyTestedZonesMaxLookup;
for (int i = start; i < end; i++)
{
//
// Initialize Indexed Bar ...
has = forBar.BarAt(i, iBar);
if (!has)
{
continue;
}
//
// Selecting Support and Resistances ...
//
// Supports ...
idx = GetYoungestBefore(iBar.time, supports);
has = IsValidIndex(idx);
if (has)
{
//
// Check Testing ...
has = IsTested(iBar, supports[idx]);
if (has)
{
//
AddIfNotExists(
supports[idx],
structure.recentlyTestedZones //
);
}
}
//
// Resistances ...
idx = GetYoungestBefore(iBar.time, resistances);
has = IsValidIndex(idx);
if (has)
{
//
// Check Testing ...
has = IsTested(iBar, resistances[idx]);
if (has)
{
//
AddIfNotExists(
resistances[idx],
structure.recentlyTestedZones //
);
}
}
}
}
//
// Checkup for FakeBreaked Zones ...
if (config.detectSupport ||
config.detectResistance)
{
//
// Retrieve Previous Bar ...
int idx = -1;
XOHCL pForBar;
XOHCL breakerBar;
XBoxZone pSupport;
XOHCL pBreakerBar;
XBoxZone pResistance;
//
// Selecting Previously Touched Support / Resistance ...
has = forBar.GetPreviousBar(pForBar);
if (has)
{
//
// Detecting Nearest Above Lows Support ...
idx = GetYoungestAbove(
pForBar.low,
supports //
);
has = IsValidIndex(idx) &&
IsBreaked(
forBar,
supports[idx] //
);
if (has)
{
pSupport = supports[idx];
}
//
// Detecting Nearest Below Highs Resistance ...
idx = GetYoungestBelow(
pForBar.high,
resistances //
);
has = IsValidIndex(idx) &&
IsBreaked(
forBar,
resistances[idx] //
);
if (has)
{
pResistance = resistances[idx];
}
}
//
// Check at least a zone Exists ...
// Selecting pTestedZone ...
has = pSupport.IsValid() ||
pResistance.IsValid();
if (has)
{
//
// Support ...
has = pSupport.IsValid();
if (has)
{
//
structure.isPTest = true;
structure.pTestedZone = pSupport;
}
//
// Resistance ...
has = pResistance.IsValid();
if (has)
{
//
structure.isPTest = true;
structure.pTestedZone = pResistance;
}
}
//
// Check pTestedZone Existance ...
has = structure.isPTest &&
structure.pTestedZone.IsValid();
if (has)
{
//
// Get Breaker Bars ...
XOHCL breakerBars[];
int breakerBarsCount = GetBreakerBars(
structure.pTestedZone,
breakerBars //
);
has = IsValidSize(breakerBarsCount);
if (has)
{
//
idx = GetYoungestBar(breakerBars);
has = IsValidIndex(idx);
if (has)
{
breakerBar = breakerBars[idx];
}
}
//
SpecifiedClean(breakerBars);
}
//
// Check Zone Breaker Bar Exists ...
// Validate Zone Fake Breake Langth ...
has = breakerBar.IsValid();
if (has)
{
//
// Validate Breake Length ...
has = (breakerBar.Index() - pForBar.Index()) <= config.supportAndResistanceBreakeValidationLength;
}
//
// Cleanup Resources ...
//
if (!has)
{
//
structure.isPTest = false;
structure.pTestedZone.Clean();
}
pForBar.Clean();
pSupport.Clean();
breakerBar.Clean();
pBreakerBar.Clean();
pResistance.Clean();
}
}
//
// Lockup For Previous Zone ...
has = structure.isSupportTouched ||
structure.isResistanceTouched;
if (has)
{
//
if (structure.isSupportTouched)
{
//
idx = GetYoungestBefore(
structure.support.from,
supports //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = supports[idx];
}
}
else if (structure.isResistanceTouched)
{
//
idx = GetYoungestBefore(
structure.resistance.from,
resistances //
);
has = IsValidIndex(idx);
if (has)
{
structure.prevZone = resistances[idx];
}
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,641 @@
// //
// // Detect At lease Two PEAK and Two Vale ...
// XZigZagPoint tmpPoints[];
// Copy(
// points,
// tmpPoints //
// );
// //
// // Detect Highs ...
// //
// // Highest High ...
// //
// XZigZagPoint iZGPeak1;
// XZigZagPoint iZGPeak2;
// //
// // First ...
// int idx = GetHighest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_PEAK //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGPeak1 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Second ...
// idx = GetHighest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_PEAK //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGPeak2 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Detect Lows ...
// //
// XZigZagPoint iZGVale1;
// XZigZagPoint iZGVale2;
// //
// // First ...
// idx = GetLowest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_VALE //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGVale1 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Second ...
// idx = GetLowest(
// tmpPoints,
// X_ZIGZAG_POINT_TYPE_VALE //
// );
// result = IsValidIndex(idx);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// iZGVale2 = tmpPoints[idx];
// ArrayRemove(
// tmpPoints,
// idx,
// 1 //
// );
// //
// // Check Directions ...
// bool isBullish =
// //
// (iZGPeak1.time > iZGPeak2.time &&
// iZGVale1.time < iZGVale2.time)
// //
// ;
// bool isBearish =
// //
// (iZGPeak1.time < iZGPeak2.time &&
// iZGVale1.time > iZGVale2.time)
// //
// ;
// result =
// (isBullish && !isBearish) ||
// (isBearish && !isBullish);
// if (!result)
// {
// //
// Clean();
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
// //
// return result;
// }
// //
// // Setting Direction ...
// dir =
// isBullish
// ? X_DIRECTION_BULLISH
// : isBearish
// ? X_DIRECTION_BEARISH
// : X_DIRECTION_NONE;
// //
// // Setting Points ...
// Copy(
// points,
// pivots //
// );
//
// Cleanup Resources ...
// iZGPeak1.Clean();
// iZGPeak2.Clean();
// iZGVale1.Clean();
// iZGVale2.Clean();
// SpecifiedClean(tmpPoints);
/**
* Analyse Market Structure ...
*
* @param bar: XOHCL, Specified Bar ...
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
*
* @return ( bool )
*/
bool Analyse(
XOHCL &bar,
XZigZagPivot &_pivots[] //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasChild(_pivots) &&
bar.symbol == _pivots[0].symbol;
if (!result)
{
//
Clean();
return result;
}
//
// AssignSymbol and Period ...
time = bar.time;
symbol = bar.symbol;
period = bar.period;
Copy(_pivots, pivots);
//
// Calculate Peaks and Vales Regressions ...
//
// Peaks Processing ...
double mPeak = 0;
double bPeak = 0;
result = ValidateZigZagPivots(
mPeak,
bPeak,
_pivots,
X_ZIGZAG_PIVOT_TYPE_PEAK //
);
//
// Vales Processing ...
double mVale = 0;
double bVale = 0;
result =
result &&
ValidateZigZagPivots(
mVale,
bVale,
_pivots,
X_ZIGZAG_PIVOT_TYPE_VALE //
);
if (!result)
{
//
Clean();
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
//
return result;
}
// //
// // Extracting Pivots ...
// int numberOfPivots = 2;
// //
// // Reading Recent Peaks ...
// XZigZagPivot recentPeaks[];
// int recentPeaksCount = GetRecent(
// _pivots,
// recentPeaks,
// numberOfPivots,
// X_ZIGZAG_PIVOT_TYPE_PEAK //
// );
// //
// // Reading Recent Vales ...
// XZigZagPivot recentVales[];
// int recentValesCount = GetRecent(
// _pivots,
// recentVales,
// numberOfPivots,
// X_ZIGZAG_PIVOT_TYPE_VALE //
// );
// //
// // Validate Pivots ...
// result =
// recentPeaksCount >= numberOfPivots &&
// recentValesCount >= numberOfPivots;
// if (!result)
// {
// //
// Clean();
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
// //
// return result;
// }
// //
// // Detect Direction ...
// //
// int zIdx = 0;
// int pIdx = numberOfPivots - 1;
// //
// bool isBullish =
// recentPeaks[zIdx].value > recentPeaks[pIdx].value &&
// recentVales[zIdx].value > recentVales[pIdx].value;
// //
// bool isBearish =
// recentPeaks[zIdx].value < recentPeaks[pIdx].value &&
// recentVales[zIdx].value < recentVales[pIdx].value;
// //
// result = isBullish || isBearish;
// if (!result)
// {
// //
// Clean();
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
// //
// return result;
// }
// //
// dir =
// isBullish
// ? X_DIRECTION_BULLISH
// : X_DIRECTION_BEARISH;
//
// Calculate Support and Resistance ...
//
// Validate ...
result = IsValid();
if (!result)
{
Clean();
}
//
// SpecifiedClean(recentPeaks);
// SpecifiedClean(recentVales);
//
return result;
}
bool ValidateZigZagPivots(
double &_pivot,
double &_processed,
XZigZagPivot &_pivots[],
ENUM_X_ZIGZAG_POINT_TYPE _type //
)
{
//
bool result = false;
//
// Prepare ...
_pivot = 0;
_processed = 0;
//
// Validate ...
result = HasChild(_pivots);
if (!result)
{
return result;
}
//
// Define Required Variables for Calculations ...
double sumT = 0;
double sumP = 0;
double sumTP = 0;
double sumT2 = 0;
bool has = false;
int typeCount = 0;
//
// Loop Through Pivots to Calculate Specified
// Type Pivots Summaries ...
int count = ArraySize(_pivots);
for (int i = 0; i < count; i++)
{
//
// Check Type Passed ...
has =
!IsXValid(_type)
? true
: _type == _pivots[i].type;
if (!has)
{
continue;
}
//
typeCount++;
double iP = _pivots[i].value;
double iT = (double)_pivots[i].time;
//
sumT += iT;
sumP += iP;
sumTP += iT * iP;
sumT2 += iT * iP;
}
//
// Calculate Process Values ...
double denominator = typeCount * sumT2 - sumT * sumT;
if (denominator != 0)
{
//
_pivot = (typeCount * sumTP - sumT * sumP) / denominator;
_processed = (sumP - _pivot * sumT) / typeCount;
}
else
{
_processed = sumP / typeCount;
}
//
// Validating Result ...
result = _pivot > 0 &&
_processed > 0;
//
return result;
}
/**
* Analyse Market Structure ...
*
* @param bar: XOHCL, Specified Bar ...
* @param _pivots: XZigZagPivot, Specified ZigZag Points Collection ...
*
* @return ( bool )
*/
bool Analyse(
XOHCL &bar,
XZigZagPivot &_pivots[] //
)
{
//
bool result = false;
//
// Validate ...
result = bar.IsValid() &&
HasChild(_pivots) &&
bar.symbol == _pivots[0].symbol;
if (!result)
{
//
Clean();
return result;
}
//
// Assign Requirements ...
//
time = bar.time;
symbol = bar.symbol;
period = bar.period;
Copy(_pivots, pivots);
//
int oldestPeakIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
int oldestValeIdx = GetOldest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
int youngestPeakIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_PEAK);
int youngestValeIdx = GetYoungest(pivots, X_ZIGZAG_PIVOT_TYPE_VALE);
//
// Calculate Peaks and Vales Regressions ...
//
// Peaks Processing ...
double mPeak = 0;
double bPeak = 0;
bool hasPeak = ValidateZigZagPivots(
mPeak,
bPeak,
pivots,
X_ZIGZAG_PIVOT_TYPE_PEAK //
);
//
// Vales Processing ...
double mVale = 0;
double bVale = 0;
bool hasVale = ValidateZigZagPivots(
mVale,
bVale,
pivots,
X_ZIGZAG_PIVOT_TYPE_VALE //
);
//
// Validate Calculated requirements ...
result =
(hasPeak || hasVale) &&
(IsValidIndex(oldestPeakIdx) &&
IsValidIndex(oldestValeIdx) &&
IsValidIndex(youngestPeakIdx) &&
IsValidIndex(youngestValeIdx));
if (!result)
{
//
Clean();
return result;
}
//
// Calculating Values ...
//
peakToTime = pivots[youngestPeakIdx].time;
peakFromTime = pivots[oldestPeakIdx].time;
//
valeToTime = pivots[youngestValeIdx].time;
valeFromTime = pivots[oldestValeIdx].time;
//
// Check Different Senarios ...
// 1-Valid Peak and Valid Vale Exists ...
if (hasPeak && hasVale)
{
//
// When Slopes Have same Sign, Use Average Slope for Parallel Lines ...
if (mPeak * mVale > 0)
{
//
// Calculating Parallel Slopes ...
double slopeParallel = (mPeak + mVale) / 2;
double bParallelPeak = pivots[youngestPeakIdx].value - slopeParallel * (double)peakToTime;
double bParallelVale = pivots[youngestValeIdx].value - slopeParallel * (double)valeToTime;
//
// Peak ...
peakTo = slopeParallel * (double)peakToTime + bParallelPeak;
peakFrom = slopeParallel * (double)peakFromTime + bParallelPeak;
//
// Vale ...
valeTo = slopeParallel * (double)valeToTime + bParallelVale;
valeFrom = slopeParallel * (double)valeFromTime + bParallelVale;
}
else
//
// separate trendlines if slopes differ ...
{
//
// Peak ...
peakTo = mPeak * (double)peakToTime + bPeak;
peakFrom = mPeak * (double)peakFromTime + bPeak;
//
// Vale ...
valeTo = mVale * (double)valeToTime + bVale;
valeFrom = mVale * (double)valeFromTime + bVale;
}
}
else
//
// Only one of them Exists ...
{
//
// Valid Peak ...
if (hasPeak)
{
//
// Peak ...
peakTo = mPeak * (double)peakToTime + bPeak;
peakFrom = mPeak * (double)peakFromTime + bPeak;
}
//
// Valid Vale ...
if (hasVale)
{
//
// Vale ...
valeTo = mVale * (double)valeToTime + bVale;
valeFrom = mVale * (double)valeFromTime + bVale;
}
}
//
// Detecting Direction ...
//
bool isBullish =
valeTo > valeFrom ||
(valeTo > valeFrom &&
peakTo > peakFrom);
//
bool isBearish =
peakTo < peakFrom ||
(peakTo < peakFrom &&
valeTo < valeFrom);
//
// Validate When Only One Direction Exists ...
result =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
if (!result)
{
//
Clean();
return result;
}
//
dir =
isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
// Calculate Support and Resistance ...
//
// Validate ...
result = IsValid();
if (!result)
{
Clean();
}
//
return result;
}
@@ -0,0 +1,511 @@
//
// Testing Bar Zones ...
// XBoxZone barZones[];
// int barCounts = fima2Signaller.fimaHelper.ExtractBarZones(
// barZones,
// 1, // Bar Index ...
// 50, // Number of Zones ...
// 3, // Break Validation Length ...
// true, // Validate Fake Breakes ...
// 5, // Shadow Multiplier ...
// 1, // Strength ...
// 14 // Validation Length ...
// );
// if (IsValidSize(barCounts))
// {
// //
// // XCBoxObject *iObj;
// // for (int i = 0; i < barCounts; i++)
// // {
// // //
// // iObj = NULL;
// // bool isCreated = fima2Signaller.poiDrawer.DrawBox(
// // barZones[i],
// // iObj,
// // true, // Ignore At ...
// // barZones[i].type // Name ...
// // );
// // //
// // ZeroMemory(iObj);
// // }
// // //
// // Print("Bar Zones Detected ...");
// }
//
// Testing HK Zones ...
// XBoxZone hkZones[];
// int hkCounts = fima2Signaller.fimaHelper.ExtractHKZones(
// hkZones,
// 1, // Bar Index ...
// 50, // Number of Zones ...
// 5, // Shadow Multiplier ...
// 1, // Strength ...
// 14 // Validation Length ...
// );
// if (IsValidSize(hkCounts))
// {
// // //
// // XCBoxObject *iObj;
// // for (int i = 0; i < hkCounts; i++)
// // {
// // //
// // iObj = NULL;
// // bool isCreated = fima2Signaller.poiDrawer.DrawBox(
// // hkZones[i],
// // iObj,
// // true, // Ignore At ...
// // hkZones[i].type // Name ...
// // );
// // //
// // ZeroMemory(iObj);
// // }
// // //
// // Print("HK Zones Detected ...");
// }
//
// Testing XFIMA MA Pivots ...
// XPivot maPivots[];
// int maPivotsCount = fimaHelper.ExtractMAPivots(
// maPivots,
// 1, // Bar Index ...
// 50, // Number of Pivots ...
// 1 // Validation Diff ...
// );
// if (IsValidSize(maPivotsCount))
// {
// //
// // CArrayObj *iPivotsObj;
// // maPivotsCount = poiDrawer.DrawPivots(
// // maPivots,
// // iPivotsObj //
// // );
// //
// // Print("MA Pivots Detected ...");
// }
//
// Custom Indicator Direction Shifts ...
bool hasMACross = HasDirection(structure.maCrossDir);
bool hasHKSwitch = HasDirection(structure.hkSwitchDir);
bool hasSARSwitch = HasDirection(structure.sarSwitchDir);
//
// Check Required Pattern Exists ...
bool hasPinnedBar = HasDirection(structure.pinnedDir);
bool hasEngulfedBar = HasDirection(structure.engulfedDir);
bool hasFlagPattern = HasDirection(structure.flagPatternDir);
bool hasStarPattern = HasDirection(structure.starPatternDir);
bool hasRisingPattern = HasDirection(structure.risingPatternDir);
bool hasPiercingPattern = HasDirection(structure.piercingPatternDir);
bool hasSignalKeyBar = HasDirection(structure.signalKeyBarPatternDir);
//
// Check Bar Pattern Exists ...
// and Select Pattern Direction and Price and Price Type ...
has = hasPinnedBar ||
hasEngulfedBar ||
hasFlagPattern ||
hasStarPattern ||
hasSignalKeyBar ||
hasRisingPattern ||
hasPiercingPattern;
if (has)
{
//
if (hasPinnedBar)
{
//
iDir = structure.pinnedDir;
iName = "XPinned_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasEngulfedBar)
{
//
iDir = structure.engulfedDir;
iName = "XEngulfed_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasFlagPattern)
{
//
iDir = structure.flagPatternDir;
iName = "XFlag_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasStarPattern)
{
//
iDir = structure.starPatternDir;
iName = "XStar_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasSignalKeyBar)
{
//
iDir = structure.risingPatternDir;
iName = "XRising_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasRisingPattern)
{
//
iDir = structure.piercingPatternDir;
iName = "XPiercing_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
else if (hasPiercingPattern)
{
//
iDir = structure.signalKeyBarPatternDir;
iName = "XSignalKey_" + ToXString(iDir) + ToXString(TimeToSeconds(bar.time));
}
//
isBullish = IsSpecifiedBullish(iDir);
isBearish = IsSpecifiedBearish(iDir);
//
// Retrieve Price Type for Validate ...
iPriceType = isBullish
? X_PRICE_DOWN
: X_PRICE_UP;
iPriceEdgeType = isBullish
? X_PRICE_LOW
: X_PRICE_HIGH;
//
iPrice = bar.GetPrice(iPriceType);
iPriceEdge = bar.GetPrice(iPriceEdgeType);
//
// Validate Calculations ...
has = HasDirection(iDir) &&
(isBullish ||
isBearish) &&
NotEmptyZero(iPrice) &&
NotEmptyZero(iPriceEdge) &&
iPrice != iPriceEdge;
if (!has)
{
//
isBullish = false;
isBearish = false;
iDir = X_DIRECTION_NONE;
}
}
//
// Disable Signallers ...
has = false;
// Strategy 1 ...
// Works on Support or Resistances Areas ...
// has = Strategy1HasSignal(
// bar,
// iZone,
// iName,
// supports,
// resistances,
// iDir,
// structure,
// fimaConditions //
// );
//
// Do all Draws Here ...
bool canDraw = false;
if (canDraw && has)
{
//
int iWidth = 2;
XPOIStyle iStyle;
XCBoxObject *iBoxObj = NULL;
color iClr = isBullish
? clrYellow
: clrDarkOrange;
//
// Supports ...
has = HasChild(supports);
if (has)
{
//
count = ArraySize(supports);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
supports[i],
iBoxObj,
true, // Ignore At ...
supports[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
supports[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Resistances ...
has = HasChild(resistances);
if (has)
{
//
count = ArraySize(resistances);
for (int i = 0; i < count; i++)
{
//
has = poiDrawer.DrawBox(
resistances[i],
iBoxObj,
true, // Ignore At ...
resistances[i].type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
resistances[i].dir //
);
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
//
iStyle.Clean();
ZeroMemory(iBoxObj);
}
}
//
// Selected Zone ...
has = iZone.IsValid();
if (has)
{
//
has = poiDrawer.DrawBox(
iZone,
iBoxObj,
true, // Ignore At ...
iZone.type // Name ...
);
if (has)
{
//
poiDrawer.GetBoxStyle(
iStyle,
iZone.dir //
);
//
iStyle.clr = iClr;
iStyle.width = iWidth;
//
poiDrawer.ApplyBoxStyle(
iBoxObj,
iStyle //
);
}
}
//
// TrendLines ...
//
// Pivots ...
//
has = HasChild(pvPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
pvPivots,
drawnPivots //
);
}
//
has = HasChild(zgPivots);
if (has)
{
//
CArrayObj *drawnPivots = new CArrayObj();
count = poiDrawer.DrawPivots(
zgPivots,
drawnPivots //
);
}
//
// Patterns Bar ...
has = HasDirection(iDir);
if (has)
{
//
int iCode = 159;
ENUM_ARROW_ANCHOR iAnchor = isBullish
? ANCHOR_TOP
: ANCHOR_BOTTOM;
//
XCBarArrowObject *iPatternObj;
has = poiDrawer.DrawBarArrow(
bar,
iPatternObj,
iPriceEdgeType,
iCode,
iClr,
iWidth,
iAnchor,
iName,
true, // Ignore Bar Tag ...
10 // Threshold ...
);
}
}
/////////////////////////////////////////////////
/**
* Check Pattern Has Signal Based on Strategy 2 ...
*
* @param bar: XOHCL, reference to Pattern Bar ...
* @param iZone: XBoxZone, reference to holds affected zone ...
* @param patternName: string, detected pattern's name ...
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
* @param patternDir: ENUM_X_DIRECTION, detected pattern's direction ...
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
* @param fimaMarketStructure: XFIMAMarketStructure, refrence to Provides Market Structure ...
*
* @return ( bool )
*/
bool Strategy2HasSignal(
XOHCL &bar,
XBoxZone &iZone,
string patternName,
XBoxZone &supports[],
XBoxZone &resistances[],
ENUM_X_DIRECTION patternDir,
XFIMAMarketStructure &structure,
XFIMAConditions &fimaConditions,
XFIMAMarketStructure &fimaMarketStructure //
)
{
//
bool result = false;
//
// Prepare ...
iZone.Clean();
//
// Validate ...
//
// Do Detection ...
//
// Validate result ...
//
// Cleanup Resources ...
//
return result;
}
/**
* Check Pattern Has Signal Based on Strategy 1 ...
*
* @param bar: XOHCL, reference to Pattern Bar ...
* @param iZone: XBoxZone, reference to holds affected zone ...
* @param supports: XBoxZone, array reference to Provide Exists Supports ...
* @param resistances: XBoxZone, array reference to Provide Exists Resistances ...
* @param structure: XFIMAMarketStructure, refrence to Provides Market Structure ...
* @param fimaConditions: XFIMAConditions, reference to Bar Specified XFIMA Conditions ...
*
* @return ( bool )
*/
bool Strategy3HasSignal(
XOHCL &bar,
XBoxZone &iZone,
XBoxZone &supports[],
XBoxZone &resistances[],
XFIMAMarketStructure &structure,
XFIMAConditions &fimaConditions //
)
{
//
bool result = false;
//
// Prepare ...
iZone.Clean();
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Reading XHK ...
//
// Bar 1 ...
double cHKO = fimaConditions.hkOpenBuffer[0];
double cHKH = fimaConditions.hkHighBuffer[0];
double cHKL = fimaConditions.hkLowBuffer[0];
double cHKC = fimaConditions.hkCloseBuffer[0];
//
// Bar 2 ...
double pHKO = fimaConditions.hkOpenBuffer[1];
double pHKH = fimaConditions.hkHighBuffer[1];
double pHKL = fimaConditions.hkLowBuffer[1];
double pHKC = fimaConditions.hkCloseBuffer[1];
//
bool isCHKBullish = cHKO < cHKC;
bool isCHKBearish = cHKO > cHKC;
//
bool isPHKBullish = pHKO < pHKC;
bool isPHKBearish = pHKO > pHKC;
//
bool isCHKSwitchedToBullish = isCHKBullish && !isPHKBullish;
bool isCHKSwitchedToBearish = isCHKBearish && !isPHKBearish;
//
return result;
}
@@ -0,0 +1,916 @@
/**
* Leg Pattern Detection ...
*
* @param bar: XOHCL, reference to Specified Bar ...
* @param zone: XBoxZone, reference to Holds Detection Zone ...
* @param validationLength: int, leg minimum Validation Length ...
* @param loopback: int, Max Allowed Loopback Length ...
*
* @return ( bool )
*/
bool IsLegPattern(
XOHCL &bar,
XLeg &leg,
int validationLength = 3,
int loopback = 10 //
)
{
//
bool result = false;
//
// Prepare ...
leg.Clean();
//
// Normalize ...
loopback = NormalizeInt(loopback, 5);
//
// Validate ...
result = bar.IsValid();
if (!result)
{
return result;
}
//
// Prepare Patterns Analysis Config ...
XPatternAnalysisConfig iPatternsConfig;
iPatternsConfig.Default();
iPatternsConfig.CleanPatterns();
iPatternsConfig.AddPattern(X_BAR_PATTERN_LOW);
iPatternsConfig.AddPattern(X_BAR_PATTERN_HIGH);
iPatternsConfig.AddPattern(X_BAR_PATTERN_FLAG);
iPatternsConfig.AddPattern(X_BAR_PATTERN_STAR);
iPatternsConfig.AddPattern(X_BAR_PATTERN_RISING);
iPatternsConfig.AddPattern(X_BAR_PATTERN_PIERCING);
iPatternsConfig.AddPattern(X_BAR_PATTERN_ENGULFED);
iPatternsConfig.AddPattern(X_BAR_PATTERN_MOMENTUM);
iPatternsConfig.AddPattern(X_BAR_PATTERN_SIGNALKEY);
iPatternsConfig.AddPattern(X_BAR_PATTERN_TRUE_GAPED);
//
XOHCL iBar;
XOHCL pBar;
XOHCL iZBar;
XBoxZone zone;
XBoxZone iZone;
XBoxZone jZone;
bool has = false;
XBoxZone supports[];
XOHCL bullishBars[];
XOHCL bearishBars[];
XBoxZone bullishFVGs[];
XBoxZone bearishFVGs[];
bool isBullish = false;
bool isBearish = false;
XBoxZone resistances[];
double bullishPower = 0;
double bearishPower = 0;
int bullishBarsCount = 0;
int bearishBarsCount = 0;
int barIndex = bar.Index();
int start = barIndex + 1;
XPatternAnalysis iPattern;
int end = start + loopback;
XPatternAnalysis patterns[];
int bullishPatternsCount = 0;
int bearishPatternsCount = 0;
int sequentialsBullishBarsCount = 0;
int sequentialsBearishBarsCount = 0;
ENUM_X_DIRECTION iDir = X_DIRECTION_NONE;
//
for (int i = end; i >= start; i--)
{
//
// Initialize Indexed Bar ...
iBar.Clean();
pBar.Clean();
result = bar.BarAt(i, iBar);
result = result &&
iBar.GetPreviousBar(pBar);
if (!result)
{
break;
}
//
// Fill Bar Direction ...
isBullish = iBar.IsBullish();
isBearish = iBar.IsBearish();
//
// Directional ...
//
if (isBullish)
{
//
bullishBarsCount++;
//
bullishPower += iBar.GetBody();
bullishPower += iBar.GetLowShadow();
bullishPower -= iBar.GetHighShadow();
//
AddIfNotExists(iBar, bullishBars);
}
//
if (isBearish)
{
//
bearishBarsCount++;
//
bearishPower += iBar.GetBody();
bearishPower -= iBar.GetLowShadow();
bearishPower += iBar.GetHighShadow();
//
AddIfNotExists(iBar, bearishBars);
}
//
// Sequentail ....
//
// Bullish ...
if (isBullish)
{
//
if (pBar.IsBullish())
{
sequentialsBullishBarsCount++;
}
else if (pBar.IsBearish())
{
sequentialsBullishBarsCount = 0;
}
}
//
// Bearish ...
if (isBearish)
{
//
if (pBar.IsBearish())
{
sequentialsBearishBarsCount++;
}
else if (pBar.IsBullish())
{
sequentialsBearishBarsCount = 0;
}
}
//
// Detect Patterns ...
iPattern.Clean();
has = AnalyseBarPatterns(iBar, iPattern, iPatternsConfig);
if (has)
{
//
AddRef(iPattern, patterns);
//
bullishPatternsCount += iPattern.Count(X_DIRECTION_BULLISH);
bearishPatternsCount += iPattern.Count(X_DIRECTION_BEARISH);
}
//
// FVG Detection ...
CleanDirection(iDir);
has = HasFVG(iBar, iDir, iZone);
if (has)
{
//
if (iZone.IsBullish())
{
AddIfNotExists(iZone, bullishFVGs);
}
else
{
AddIfNotExists(iZone, bearishFVGs);
}
}
//
// Support / Resistance Detection ...
has = HasSupportResistance(
iBar,
iZone,
jZone,
5 //
);
if (has)
{
//
if (iZone.IsValid())
{
AddIfNotExists(iZone, supports);
}
//
if (jZone.IsValid())
{
AddIfNotExists(jZone, resistances);
}
}
}
//
// Summarizing ...
//
// Detect Direction ...
zone.Clean();
isBullish = false;
isBearish = false;
CleanDirection(iDir);
//
isBullish =
//
bullishPower > 0 &&
bullishBarsCount > 0 &&
bullishPatternsCount > 0 &&
sequentialsBullishBarsCount > 0 &&
//
bullishPower > bearishPower &&
bullishBarsCount > bearishBarsCount &&
bullishPatternsCount > bearishPatternsCount &&
sequentialsBullishBarsCount > sequentialsBearishBarsCount
//
;
//
isBearish =
//
bearishPower > 0 &&
bearishBarsCount > 0 &&
bearishPatternsCount > 0 &&
sequentialsBearishBarsCount > 0 &&
//
bearishPower > bullishPower &&
bearishBarsCount > bullishBarsCount &&
bearishPatternsCount > bullishPatternsCount &&
sequentialsBearishBarsCount > sequentialsBullishBarsCount
//
;
//
// Validate ...
result =
(isBullish && !isBearish) ||
(isBearish && !isBullish);
//
// PRICE Types ...
ENUM_X_PRICE lowerPriceType = X_PRICE_LOW;
ENUM_X_PRICE upperPriceType = X_PRICE_HIGH;
//
// Prepare Zone ...
if (result)
{
//
zone.at = bar.time;
zone.to = bar.time;
zone.period = bar.period;
zone.symbol = bar.symbol;
//
zone.type = ToXString(X_BAR_PATTERN_LEG);
zone.dir = isBullish
? X_DIRECTION_BULLISH
: X_DIRECTION_BEARISH;
//
int idx = -1;
if (isBullish)
{
idx = GetOldest(bullishBars);
}
else
{
idx = GetOldest(bearishBars);
}
//
result = IsValidIndex(idx);
if (result)
{
//
iZBar.Clean();
if (isBullish)
{
iZBar = bullishBars[idx];
}
else
{
iZBar = bearishBars[idx];
}
//
zone.from = iZBar.time;
//
iZBar.Clean();
}
//
if (isBullish)
{
//
// Prepare Upper and Lower ...
//
// Upper ...
idx = GetHighestBarPrice(bullishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.upper = bullishBars[idx].GetPrice(upperPriceType);
}
//
// Lower ...
idx = GetLowestBarPrice(bullishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.lower = bullishBars[idx].GetPrice(lowerPriceType);
}
}
else
{
//
// Prepare Upper and Lower ...
//
// Upper ...
idx = GetHighestBarPrice(bearishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.upper = bearishBars[idx].GetPrice(upperPriceType);
}
//
// Lower ...
idx = GetLowestBarPrice(bearishBars, upperPriceType);
if (IsValidIndex(idx))
{
zone.lower = bearishBars[idx].GetPrice(lowerPriceType);
}
}
//
result = zone.IsValid();
}
//
// Prepare XLeg ...
if (result)
{
//
leg.dir = zone.dir;
leg.time = zone.from;
leg.upper = zone.upper;
leg.lower = zone.lower;
leg.symbol = zone.symbol;
leg.period = zone.period;
Copy(patterns, leg.patterns);
Copy(supports, leg.supports);
Copy(bullishBars, leg.bullishBars);
Copy(bearishBars, leg.bearishBars);
Copy(resistances, leg.resistances);
Copy(bullishFVGs, leg.bullishFVGs);
Copy(bearishFVGs, leg.bearishFVGs);
leg.sequentialBullishBars = sequentialsBullishBarsCount;
leg.sequentialBearishBars = sequentialsBearishBarsCount;
//
result = leg.IsValid();
}
//
// Cleanup ...
if (!result)
{
zone.Clean();
}
iBar.Clean();
pBar.Clean();
zone.Clean();
iZBar.Clean();
iZone.Clean();
jZone.Clean();
iPattern.Clean();
XClean(supports);
XClean(patterns);
XClean(bullishBars);
XClean(bearishBars);
XClean(bullishFVGs);
XClean(bearishFVGs);
XClean(resistances);
//
return result;
}
bool IsLegPattern1(
XOHCL &bar,
XLeg &leg,
int validationLength = 5,
int loopback = 500 //
)
{
//
bool result = false;
//
// Prepare ...
leg.Clean();
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
validationLength = NormalizeInt(validationLength, 3);
//
// Validate ...
result = bar.IsValid() &&
fimaParser.IsValid();
if (!result)
{
return result;
}
//
int idx = bar.Index();
while (idx < bar.Index() + loopback)
{
//
}
//
return result;
}
//////////////////////////////////////////////////
//
// Leg ...
XLeg leg; // Exists Leg ...
bool drawLeg; // Draw Leg ...
bool manageLegs;
//
bool HasLeg()
{
return leg.IsValid();
}
//
bool ValidateLeg(XOHCL &bar)
{
//
bool result = false;
//
result = HasLeg() &&
bar.IsValid();
if (!result)
{
return result;
}
//
result =
leg.IsBullish()
? bar.low > leg.lower
: leg.IsBearish()
? bar.high < leg.upper
: false;
//
return result;
}
//
void DrawLeg()
{
//
if (!drawLeg)
{
return;
}
//
if (!HasLeg())
{
return;
}
//
// Update to Times ...
leg.UpdateTimes();
//
// Draw Leg Box ...
XBoxZone legZone;
leg.ToBox(legZone);
if (legZone.IsValid())
{
//
legZone.to = TimeCurrent();
poiDrawer.DrawZone(legZone, structureDrawConfig.drawConfig);
}
//
// Draw Legs Other Stufs ...
return;
//
// FVGs ...
poiDrawer.DrawZones(leg.bullishFVGs, structureDrawConfig.drawConfig);
poiDrawer.DrawZones(leg.bearishFVGs, structureDrawConfig.drawConfig);
//
// Support and Resistances ...
poiDrawer.DrawZones(leg.supports, structureDrawConfig.drawConfig);
poiDrawer.DrawZones(leg.resistances, structureDrawConfig.drawConfig);
//
// Patterns ...
poiDrawer.DrawPatternAnalysises(leg.patterns, structureDrawConfig.barAnalysisDrawConfig);
}
//
void ManageLeg(XOHCL &bar)
{
//
// Validate Exists ...
if (HasLeg())
{
//
if (!ValidateLeg(bar))
{
//
// Invalidate XLeg ...
leg.Clean();
}
}
//
// Detect New ...
if (!HasLeg())
{
poiDetector.IsLegPattern(bar, leg);
}
//
// Update Exists ...
if (HasLeg())
{
//
// Update to Times ...
leg.UpdateTimes();
//
DrawLeg();
}
}
//
//
//
ManageLeg(bar);
//
// Checking For Leg Pattern ...
bool hasLeg = poiDetector.IsLegPattern(
pBar,
_leg,
3,
10 //
);
if (hasLeg)
{
hasLeg = _leg.ToBox(legZone);
}
bool hasBullishLeg = hasLeg && _leg.IsBullish();
bool hasBearishLeg = hasLeg && _leg.IsBearish();
//
//
//
int CollectPivots(
XPivot &pivots[],
int barIndex = 0,
int loopback = 500 //
)
{
//
int result = 0;
//
// Prepare ...
XClean(pivots);
//
// Normalize ...
loopback = NormalizeInt(loopback, 50);
barIndex = NormalizeBarIndex(barIndex);
//
// Validate ...
bool has = IsValid();
if (!has)
{
return result;
}
//
has = false;
XOHCL tmpBar;
XPivot tmpPivot;
double tmpValue;
datetime tmpTime;
bool isBullish = false;
bool isBearish = false;
string tmpSymbol = symbol;
ENUM_TIMEFRAMES tmpPeriod = period;
ENUM_X_DIRECTION tmpDir = X_DIRECTION_NONE;
for (int i = barIndex; i < barIndex + loopback; i++)
{
//
tmpBar.Clean();
tmpPivot.Clean();
//
has = tmpBar.Init(tmpSymbol, tmpPeriod, i);
if (!has)
{
continue;
}
//
// XSAR ...
isBullish = IsSARSwitchedToBullish(i);
isBearish = IsSARSwitchedToBearish(i);
has = isBullish || isBearish;
if (has)
{
}
//
// XMA Fast / Slow ...
//
// States ...
isBullish = IsMASlowSwitchedToBullish(i);
isBearish = IsMASlowSwitchedToBearish(i);
has = isBullish || isBearish;
if (has)
{
}
//
// Crossed Fast Slow ...
isBullish = IsMAFastCrossedOverSlow(i);
isBearish = IsMAFastCrossedUnderSlow(i);
has = isBullish || isBearish;
if (has)
{
}
//
// Crossed Last ...
isBullish = IsMASlowCrossedOverLast(i);
isBearish = IsMASlowCrossedUnderLast(i);
has = isBullish || isBearish;
if (has)
{
}
//
// XHK ...
isBullish = IsHKSwitchedToBullish(i);
isBearish = IsHKSwitchedToBearish(i);
has = isBullish || isBearish;
if (has)
{
}
}
//
result = ArraySize(pivots);
//
return result;
}
//
//
//
/**
* an strucutre to Model Specified Leg Pattern ...
**/
struct XLeg
{
//
// Props ...
//
datetime time;
string symbol;
ENUM_X_DIRECTION dir;
ENUM_TIMEFRAMES period;
//
double upper;
double lower;
//
XOHCL bullishBars[];
XOHCL bearishBars[];
//
XBoxZone supports[];
XBoxZone resistances[];
//
XBoxZone bullishFVGs[];
XBoxZone bearishFVGs[];
//
XPatternAnalysis patterns[];
//
int sequentialBullishBars;
int sequentialBearishBars;
//
// Constructor ...
//
// Tools ...
/**
* Cleanup ...
*/
void Clean()
{
//
time = NULL;
symbol = NULL;
period = NULL;
dir = X_DIRECTION_NONE;
//
upper = 0;
lower = 0;
sequentialBullishBars = 0;
sequentialBearishBars = 0;
//
XClean(patterns);
XClean(supports);
XClean(bullishBars);
XClean(bearishBars);
XClean(resistances);
XClean(bullishFVGs);
XClean(bearishFVGs);
}
/**
* Validate ...
*
* @return ( bool )
*/
bool IsValid()
{
//
bool result = false;
//
result =
IsXValid(time) &&
IsXValid(symbol) &&
IsXValid(period) &&
HasDirection(dir) &&
NotEmptyZero(upper) &&
NotEmptyZero(lower) &&
upper > lower;
//
return result;
}
/**
* Check is Bullish ...
*
* @return ( bool )
*/
bool IsBullish()
{
return IsValid() &&
IsXBullish(dir);
}
/**
* Check is Bearish ...
*
* @return ( bool )
*/
bool IsBearish()
{
return IsValid() &&
IsXBearish(dir);
}
/**
* Converts a Leg to XBoxZone ...
*
* @param zone: XBoxZone, reference to holds Converted ...
*
* @return ( bool )
*/
bool ToBox(XBoxZone &zone)
{
//
bool result = false;
//
// Prepare ...
zone.Clean();
//
// Validate ...
result = IsValid();
if (!result)
{
return result;
}
//
zone.at = time;
zone.dir = dir;
zone.from = time;
zone.upper = upper;
zone.lower = lower;
zone.symbol = symbol;
zone.period = period;
zone.to = TimeCurrent();
zone.type = ToXString(X_BAR_PATTERN_LEG);
//
result = zone.IsValid();
//
// Cleanup ...
if (!result)
{
zone.Clean();
}
//
return result;
}
/**
* Update Times of Collections ...
*
* @param value: datetime, Specified Time ...
*/
void UpdateTimes(datetime value = NULL)
{
//
// Normalize ...
value = NormalizeTime(value);
//
// Validate ...
if (!IsValid())
{
return;
}
//
UpdateToTime(supports, value);
UpdateToTime(resistances, value);
UpdateToTime(bullishFVGs, value);
UpdateToTime(bearishFVGs, value);
}
//
};
@@ -0,0 +1,686 @@
{
"lists": [
{
"id": "d66f2925-aa4e-46e4-8f3e-f2c0ba6c9454",
"title": "Backlog",
"cards": []
},
{
"id": "61ca33e6-05e4-4b44-b88d-3bc8ae5cba86",
"title": "To Do",
"cards": []
},
{
"id": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "Doing",
"cards": [
{
"id": "a59a73f4-1ab4-477b-893e-b2dfb71fe6ea",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "Add Support for PV in XKI Indicator.",
"description": "",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "f8eb6951-f337-40da-9b98-e468f77709fd",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "implementing Signallers Has Strategy Functions ...",
"description": "Fill Signal Strategies\n",
"labels": [],
"checkboxes": [
{
"id": "832b1c6e-8219-48ed-a897-45251f444cb1",
"title": "Strategy 1",
"checked": false
},
{
"id": "ca4683e7-14f0-4dde-86a2-16ea71e08a48",
"title": "Add more Validations on Entries in Strategy 1;",
"checked": false
},
{
"id": "bd3c09a7-1fbf-45f9-bcf7-ec0f71d1be24",
"title": "adding support Validate by Support and Resistances Zones; on Strategy 1; ",
"checked": false
}
],
"comments": []
},
{
"id": "bad677c0-a119-4f44-be8b-185fc4c996c7",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "add Targets in strategy 1",
"description": "use Guards Instead of Targets.",
"labels": [],
"checkboxes": [],
"comments": []
},
{
"id": "bcb422f9-89db-4816-ba3a-bae95c9c8da4",
"listId": "6f8db3d6-fcaa-4522-bee5-0e3e38c96e73",
"title": "Test all XKI Helper Functions",
"description": "Test all KI Parser Conditional Tools ...\n ",
"labels": [],
"checkboxes": [
{
"id": "987aadc7-1775-4ddb-96a8-c7867b41c5dc",
"title": "IsKIFastBullish",
"checked": true
},
{
"id": "33d30e91-1d65-4cc9-8955-4fcdac1a1a1c",
"title": "IsKIFastBearish",
"checked": true
},
{
"id": "f5efdef3-3dd5-4a67-9335-27ade4a08119",
"title": "IsKIFastSwitchedToBullish",
"checked": true
},
{
"id": "95fd5f87-3076-4a10-9d1d-2190c74e77dc",
"title": "IsKIFastSwitchedToBearish",
"checked": true
},
{
"id": "5848cd3c-7f60-4310-adde-56d0e80896a2",
"title": "IsKIFastOverLast",
"checked": true
},
{
"id": "879b6657-8a36-4329-9edd-2b5243733c37",
"title": "IsKIFastUnderLast",
"checked": true
},
{
"id": "7ebd6627-2bd7-47b1-9b3c-51643a446cb3",
"title": "IsKIFastSameAsLast",
"checked": true
},
{
"id": "4533e930-8c54-45ea-95b8-a95aa9278bd8",
"title": "IsKIFastSwitchedOverLast",
"checked": true
},
{
"id": "1231584a-5181-457b-8f31-02da2962c54a",
"title": "IsKIFastSwitchedUnderLast",
"checked": true
},
{
"id": "67f9ccdb-eff3-4e1e-945b-5232773f16f5",
"title": "IsKISlowBullish",
"checked": true
},
{
"id": "2262f093-f7c9-4a73-983c-055b6098f915",
"title": "IsKISlowBearish",
"checked": true
},
{
"id": "0e6b67fe-0ff5-4783-a4e3-36b3a70007f5",
"title": "IsKISlowSwitchedToBullish",
"checked": true
},
{
"id": "0ec4ea00-63bc-4059-92e2-46afa6793325",
"title": "IsKISlowSwitchedToBearish",
"checked": true
},
{
"id": "cf71aa02-fbf9-4f42-a4f2-791353cc290e",
"title": "IsKISlowOverLast",
"checked": true
},
{
"id": "da046ac2-0ed5-4c45-ba5b-ffd31a1f65a3",
"title": "IsKISlowUnderLast",
"checked": true
},
{
"id": "f57c9dde-9294-4909-b5c8-4a8a9a661072",
"title": "IsKISlowSameAsLast",
"checked": true
},
{
"id": "c52951e5-7a57-4823-a061-9d7a4aa9f0f4",
"title": "IsKISlowSwitchedOverLast",
"checked": true
},
{
"id": "9e523117-d742-4ffa-ae7d-cbd995b6bc61",
"title": "IsKISlowSwitchedUnderLast",
"checked": true
},
{
"id": "3ae34a28-6172-4209-832d-41647e45c072",
"title": "IsKISuperSlowBullish",
"checked": true
},
{
"id": "a7720bdf-2535-430f-9f55-81fa2d281910",
"title": "IsKISuperSlowBearish",
"checked": true
},
{
"id": "b03e521f-d1b4-4e83-9aaa-6a65297420d5",
"title": "IsKISuperSlowSwitchedToBullish",
"checked": true
},
{
"id": "3a59a397-816d-4e41-93cd-cab889ebcc1e",
"title": "IsKISuperSlowSwitchedToBearish",
"checked": true
},
{
"id": "315380e3-702b-41bf-abf5-4b85c0e00ce4",
"title": "IsKISuperSlowOverLast",
"checked": true
},
{
"id": "3a18f5b6-f18e-43d8-b8e6-43fc530ac80d",
"title": "IsKISuperSlowUnderLast",
"checked": true
},
{
"id": "4174d12c-382f-4615-9a65-99c447fa6a2a",
"title": "IsKISuperSlowSameAsLast",
"checked": true
},
{
"id": "03c1fc35-b0c4-477f-ab30-d183a990aff1",
"title": "IsKISuperSlowSwitchedOverLast",
"checked": true
},
{
"id": "82f549d7-6afa-4408-9d3a-d41d4d623bb7",
"title": "IsKISuperSlowSwitchedUnderLast",
"checked": true
},
{
"id": "abd7362a-29ba-4f92-9fe0-0496ccb7e9c6",
"title": "IsKIWaveBullish",
"checked": true
},
{
"id": "440e446f-9aa9-4f74-a950-63a013b42fa5",
"title": "IsKIWaveBearish",
"checked": true
},
{
"id": "2606bddb-aae1-4cca-8a29-b11c9f7015e6",
"title": "IsKIWaveSwitchedToBullish",
"checked": true
},
{
"id": "2036fddf-c4eb-4c5d-a550-d3f84341e78b",
"title": "IsKIWaveSwitchedToBearish",
"checked": true
},
{
"id": "649905b4-d0e9-4009-aeda-08a633861201",
"title": "IsKIWaveOverLast",
"checked": true
},
{
"id": "cc181a1f-298a-438d-afc8-74b0d4200228",
"title": "IsKIWaveUnderLast",
"checked": true
},
{
"id": "66bafec6-7794-4650-8919-d6409b49fbdf",
"title": "IsKIWaveSwitchedOverLast",
"checked": true
},
{
"id": "a5a714cb-ea11-42e3-8e9c-8745405998ae",
"title": "IsKIWaveSwitchedUnderLast",
"checked": true
},
{
"id": "b94e9071-5f85-4a38-828c-7cf8a1e99a63",
"title": "IsPriceOverKIUpper",
"checked": true
},
{
"id": "f534622b-5a7f-4c9c-85ed-c562d907fd89",
"title": "IsPriceSwitchedOverKIUpper",
"checked": true
},
{
"id": "c3a7d88b-c81f-46d4-a3cc-a0d1f5597371",
"title": "IsPriceUnderKIUpper",
"checked": true
},
{
"id": "8e559cb9-f6a9-412e-8882-e622030cf838",
"title": "IsPriceSwitchedUnderKIUpper",
"checked": true
},
{
"id": "1efcb06a-0edd-41d0-8e8b-18cba4f64226",
"title": "IsPriceOverKILower",
"checked": true
},
{
"id": "b16ad1a1-1fb2-4bb6-b2f8-f9310d012f4f",
"title": "IsPriceSwitchedOverKILower",
"checked": true
},
{
"id": "7e95d7e0-a50f-412b-a024-2568bf66c3f1",
"title": "IsPriceUnderKILower",
"checked": true
},
{
"id": "dd0deb1f-a259-4ce9-a471-92e268e10abe",
"title": "IsPriceSwitchedUnderKILower",
"checked": true
},
{
"id": "d747f70e-af68-42f1-a621-efd3ce518b47",
"title": "IsPriceInsideKIBands",
"checked": true
},
{
"id": "ebf997ee-8944-4442-86fb-6d01ea64b8a6",
"title": "IsMAFastBullish",
"checked": true
},
{
"id": "e756a5d0-4477-4277-be7d-5897079add6a",
"title": "IsMAFastSwitchedToBullish",
"checked": true
},
{
"id": "11eb8b4c-004c-4272-921f-4067315aac6a",
"title": "IsMAFastBearish",
"checked": true
},
{
"id": "548819d7-06fa-4ca5-adf2-c4c2d3064d7e",
"title": "IsMAFastSwitchedToBearish",
"checked": true
},
{
"id": "90451b0f-ec2e-48e0-8797-7f48cedf743c",
"title": "IsMAFastOverLast",
"checked": true
},
{
"id": "14210197-c670-4f49-8935-b65926945837",
"title": "IsMAFastSwitchedOverLast",
"checked": true
},
{
"id": "6158296f-fec3-443e-826b-84a481225013",
"title": "IsMAFastUnderLast",
"checked": true
},
{
"id": "e84b372e-fbdc-45da-a604-76a0fc6381c4",
"title": "IsMAFastSwitchedUnderLast",
"checked": true
},
{
"id": "ef0feb55-069c-4e9a-a56e-de05f6b6801f",
"title": "IsMASlowBullish",
"checked": true
},
{
"id": "0568553a-8ad1-4588-834e-26befe2a9bbb",
"title": "IsMASlowSwitchedToBullish",
"checked": true
},
{
"id": "630cd36a-f848-44d6-958b-728c4757df6e",
"title": "IsMASlowBearish",
"checked": true
},
{
"id": "62899e4a-87da-4fc9-8b4b-f1b8b077c177",
"title": "IsMASlowSwitchedToBearish",
"checked": true
},
{
"id": "acca2b2e-27d6-44dc-bd7f-98857e1b7e64",
"title": "IsMASlowOverLast",
"checked": true
},
{
"id": "762fd136-113c-444f-8373-2104bc4db466",
"title": "IsMASlowSwitchedOverLast",
"checked": true
},
{
"id": "49631b5a-8b69-4649-a47d-bef5bda3e137",
"title": "IsMASlowUnderLast",
"checked": true
},
{
"id": "3cd7c2a1-8a8a-4aba-85c2-6279a356c49e",
"title": "IsMASlowSwitchedUnderLast",
"checked": true
},
{
"id": "43bbc4df-7601-4460-b636-61b73b30f10a",
"title": "IsMASuperSlowBullish",
"checked": true
},
{
"id": "a64507e6-c99a-4e6a-a995-c1be671d1083",
"title": "IsMASuperSlowSwitchedToBullish",
"checked": true
},
{
"id": "91c30277-6ea9-40e8-8467-d06beabf486b",
"title": "IsMASuperSlowBearish",
"checked": true
},
{
"id": "65295670-87f7-481c-ab9e-a92c8606923f",
"title": "IsMASuperSlowSwitchedToBearish",
"checked": true
},
{
"id": "0a102b6a-fabe-4aba-938f-d87a22e11b5e",
"title": "IsMASuperSlowOverLast",
"checked": true
},
{
"id": "cc1a7131-227d-4007-82ed-78c8cc9ef33e",
"title": "IsMASuperSlowSwitchedOverLast",
"checked": true
},
{
"id": "97e4a349-77c8-4997-8f1b-875fff8229ab",
"title": "IsMASuperSlowUnderLast",
"checked": true
},
{
"id": "93899467-f06d-420a-ac6e-e645c8c07389",
"title": "IsMASuperSlowSwitchedUnderLast",
"checked": true
},
{
"id": "2cbc64ba-1882-47a6-9206-7b25e8008395",
"title": "IsMACrossoverBullish",
"checked": true
},
{
"id": "d7af351b-1de4-4ca9-958a-388d944d4fa9",
"title": "IsMACrossoverSwitchedToBullish",
"checked": true
},
{
"id": "44b233e6-5a56-4f3a-9c28-60e11aa2059a",
"title": "IsMACrossoverBearish",
"checked": true
},
{
"id": "5af39475-d1f8-477f-b867-5359aaaf94fa",
"title": "IsMACrossoverSwitchedToBearish",
"checked": true
},
{
"id": "d2a8183b-3553-4016-8155-a114c70da5ec",
"title": "IsPeakSameAsLast",
"checked": true
},
{
"id": "7395f77c-7491-417e-8ca8-a41923b46b68",
"title": "IsPeakOverLast",
"checked": true
},
{
"id": "afdae94d-1a14-408d-b1bd-e84c0868a655",
"title": "IsPeakUnderLast",
"checked": true
},
{
"id": "45f52be4-1f08-4e7a-b15b-d8db48752449",
"title": "IsValeSameAsLast",
"checked": true
},
{
"id": "ebc003bc-850d-44e2-a0ed-5ddaba71ae1a",
"title": "IsValeOverLast",
"checked": true
},
{
"id": "c979f0c3-e356-4fa6-bead-596e4a06b962",
"title": "IsValeUnderLast",
"checked": true
},
{
"id": "dd69c2c0-c999-4235-8cb5-74607b27c7ec",
"title": "IsATRBreakoutUp",
"checked": false
},
{
"id": "1a77e8e1-b3e8-48b4-b072-1cda3a69c6f9",
"title": "IsATRBreakoutDown",
"checked": false
},
{
"id": "bfeb3c24-f0ed-4aed-99af-bec8db026a62",
"title": "IsATROverLast",
"checked": false
},
{
"id": "62881e04-9b38-49e4-ae9d-e5161c1b0b5c",
"title": "IsATRUnderLast",
"checked": false
},
{
"id": "33ec5ba0-d31a-4602-ba79-7d3b4d9d7986",
"title": "IsATRSwitchedOverLast",
"checked": false
},
{
"id": "cf0fb674-8dfc-4ed1-b1dd-5a8447d818a4",
"title": "IsATRSwitchedUnderLast",
"checked": false
},
{
"id": "ab07c8e5-454c-4c9b-a69d-fa2e8330a2e0",
"title": "IsVolatilityHigh",
"checked": false
},
{
"id": "031521be-0062-4d07-ade4-ff17782888c7",
"title": "IsVolatilityLow",
"checked": false
},
{
"id": "49376783-45aa-4a57-a304-3547babf0ccd",
"title": "IsVolatilitySwitchdToHigh",
"checked": false
},
{
"id": "5803601b-9143-471d-968f-59622d37b70a",
"title": "IsVolatilitySwitchdToLow",
"checked": false
},
{
"id": "0ab99ddc-75b8-45c7-9140-8cd3dc6921c6",
"title": "IsRSIBullish",
"checked": false
},
{
"id": "ba39f76c-2257-48fe-94ca-addf2148ee23",
"title": "IsRSIBearish",
"checked": false
},
{
"id": "91c098b3-56d8-4728-b411-edf7e42d60b0",
"title": "IsRSIOverbought",
"checked": false
},
{
"id": "7917431d-9bc9-4514-8aea-7fae7c11b0de",
"title": "IsRSIOversold",
"checked": false
},
{
"id": "83d4b28b-fe6c-411c-a209-c57e3c8251d0",
"title": "IsRSISwitchedToOverSold",
"checked": false
},
{
"id": "96493d94-9db6-49de-a7f1-e3990b9469b8",
"title": "IsRSISwitchedFromOverSold",
"checked": false
},
{
"id": "02579268-284f-40f3-93c9-0cb3f70d103a",
"title": "IsRSISwitchedToOverbought",
"checked": false
},
{
"id": "6c473b2e-1b37-44b2-a08c-ce6217d0c00e",
"title": "IsRSISwitchedFromOverbought",
"checked": false
},
{
"id": "30177c7a-47df-4d90-8132-0f467ebc071c",
"title": "IsRSISwitchedToBullish",
"checked": false
},
{
"id": "a3e07f9c-72da-49b4-8101-f742644a2b81",
"title": "IsRSISwitchedToBearish",
"checked": false
}
],
"comments": []
}
]
},
{
"id": "c6b07a7f-d2e7-4f67-a5a9-0d93cd8bf981",
"title": "Test",
"cards": [
{
"id": "128af636-5cd8-4311-a565-e822ba380d59",
"listId": "c6b07a7f-d2e7-4f67-a5a9-0d93cd8bf981",
"title": "Add Support for ATR MA in XKI Indicator ...",
"description": "since we have to Calculate Volatility of ATR for Reversal or Breakouts,\nwe Have to Compare ATR by it's Moving Averages ...\n\nhere in this task we need to add support for atr MA ...",
"labels": [],
"checkboxes": [
{
"id": "f3aabe70-9df5-405d-a737-55e9cc6b2027",
"title": "Add Buffer;",
"checked": true
},
{
"id": "d6d295c4-b3e9-4946-b305-20df0858db59",
"title": "Calculate;",
"checked": true
},
{
"id": "d0e3f5b6-56c9-41a6-95c0-71de279bc70c",
"title": "Implement in Conditions;",
"checked": true
},
{
"id": "4827fc2b-e71d-468c-a069-ec5f17bc6962",
"title": "Implement in Helper;",
"checked": true
},
{
"id": "3fb4bac7-32c5-43be-b6ac-ccf4a15a117b",
"title": "Use in Parser;",
"checked": true
},
{
"id": "b98a8eee-1cbf-455b-9e8f-e4d42ba3f327",
"title": "Remove threshold;",
"checked": true
},
{
"id": "c3636ee3-d577-4728-9b2b-a9237687fd1a",
"title": "Refactor Side Affects;",
"checked": true
}
],
"comments": [
{
"id": "128f3338-1b62-4c2c-8ce4-723ed97fd41c",
"comment": "here we are going to test changes ..."
}
]
},
{
"id": "1b86f94a-a66e-482c-9172-c9dbb338bb63",
"listId": "c6b07a7f-d2e7-4f67-a5a9-0d93cd8bf981",
"title": "Testing POI(s) for Strategies ...",
"description": "we have some POIs in POI Detectors ...\nin this task we have to test them Works ...",
"labels": [],
"checkboxes": [
{
"id": "224b6c66-341f-4dda-aa25-6b45ab034a6e",
"title": "Add Support Testing them;",
"checked": true
},
{
"id": "50caaa08-a3a4-4be5-85d8-4ab41e8dd945",
"title": "Add Support for Safe Entry;",
"checked": true
},
{
"id": "95ee0eba-4e0d-4a6a-be62-93aa562ab767",
"title": "POI",
"checked": true
},
{
"id": "aec8ebe5-0d88-4ea7-bfd3-eb1a26af8a55",
"title": "Breakout POI",
"checked": true
},
{
"id": "6104db5f-95b2-401a-9efd-354b685e7a5f",
"title": "Reversal POI",
"checked": true
},
{
"id": "05aaad69-af4d-4253-89a7-e46a80cae593",
"title": "Continuation POI",
"checked": true
},
{
"id": "a7a75d64-00dd-4004-bab2-5040a47b8441",
"title": "Exhaustion POI",
"checked": true
},
{
"id": "a9c52b07-9a50-4c30-abf9-cd8e3febb6aa",
"title": "TrendExhausted POI",
"checked": true
}
],
"comments": [
{
"id": "cbcb5bf5-898d-4f5a-88bc-55007a11244c",
"comment": "all POI(s) noe well tested ...\nand everythings ready for implementing Strategies ..."
}
]
}
]
},
{
"id": "89823cc9-39a6-4d8b-bd5e-b6a14c03b01d",
"title": "Done",
"cards": []
}
],
"archive": {
"lists": [],
"cards": []
},
"settings": {
"labels": []
}
}
@@ -0,0 +1,46 @@
{
"lists": [
{
"id": "291ee671-37c7-45eb-bd40-24df3cb445ca",
"title": "BackLog",
"cards": []
},
{
"id": "53bb4f6a-34b9-48b8-9391-642c42d222d1",
"title": "ToDO",
"cards": [
{
"id": "b13fa9ba-5a66-42a6-a5eb-50789a59fad3",
"listId": "53bb4f6a-34b9-48b8-9391-642c42d222d1",
"title": "Apply Fix on XRR Tools",
"description": "Try to Recompile XRR Tools and Check it Works Currently or not;",
"labels": [],
"checkboxes": [],
"comments": []
}
]
},
{
"id": "ca095e9c-39f3-44dd-862c-d6c4af1dffff",
"title": "Doing",
"cards": []
},
{
"id": "842e4cfc-aee9-4fa7-9321-cc8ba0d194de",
"title": "Test",
"cards": []
},
{
"id": "b99e6c6c-ec5c-4f7c-b937-5bbba1551004",
"title": "Done",
"cards": []
}
],
"archive": {
"lists": [],
"cards": []
},
"settings": {
"labels": []
}
}

Some files were not shown because too many files have changed in this diff Show More