last backup ...
This commit is contained in:
@@ -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 ...
|
||||
};
|
||||
|
||||
//
|
||||
Reference in New Issue
Block a user