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 ...
};
//