last backup XCAEA
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: " + ToString(mItem.period) + separator +
|
||||||
|
"Time: " + ToString(mItem.time) + separator +
|
||||||
|
(includeScores
|
||||||
|
? "---------------" + separator +
|
||||||
|
"Scores:" + separator +
|
||||||
|
"---------------" + separator +
|
||||||
|
"Bullish: " + ToString(bullishScore) + separator +
|
||||||
|
"Bearish: " + ToString(bearishScore) + separator +
|
||||||
|
"---------------" + separator
|
||||||
|
: "") +
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,398 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 ...
|
||||||
|
void XCAccount()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mAccountInfo = new CAccountInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
void ~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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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,967 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Class Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: XCBaseExpert
|
||||||
|
// Description: provides all based classes for use ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property library
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://www.saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.x-trade.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
string XCBaseExpertToken = "XCBaseEA";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementations ...
|
||||||
|
class XCBaseExpert : public XCBaseAlert
|
||||||
|
{
|
||||||
|
//
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
XCTrade *mTrader; // Trader of Expert Adviser ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructur(s) ...
|
||||||
|
void XCBaseExpert()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
void ~XCBaseExpert()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
delete mTrader;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(mTrader);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Getter(s) / Setter(s) ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Magic Number ...
|
||||||
|
*
|
||||||
|
* @return ( long )
|
||||||
|
*/
|
||||||
|
long MagicNumber()
|
||||||
|
{
|
||||||
|
return mMagicNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Magic Number ...
|
||||||
|
*
|
||||||
|
* @param value: Long ...
|
||||||
|
*/
|
||||||
|
void MagicNumber(long value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mMagicNumber = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Slippage ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int Slippage()
|
||||||
|
{
|
||||||
|
return mSlippage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Slippage ...
|
||||||
|
*
|
||||||
|
* @param value: Integer ...
|
||||||
|
*/
|
||||||
|
void Slippage(int value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mSlippage = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Tag Prefix ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string TagPrefix()
|
||||||
|
{
|
||||||
|
return mTagPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Tag Prefix ...
|
||||||
|
*
|
||||||
|
* @param value: String ...
|
||||||
|
*/
|
||||||
|
void TagPrefix(string value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mTagPrefix = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbol ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Period ...
|
||||||
|
*
|
||||||
|
* @return ( ENUM_TIMEFRAMES )
|
||||||
|
*/
|
||||||
|
ENUM_TIMEFRAMES GetPeriod()
|
||||||
|
{
|
||||||
|
return mPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Period ...
|
||||||
|
*
|
||||||
|
* @param value: ENUM_TIMEFRAMES member ...
|
||||||
|
*/
|
||||||
|
void SetPeriod(ENUM_TIMEFRAMES value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mPeriod = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Symbol ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GetSymbol()
|
||||||
|
{
|
||||||
|
return mSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Symbol ...
|
||||||
|
*
|
||||||
|
* @param value: String ...
|
||||||
|
*/
|
||||||
|
void SetSymbol(string value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mSymbol = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Multi Symbol is Enable or Not ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool MultiSymbol()
|
||||||
|
{
|
||||||
|
return mMultiSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Multi Symbol is Enable or Not ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void MultiSymbol(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mMultiSymbol = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Multi Provided Symbols ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string Symbols()
|
||||||
|
{
|
||||||
|
return mSymbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Multi Provided Symbols ...
|
||||||
|
*
|
||||||
|
* @param value: String ...
|
||||||
|
*/
|
||||||
|
void Symbols(string value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mSymbols = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signalling ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Force Disable Signalling ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool Disabled()
|
||||||
|
{
|
||||||
|
return mDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Force Disable Signalling ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void Disabled(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mDisabled = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Allow Long Signals ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool AllowLong()
|
||||||
|
{
|
||||||
|
return mAllowLong;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Allow Long Signals ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void AllowLong(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mAllowLong = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Allow Short Signalling ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool AllowShort()
|
||||||
|
{
|
||||||
|
return mAllowShort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Allow Short Signalling ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void AllowShort(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mAllowShort = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reports ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Report New Month State ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ReportNewMonths()
|
||||||
|
{
|
||||||
|
return mReportNewMonths;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Report New Month State ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void ReportNewMonths(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mReportNewMonths = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Report New Weeks State ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ReportNewWeeks()
|
||||||
|
{
|
||||||
|
return mReportNewWeeks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Report New Weeks State ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void ReportNewWeeks(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mReportNewWeeks = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Report New Days State ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ReportNewDays()
|
||||||
|
{
|
||||||
|
return mReportNewDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Report New Days State ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void ReportNewDays(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mReportNewDays = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Report New Hours State ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ReportNewHours()
|
||||||
|
{
|
||||||
|
return mReportNewHours;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Report New Hours State ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void ReportNewHours(bool value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mReportNewHours = value;
|
||||||
|
ReConfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Expert OnInit Event ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool HandleOnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
string message = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Input ...
|
||||||
|
result = ValidateInputs();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
message = "Invalid Inputs ....";
|
||||||
|
|
||||||
|
//
|
||||||
|
Alert(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial All Requirements ...
|
||||||
|
result = InitEA();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial All GUI Requirements ...
|
||||||
|
result = InitGUI();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
message = "Initialized Successfully ...";
|
||||||
|
Alert(message);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Expert OnDeInit Event ...
|
||||||
|
*/
|
||||||
|
void HandleOnDeInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Destroy all GUI Requirements ...
|
||||||
|
DestroyGUI();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert De Initialization Succeeded ...
|
||||||
|
string msg = "De Initialized Successfully ...";
|
||||||
|
Alert(msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy all EA Requirements ...
|
||||||
|
DestroyEA();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Expert OnTick Event ...
|
||||||
|
*/
|
||||||
|
void HandleOnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
UpdateGUI();
|
||||||
|
HandleReportTime();
|
||||||
|
HandleStrategiesOnTick();
|
||||||
|
HandleStrategiesGuard();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Expert OnTrade Event ...
|
||||||
|
*/
|
||||||
|
void HandleOnTrade()
|
||||||
|
{
|
||||||
|
mTrader.HandleOnTrade();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Expert OnTimer Event ...
|
||||||
|
*/
|
||||||
|
void HandleOnTimer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Expert OnChart Event ...
|
||||||
|
*/
|
||||||
|
void HandleOnChartEvent(
|
||||||
|
const int id,
|
||||||
|
const long &lparam,
|
||||||
|
const double &dparam,
|
||||||
|
const string &sparam //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Virtual Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply Default Configurations ...
|
||||||
|
*/
|
||||||
|
virtual void DefaultConfigure()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Commons ...
|
||||||
|
Slippage(10);
|
||||||
|
TagPrefix("");
|
||||||
|
MagicNumber(1694056);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbol ...
|
||||||
|
SetSymbol(_Symbol);
|
||||||
|
SetPeriod(_Period);
|
||||||
|
MultiSymbol(false);
|
||||||
|
Symbols("EURUSDb,GBPUSDb,USDJPYb,USDCHFb,DowJones30,XAUUSDb");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signalling ...
|
||||||
|
Disabled(false);
|
||||||
|
AllowLong(true);
|
||||||
|
AllowShort(true);
|
||||||
|
|
||||||
|
//
|
||||||
|
string tag = GetTag();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert ...
|
||||||
|
SetAlertPrefix(tag);
|
||||||
|
SetAlertLogAlerts(true);
|
||||||
|
SetAlertPushAlerts(true);
|
||||||
|
SetAlertMailAlerts(false);
|
||||||
|
SetAlertEnableAlerts(true);
|
||||||
|
SetAlertTerminalAlerts(false);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reports ...
|
||||||
|
ReportNewDays(true);
|
||||||
|
ReportNewWeeks(false);
|
||||||
|
ReportNewHours(false);
|
||||||
|
ReportNewMonths(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vaslidate Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( virtual bool )
|
||||||
|
*/
|
||||||
|
virtual bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
string errMessage = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCommonValid = (
|
||||||
|
//
|
||||||
|
mSlippage > 0 &&
|
||||||
|
mMagicNumber > 0
|
||||||
|
//
|
||||||
|
);
|
||||||
|
if (!isCommonValid)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
errMessage += "common configurations error;" + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
isCommonValid &&
|
||||||
|
//
|
||||||
|
// Otere ...
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
||||||
|
errMessage = " Errors: \n" + errMessage;
|
||||||
|
Alert(errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initializers and DeInitializers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial EA Requirements ...
|
||||||
|
*
|
||||||
|
* @return ( virtual bool )
|
||||||
|
*/
|
||||||
|
virtual bool InitEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Helpers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Trader Instance and Configure it ...
|
||||||
|
mTrader = new XCTrade(
|
||||||
|
mSlippage,
|
||||||
|
mMagicNumber //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy Initialized Requirements ...
|
||||||
|
*/
|
||||||
|
virtual void DestroyEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
delete mTrader;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(mTrader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GUI Initialize if required ...
|
||||||
|
*
|
||||||
|
* @return ( virtual bool )
|
||||||
|
*/
|
||||||
|
virtual bool InitGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update All GUI Contents ...
|
||||||
|
*/
|
||||||
|
virtual void UpdateGUI()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all Initialized GUi Elements ...
|
||||||
|
*/
|
||||||
|
virtual void DestroyGUI()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls When a Position's SL Triggered ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal instance ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnStopLossTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls When a Position's TP Triggered ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal instance ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnTakeProfitTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Force Close a Position ...
|
||||||
|
*
|
||||||
|
* @param ticket: Position Ticket ...
|
||||||
|
* @param position: XPosition ...
|
||||||
|
* @param comment: Closing Comment ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnPositionForceClosed(
|
||||||
|
const ulong ticket,
|
||||||
|
const XPosition &position,
|
||||||
|
const string comment //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Position Modified ...
|
||||||
|
*
|
||||||
|
* @param ticket: ULONG ...
|
||||||
|
* @param profit: Double ...
|
||||||
|
* @param comment: String ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnPositionModified(
|
||||||
|
const ulong ticket,
|
||||||
|
const double profit,
|
||||||
|
const string comment //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Position Partially Closed ...
|
||||||
|
*
|
||||||
|
* @param ticket: ULONG ...
|
||||||
|
* @param profit: Double ...
|
||||||
|
* @param comment: String ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnPositionPartialClosed(
|
||||||
|
const ulong ticket,
|
||||||
|
const double profit,
|
||||||
|
const string comment //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Deals Changed ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnDealsChanged(int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Orders Changed ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnOrdersChanged(int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Positions Changed ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
virtual void HandleOnPositionsChanged(int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do All Signalling Processing Here ...
|
||||||
|
*/
|
||||||
|
virtual void HandleStrategiesOnTick()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Strategies for Guards and then Apply Them ...
|
||||||
|
*/
|
||||||
|
virtual void HandleStrategiesGuard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Time Handlers ...
|
||||||
|
|
||||||
|
virtual void HandleOnNewMonth()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void HandleOnNewWeek()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void HandleOnNewDay()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void HandleOnNewHour()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void ReConfigure()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Identifier Tag ...
|
||||||
|
*
|
||||||
|
* @return ( virtual string )
|
||||||
|
*/
|
||||||
|
virtual string GetTag()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
string tagPrefix = TagPrefix();
|
||||||
|
if (IsValid(tagPrefix))
|
||||||
|
{
|
||||||
|
result = tagPrefix;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
XCBaseExpertToken + result;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
XTimeTracker mTimeTracker; // Time Tracker for Providing Reports ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report Account Balance ...
|
||||||
|
*/
|
||||||
|
void HandleReportBalance()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!IsRunningOnTestMode())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
string msg = "Balance: " + ToString(mTrader.mAccount.GetBalance());
|
||||||
|
Log(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time Reporting based on Inputs ...
|
||||||
|
*/
|
||||||
|
void HandleReportTime()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Monthly Report ....
|
||||||
|
if (mTimeTracker.IsNewMonth())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleOnNewMonth();
|
||||||
|
|
||||||
|
//
|
||||||
|
if (mReportNewMonths)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Month ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weekly Report ....
|
||||||
|
if (mTimeTracker.IsNewWeek())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleOnNewWeek();
|
||||||
|
|
||||||
|
//
|
||||||
|
if (mReportNewWeeks)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Week ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Daily Report ....
|
||||||
|
if (mTimeTracker.IsNewDay())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleOnNewDay();
|
||||||
|
|
||||||
|
//
|
||||||
|
if (mReportNewDays)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Day ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hourly Report ....
|
||||||
|
if (mTimeTracker.IsNewHour())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleOnNewHour();
|
||||||
|
|
||||||
|
//
|
||||||
|
if (mReportNewHours)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Hour ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
long mMagicNumber; // Magic Number ...
|
||||||
|
int mSlippage; // Slippage ...
|
||||||
|
string mTagPrefix; // Tag Prefix ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbol ...
|
||||||
|
ENUM_TIMEFRAMES mPeriod; // Period ...
|
||||||
|
string mSymbol; // Symbol ...
|
||||||
|
bool mMultiSymbol; // Multi Symbol is Enable or Not ...
|
||||||
|
string mSymbols; // Multi Provided Symbols ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signalling ...
|
||||||
|
bool mDisabled; // Force Disable Signalling ...
|
||||||
|
bool mAllowLong; // Allow Long Signals ...
|
||||||
|
bool mAllowShort; // Allow Short Signals ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reports ...
|
||||||
|
bool mReportNewMonths; // Report New Month ...
|
||||||
|
bool mReportNewWeeks; // Report New Weeks ...
|
||||||
|
bool mReportNewDays; // Report New Days ...
|
||||||
|
bool mReportNewHours; // Report New Hours ...
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// a Class for Handle base requirements ...
|
||||||
|
// for indicators ...
|
||||||
|
class XCBaseHelper : public XCBase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
void XCBaseHelper(
|
||||||
|
string symbol, // Trading Symbol
|
||||||
|
ENUM_TIMEFRAMES period // Trading Time Frame
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mSymbol = symbol;
|
||||||
|
mPeriod = period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
void ~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() + "|" +
|
||||||
|
ToString(GetPeriod()) +
|
||||||
|
"]"
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Functions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbol ...
|
||||||
|
string mSymbol;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Period ...
|
||||||
|
ENUM_TIMEFRAMES mPeriod;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Indicator Handler ...
|
||||||
|
int mHandler;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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 ...
|
||||||
|
void XCHttp()
|
||||||
|
{
|
||||||
|
XCHttp("", 10000);
|
||||||
|
}
|
||||||
|
void XCHttp(
|
||||||
|
string path, // Base Folder to Store Data
|
||||||
|
int timeout // base timeout for Requests
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Path(path);
|
||||||
|
Timeout(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
void ~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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -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[], int &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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,792 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Class Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: XCVolume
|
||||||
|
// Description: provides all Requirements for Volume Managing ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property library
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://www.saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Template Variables of Inputs for Using ...
|
||||||
|
// input group "Volume";
|
||||||
|
// input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_STATIC; // Volume Applying Type
|
||||||
|
// input double eaStaticVoluem = X_MIN_VOLUME; // Static Volume
|
||||||
|
// input double eaDynamicVolumeStepBalance = 0.0; // Step of Balance for Increase Volume
|
||||||
|
// input double eaDynamicVolumeStepVolume = X_MIN_VOLUME; // Step of Volume Increasing
|
||||||
|
// input double eaConstantRiskBalance = 0.0; // Constant Risk Balance per Trade
|
||||||
|
// input double eaConstantPercent = 0.0; // Constant Percent of Balance Per Trade
|
||||||
|
// input double eaConstantBalance = 0.0; // Constant Balance for Calculations
|
||||||
|
// XCVolume *eaVolume;
|
||||||
|
// eaVolume = new XCVolume();
|
||||||
|
// bool result = eaVolume.Init(
|
||||||
|
// eaVolumeSelect,
|
||||||
|
// eaStaticVoluem,
|
||||||
|
// eaDynamicVolumeStepBalance,
|
||||||
|
// eaDynamicVolumeStepVolume,
|
||||||
|
// eaConstantRiskBalance,
|
||||||
|
// eaConstantPercent,
|
||||||
|
// eaConstantBalance //
|
||||||
|
// );
|
||||||
|
// if (!result) {
|
||||||
|
// return INIT_FAILED;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.x-account.class.mq5"
|
||||||
|
#include "../Libraries/x-saherelm.x-trade.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
#define X_MIN_VOLUME 0.01
|
||||||
|
|
||||||
|
//
|
||||||
|
enum ENUM_X_VOLUME_SELECT_TYPE
|
||||||
|
{
|
||||||
|
X_VOLUME_NONE, // None
|
||||||
|
X_VOLUME_STATIC, // Static Volume
|
||||||
|
X_VOLUME_CURRENT, // Current Balance
|
||||||
|
X_VOLUME_EQUITY, // Current Equity
|
||||||
|
X_VOLUME_CONSTANT // Constant Value
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsValid(ENUM_X_VOLUME_SELECT_TYPE value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = value != X_VOLUME_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
string ToString(ENUM_X_VOLUME_SELECT_TYPE value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = EnumToString(value);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementation ...
|
||||||
|
class XCVolume : public XCBase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
XCAccount *account;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XCVolume()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
account = new XCAccount();
|
||||||
|
|
||||||
|
//
|
||||||
|
Default();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCVolume()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ZeroMemory(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool Init(
|
||||||
|
ENUM_X_VOLUME_SELECT_TYPE _SelectType,
|
||||||
|
double _StaticVolume,
|
||||||
|
double _DynamicVolumeStepBalance,
|
||||||
|
double _DynamicVolumeStepVolume,
|
||||||
|
double _ConstantRiskBalance,
|
||||||
|
double _ConstantPercent,
|
||||||
|
double _ConstantBalance //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
mVolumeType = _SelectType;
|
||||||
|
mStaticVolume = _StaticVolume;
|
||||||
|
mConstantPercent = _ConstantPercent;
|
||||||
|
mConstantBalance = _ConstantBalance;
|
||||||
|
mConstantRiskBalance = _ConstantRiskBalance;
|
||||||
|
mDynamicVolumeStepVolume = _DynamicVolumeStepVolume;
|
||||||
|
mDynamicVolumeStepBalance = _DynamicVolumeStepBalance;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
CanUseStaticVolume() ||
|
||||||
|
CanUseDynamicVolume() ||
|
||||||
|
CanUseConstantRiskBalance() ||
|
||||||
|
CanUseConstantBalancePercent()
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prperties ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Volume Calculating Method ...
|
||||||
|
*
|
||||||
|
* @return (ENUM_X_VOLUME_SELECT_TYPE)
|
||||||
|
*/
|
||||||
|
ENUM_X_VOLUME_SELECT_TYPE VolumeType()
|
||||||
|
{
|
||||||
|
return mVolumeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Volume Calculating Method ...
|
||||||
|
*
|
||||||
|
* @param value: ENUM_X_VOLUME_SELECT_TYPE member ...
|
||||||
|
*/
|
||||||
|
void VolumeType(ENUM_X_VOLUME_SELECT_TYPE value)
|
||||||
|
{
|
||||||
|
mVolumeType = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Static Volume ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double StaticVolume()
|
||||||
|
{
|
||||||
|
return mStaticVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Static Volume ...
|
||||||
|
*
|
||||||
|
* @param value: double
|
||||||
|
*/
|
||||||
|
void StaticVolume(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeDouble(value, 0.01, 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
mStaticVolume = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Dynamic Volume Step Balance ...
|
||||||
|
* used to Calculate Final Lottage ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double DynamicVolumeStepBalance()
|
||||||
|
{
|
||||||
|
return mDynamicVolumeStepBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Dynamic Volume Step Balance ...
|
||||||
|
* used to Calculate Final Lottage ...
|
||||||
|
*
|
||||||
|
* @param value: Argument 1
|
||||||
|
*/
|
||||||
|
void DynamicVolumeStepBalance(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeDouble(value, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
mDynamicVolumeStepBalance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Dynamic Volume Step Volume ...
|
||||||
|
* used to Calculate Final Lottage ...
|
||||||
|
* how much increase Final Volume based oBalance Step ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double DynamicVolumeStepVolume()
|
||||||
|
{
|
||||||
|
return mDynamicVolumeStepVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Dynamic Volume Step Volume ...
|
||||||
|
* used to Calculate Final Lottage ...
|
||||||
|
* how much increase Final Volume based oBalance Step ...
|
||||||
|
*
|
||||||
|
* @param value: double
|
||||||
|
*/
|
||||||
|
void DynamicVolumeStepVolume(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeDouble(value, 0.01, 0.1);
|
||||||
|
|
||||||
|
//
|
||||||
|
mDynamicVolumeStepVolume = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Constant Balance Use for Dyamic Volume Calculation ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double ConstantBalance()
|
||||||
|
{
|
||||||
|
return mConstantBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Constant Balance Use for Dyamic Volume Calculation ...
|
||||||
|
*
|
||||||
|
* @param value: Argument 1
|
||||||
|
*/
|
||||||
|
void ConstantBalance(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeDouble(value, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
mConstantBalance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Constant Risk Value Based on Account Currency ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double ConstantRiskBalance()
|
||||||
|
{
|
||||||
|
return mConstantRiskBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Constant Risk Value Based on Account Currency ...
|
||||||
|
*
|
||||||
|
* @param value: double
|
||||||
|
*/
|
||||||
|
void ConstantRiskBalance(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeDouble(value, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
mConstantRiskBalance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Constant Percent Based On Selected Balance ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double ConstantPercent()
|
||||||
|
{
|
||||||
|
return mConstantPercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Constant Percent Based On Selected Balance ...
|
||||||
|
*
|
||||||
|
* @param value: double ...
|
||||||
|
*/
|
||||||
|
void ConstantPercent(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
value = NormalizeDouble(value, 0, 100);
|
||||||
|
|
||||||
|
//
|
||||||
|
mConstantPercent = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve Balance based on Provided Volume Type ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double GetBalance()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid(mVolumeType))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (mConstantBalance > 0 &&
|
||||||
|
mVolumeType == X_VOLUME_CONSTANT)
|
||||||
|
{
|
||||||
|
result = mConstantBalance;
|
||||||
|
}
|
||||||
|
else if (mVolumeType == X_VOLUME_CURRENT)
|
||||||
|
{
|
||||||
|
result = account.GetBalance();
|
||||||
|
}
|
||||||
|
else if (mVolumeType == X_VOLUME_EQUITY)
|
||||||
|
{
|
||||||
|
result = account.GetEquity();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve Balance based on Provided Volume Type ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double GetBalance(ENUM_X_VOLUME_SELECT_TYPE type)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid(type))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (mConstantBalance > 0 &&
|
||||||
|
type == X_VOLUME_CONSTANT)
|
||||||
|
{
|
||||||
|
result = mConstantBalance;
|
||||||
|
}
|
||||||
|
else if (type == X_VOLUME_CURRENT)
|
||||||
|
{
|
||||||
|
result = account.GetBalance();
|
||||||
|
}
|
||||||
|
else if (type == X_VOLUME_EQUITY)
|
||||||
|
{
|
||||||
|
result = account.GetEquity();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Volume Based On Given Configuration ...
|
||||||
|
*
|
||||||
|
* @param symbol: string, Trading Symbol ...
|
||||||
|
* @param entry: double, Entry Price ...
|
||||||
|
* @param sl: double, Stop Loss Price ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double CalculateVolume(
|
||||||
|
string symbol,
|
||||||
|
double entry,
|
||||||
|
double sl //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double result = X_MIN_VOLUME;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
has =
|
||||||
|
sl > 0 &&
|
||||||
|
entry > 0 &&
|
||||||
|
IsValid(symbol);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Balance Type ...
|
||||||
|
double balance = GetBalance();
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
double riskPrice = MathAbs(entry - sl);
|
||||||
|
double riskInPoints = riskPrice / points;
|
||||||
|
|
||||||
|
//
|
||||||
|
has = CanUseStaticVolume();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
result = mStaticVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = CanUseDynamicVolume();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double multiplier = balance / mDynamicVolumeStepBalance;
|
||||||
|
if (multiplier < 0)
|
||||||
|
{
|
||||||
|
multiplier = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = multiplier * mDynamicVolumeStepVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = CanUseConstantRiskBalance();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = account.CalculateVolume(
|
||||||
|
symbol,
|
||||||
|
mConstantRiskBalance,
|
||||||
|
riskInPoints //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = CanUseConstantBalancePercent();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double riskAmountPerBalance = (mConstantPercent * balance) / 100;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = account.CalculateVolume(
|
||||||
|
symbol,
|
||||||
|
riskAmountPerBalance,
|
||||||
|
riskInPoints //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (result < X_MIN_VOLUME)
|
||||||
|
{
|
||||||
|
result = X_MIN_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Volume ...
|
||||||
|
result = NormalizeVolume(result, symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Volume Based On Given Configuration ...
|
||||||
|
*
|
||||||
|
* @param signal: XSignal instance reference, provided required Data ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double CalculateVolume(XSignal &signal)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double result = X_MIN_VOLUME;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!signal.IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = CalculateVolume(
|
||||||
|
signal.symbol,
|
||||||
|
signal.entry,
|
||||||
|
signal.sl //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Specified Percent of Selected Balance for Volume ...
|
||||||
|
*
|
||||||
|
* @param percent: double, percent of Balance Risking ...
|
||||||
|
* @param symbol: string, Trading Symbol ...
|
||||||
|
* @param entry: double, Entry Price ...
|
||||||
|
* @param sl: double Stop Loss Price ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double CalculateVolume(
|
||||||
|
ENUM_X_VOLUME_SELECT_TYPE selectType,
|
||||||
|
double percent,
|
||||||
|
string symbol,
|
||||||
|
double entry,
|
||||||
|
double sl //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double result = X_MIN_VOLUME;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
has =
|
||||||
|
sl > 0 &&
|
||||||
|
entry > 0 &&
|
||||||
|
percent > 0 &&
|
||||||
|
IsValid(symbol) &&
|
||||||
|
IsValid(selectType) &&
|
||||||
|
(selectType == X_VOLUME_EQUITY ||
|
||||||
|
selectType == X_VOLUME_CURRENT);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Balance Type ...
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
double riskPrice = MathAbs(entry - sl);
|
||||||
|
double balance = GetBalance(selectType);
|
||||||
|
double riskInPoints = riskPrice / points;
|
||||||
|
|
||||||
|
//
|
||||||
|
double riskAmountPerBalance = (percent * balance) / 100;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = account.CalculateVolume(
|
||||||
|
symbol,
|
||||||
|
riskAmountPerBalance,
|
||||||
|
riskInPoints //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Default Props ...
|
||||||
|
*/
|
||||||
|
void Default()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
VolumeType(X_VOLUME_STATIC);
|
||||||
|
StaticVolume(0.01);
|
||||||
|
|
||||||
|
//
|
||||||
|
ConstantBalance(0);
|
||||||
|
ConstantPercent(0);
|
||||||
|
ConstantRiskBalance(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
DynamicVolumeStepBalance(0);
|
||||||
|
DynamicVolumeStepVolume(0.01);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Configuration is Valid For Static Volume ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool CanUseStaticVolume()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid(mVolumeType);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Static Volume ...
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
mVolumeType == X_VOLUME_STATIC &&
|
||||||
|
mStaticVolume > 0 &&
|
||||||
|
//
|
||||||
|
mDynamicVolumeStepBalance == 0 &&
|
||||||
|
//
|
||||||
|
mConstantBalance == 0 &&
|
||||||
|
mConstantPercent == 0 &&
|
||||||
|
mConstantRiskBalance == 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Configuration is Valid For Dynamic Volume ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool CanUseDynamicVolume()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid(mVolumeType);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
(mVolumeType == X_VOLUME_CURRENT ||
|
||||||
|
mVolumeType == X_VOLUME_EQUITY ||
|
||||||
|
(mVolumeType == X_VOLUME_CONSTANT &&
|
||||||
|
mConstantBalance > 0)) &&
|
||||||
|
//
|
||||||
|
mDynamicVolumeStepBalance > 0 &&
|
||||||
|
mDynamicVolumeStepVolume > 0 &&
|
||||||
|
//
|
||||||
|
mStaticVolume == 0 &&
|
||||||
|
mConstantPercent == 0 &&
|
||||||
|
mConstantRiskBalance == 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Configuration is Valid For Constant Risk Balance ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool CanUseConstantRiskBalance()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid(mVolumeType);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
(mVolumeType == X_VOLUME_CURRENT ||
|
||||||
|
mVolumeType == X_VOLUME_EQUITY ||
|
||||||
|
(mVolumeType == X_VOLUME_CONSTANT &&
|
||||||
|
mConstantBalance > 0)) &&
|
||||||
|
//
|
||||||
|
mConstantRiskBalance > 0 &&
|
||||||
|
//
|
||||||
|
mStaticVolume == 0 &&
|
||||||
|
mConstantPercent == 0 &&
|
||||||
|
mDynamicVolumeStepBalance == 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Configuration is Valid For Constant Risk Percent ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool CanUseConstantBalancePercent()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid(mVolumeType);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
(mVolumeType == X_VOLUME_CURRENT ||
|
||||||
|
mVolumeType == X_VOLUME_EQUITY ||
|
||||||
|
(mVolumeType == X_VOLUME_CONSTANT &&
|
||||||
|
mConstantBalance > 0)) &&
|
||||||
|
//
|
||||||
|
mConstantPercent > 0 &&
|
||||||
|
//
|
||||||
|
mStaticVolume == 0 &&
|
||||||
|
mConstantRiskBalance == 0 &&
|
||||||
|
mDynamicVolumeStepBalance == 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_VOLUME_SELECT_TYPE mVolumeType; // Balance Type ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Static Volume ...
|
||||||
|
double mStaticVolume; // Static Volume ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double mDynamicVolumeStepBalance; // Step of Balance ...
|
||||||
|
double mDynamicVolumeStepVolume; // Step of Volume ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double mConstantBalance; // Constant Balance ....
|
||||||
|
double mConstantRiskBalance; // Constant Risk Balance ...
|
||||||
|
double mConstantPercent; // Constant Percent of Balance ...
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
//
|
||||||
|
// Parsing Pivots ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Selected Pivot ...
|
||||||
|
XBoxZone lastOSCPivot;
|
||||||
|
double providedSL = 0;
|
||||||
|
bool hasNewOSC = false;
|
||||||
|
bool hasPivots = HasChild(pivots);
|
||||||
|
if (hasPivots)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Detect Selected Pivots ...
|
||||||
|
count = ArraySize(pivots);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iPivot = pivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Selected Last OSC Pivots ...
|
||||||
|
bool isOSC =
|
||||||
|
Contains(
|
||||||
|
"XCA_RSI",
|
||||||
|
iPivot.type //
|
||||||
|
) ||
|
||||||
|
Contains(
|
||||||
|
"XCA_CCI",
|
||||||
|
iPivot.type //
|
||||||
|
);
|
||||||
|
bool canSetOSC =
|
||||||
|
!isOSC
|
||||||
|
? false
|
||||||
|
: !lastOSCPivot.IsValid()
|
||||||
|
? true
|
||||||
|
: lastOSCPivot.from < iPivot.from;
|
||||||
|
if (canSetOSC)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
lastOSCPivot = iPivot;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect New OSC Pivot Happens ...
|
||||||
|
hasNewOSC = lastOSCPivot.IsValid() &&
|
||||||
|
cBar.time == lastOSCPivot.to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Pivot Box Type ...
|
||||||
|
bool isPVPivot =
|
||||||
|
Contains(
|
||||||
|
"XCA_PEAKSWHRES",
|
||||||
|
iPivot.type //
|
||||||
|
) ||
|
||||||
|
Contains(
|
||||||
|
"XCA_VALESWLSUP",
|
||||||
|
iPivot.type //
|
||||||
|
);
|
||||||
|
if (isPVPivot)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Select Box for OSC ...
|
||||||
|
if (hasNewOSC)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool canSelectBox =
|
||||||
|
pivotBox.IsValid()
|
||||||
|
? false
|
||||||
|
: lastOSCPivot.dir == iPivot.dir &&
|
||||||
|
(IsBullish(iPivot.dir)
|
||||||
|
? lastOSCPivot.upper > iPivot.upper &&
|
||||||
|
lastOSCPivot.lower < iPivot.upper &&
|
||||||
|
lastOSCPivot.lower <= iPivot.lower
|
||||||
|
: lastOSCPivot.lower < iPivot.lower &&
|
||||||
|
lastOSCPivot.upper > iPivot.lower &&
|
||||||
|
lastOSCPivot.upper >= iPivot.upper);
|
||||||
|
if (canSelectBox)
|
||||||
|
{
|
||||||
|
pivotBox = iPivot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
iPivot.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signaller Summarization ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cond1 Act Using PEAK VALE Box Activation or Rejection ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCond1Bullish =
|
||||||
|
//
|
||||||
|
hasNewOSC &&
|
||||||
|
(cVale < pVale ||
|
||||||
|
pVale < p2Vale) &&
|
||||||
|
pivotBox.IsValid() &&
|
||||||
|
pivotBox.IsBullish() &&
|
||||||
|
lastOSCPivot.IsBullish() &&
|
||||||
|
conditions.isValeIsPivot
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCond1Bearish =
|
||||||
|
//
|
||||||
|
hasNewOSC &&
|
||||||
|
(cPeak > pPeak ||
|
||||||
|
pPeak > p2Peak) &&
|
||||||
|
pivotBox.IsValid() &&
|
||||||
|
pivotBox.IsBearish() &&
|
||||||
|
lastOSCPivot.IsBearish() &&
|
||||||
|
conditions.isPeakIsPivot
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -0,0 +1,853 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XCXCAEASignaller ...
|
||||||
|
// Description: Class for XCAEA Signaller ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XCAEA Signaller"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../../Classes/x-saherelm.base.class.mq5"
|
||||||
|
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
|
||||||
|
#include "../Classes/xcaea.x-poi.detector.class.mq5"
|
||||||
|
#include "../Classes/xcaea.x-poi.drawer.class.mq5"
|
||||||
|
#include "../Helpers/xcaea.helper.mq5"
|
||||||
|
#include "../Libraries/xcaea.signaller.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
class XCXCAEASignaller : XCBase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
bool useGuards;
|
||||||
|
XCAEAInputs inputs;
|
||||||
|
XBarTracker barTraker;
|
||||||
|
XCXCAEAHelper *helper;
|
||||||
|
XCXCAEAPOIDrawer *drawer;
|
||||||
|
bool continuesRFTillTarget;
|
||||||
|
XBoxZone unAvailableBoxes[];
|
||||||
|
XCXCAEAPOIDetector *detector;
|
||||||
|
XCAEAStrategyConditions mConditions;
|
||||||
|
XCAEAStrategyConditions mConditionsCollection[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XCXCAEASignaller(
|
||||||
|
string _symbol,
|
||||||
|
ENUM_TIMEFRAMES _period //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
symbol = _symbol;
|
||||||
|
period = _period;
|
||||||
|
|
||||||
|
//
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCXCAEASignaller()
|
||||||
|
{
|
||||||
|
DeInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Properties ...
|
||||||
|
|
||||||
|
string GetSymbol()
|
||||||
|
{
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENUM_TIMEFRAMES GetPeriod()
|
||||||
|
{
|
||||||
|
return period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signaller Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Setup Conditions based on Signalling ...
|
||||||
|
*
|
||||||
|
* @param maxAllowedSLDistanceInPoint: int, Max Allowed SL Distance in Points (if Bigger thn Zero Provided) ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectSignalSetup(
|
||||||
|
double tpReward = 3,
|
||||||
|
double maxAllowedSLDistanceInPoint = 100 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bar Processing ...
|
||||||
|
if (!barTraker.CanProcessBar())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = false;
|
||||||
|
bool isBearish = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIndex = 0;
|
||||||
|
int cIndex = zIndex + 1;
|
||||||
|
int pIndex = cIndex + 1;
|
||||||
|
int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
int loopback = 10;
|
||||||
|
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
double ask = GetAsk(symbol);
|
||||||
|
double bid = GetBid(symbol);
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
XOHCL cBar;
|
||||||
|
XOHCL pBar;
|
||||||
|
XOHCL pPBar;
|
||||||
|
result = zBar.Init(
|
||||||
|
symbol,
|
||||||
|
period,
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
zBar.GetPreviousBar(cBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
cBar.GetPreviousBar(pBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
pBar.GetPreviousBar(pPBar);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
pPBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup Conditions ...
|
||||||
|
XBoxZone boxes[];
|
||||||
|
XBoxZone pivotBox;
|
||||||
|
XBoxZone signalBox;
|
||||||
|
double additionalSL = 0;
|
||||||
|
XBoxZone bullishBoxes[];
|
||||||
|
XBoxZone bearishBoxes[];
|
||||||
|
bool hasSignalBox = false;
|
||||||
|
XCAEAConditions conditions;
|
||||||
|
ENUM_X_DIRECTION signalBoxDir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detecting Pivots ...
|
||||||
|
detector.Update(
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Pivots ...
|
||||||
|
detector.Validate(
|
||||||
|
unAvailableBoxes,
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Founded Pivots ...
|
||||||
|
drawer.Draw(cTime);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Valid Boxes ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Bullish ...
|
||||||
|
// int bullishBoxesCount =
|
||||||
|
// detector
|
||||||
|
// .FillBullishBoxes(bullishBoxes);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Bearish ...
|
||||||
|
// int bearishBoxesCount =
|
||||||
|
// detector
|
||||||
|
// .FillBearishBoxes(bearishBoxes);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Copy(
|
||||||
|
// bullishBoxes,
|
||||||
|
// boxes,
|
||||||
|
// false //
|
||||||
|
// );
|
||||||
|
// Copy(
|
||||||
|
// bearishBoxes,
|
||||||
|
// boxes,
|
||||||
|
// false //
|
||||||
|
// );
|
||||||
|
int boxesCount = ArraySize(boxes);
|
||||||
|
bool hasBoxes = IsValidSize(boxesCount);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filter UnAvailable Boxes ...
|
||||||
|
if (hasBoxes)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Remove UnAvailable Boxes ...
|
||||||
|
has = HasChild(unAvailableBoxes);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
count = ArraySize(unAvailableBoxes);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = unAvailableBoxes[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
has = FindBoxIndex(
|
||||||
|
idx,
|
||||||
|
iBox,
|
||||||
|
boxes //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArrayRemove(
|
||||||
|
boxes,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
hasBoxes = HasChild(boxes);
|
||||||
|
boxesCount = ArraySize(boxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// if (hasBoxes)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Sinal Box ...
|
||||||
|
hasSignalBox = DetectXCAEAConditions(
|
||||||
|
boxes,
|
||||||
|
conditions,
|
||||||
|
pivotBox,
|
||||||
|
signalBox,
|
||||||
|
additionalSL,
|
||||||
|
signalBoxDir,
|
||||||
|
helper,
|
||||||
|
zIndex,
|
||||||
|
loopback //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make Pivot Box UnAvailable ...
|
||||||
|
if (pivotBox.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
pivotBox,
|
||||||
|
unAvailableBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
isBullish = hasSignalBox &&
|
||||||
|
IsBullish(signalBoxDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
isBearish = hasSignalBox &&
|
||||||
|
IsBearish(signalBoxDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Do What we Want ...
|
||||||
|
barTraker.Waits();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Signal Box ...
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
bool isCreated = helper.poiDrawer.DrawBox(
|
||||||
|
signalBox,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mObjects.Add(iObj);
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
|
||||||
|
//
|
||||||
|
Print("Signal Box ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Conditions ...
|
||||||
|
mConditions.symbol = symbol;
|
||||||
|
mConditions.period = period;
|
||||||
|
|
||||||
|
//
|
||||||
|
double spread = GetSpread(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
double entry =
|
||||||
|
isBullish
|
||||||
|
? signalBox.upper
|
||||||
|
: signalBox.lower;
|
||||||
|
|
||||||
|
//
|
||||||
|
double sl =
|
||||||
|
isBullish
|
||||||
|
? signalBox.lower
|
||||||
|
: signalBox.upper;
|
||||||
|
if (additionalSL > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
sl =
|
||||||
|
isBullish
|
||||||
|
? sl - additionalSL
|
||||||
|
: sl + additionalSL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double risk =
|
||||||
|
isBullish
|
||||||
|
? entry - sl
|
||||||
|
: sl - entry;
|
||||||
|
risk += spread;
|
||||||
|
if (risk >= maxAllowedSLDistanceInPoint * points)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Fix Risk in Big Distances ...
|
||||||
|
double hh5 = zBar.FindHighest(5, MODE_HIGH);
|
||||||
|
double ll5 = zBar.FindLowest(5, MODE_LOW);
|
||||||
|
|
||||||
|
//
|
||||||
|
double hhll5Delta = hh5 - ll5;
|
||||||
|
double riskDelta = hhll5Delta / 2;
|
||||||
|
risk = riskDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double rewardTP = risk * tpReward;
|
||||||
|
|
||||||
|
//
|
||||||
|
double tp =
|
||||||
|
isBullish
|
||||||
|
? entry + rewardTP
|
||||||
|
: entry - rewardTP;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filling ...
|
||||||
|
mConditions.sl = sl;
|
||||||
|
mConditions.tp = tp;
|
||||||
|
mConditions.pivot =
|
||||||
|
isBullish
|
||||||
|
? sl
|
||||||
|
: entry;
|
||||||
|
mConditions.point =
|
||||||
|
isBullish
|
||||||
|
? entry
|
||||||
|
: sl;
|
||||||
|
mConditions.dir = signalBoxDir;
|
||||||
|
mConditions.provider = "XCAEA";
|
||||||
|
mConditions.signalBox = signalBox;
|
||||||
|
mConditions.setupTime = zBar.time;
|
||||||
|
mConditions.conditions = conditions;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select RF Rewards ...
|
||||||
|
if (continuesRFTillTarget)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double rfReward = 1;
|
||||||
|
while (rfReward < tpReward)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double rewardRF = risk * rfReward;
|
||||||
|
double rfTP =
|
||||||
|
isBullish
|
||||||
|
? entry + rewardRF
|
||||||
|
: entry - rewardRF;
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
rfTP,
|
||||||
|
mConditions.targets //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
rfReward++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double rfReward = 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
double rewardRF = risk * rfReward;
|
||||||
|
double rfTP =
|
||||||
|
isBullish
|
||||||
|
? entry + rewardRF
|
||||||
|
: entry - rewardRF;
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
rfTP,
|
||||||
|
mConditions.targets //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resource ...
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(boxes);
|
||||||
|
Clean(bullishBoxes);
|
||||||
|
Clean(bearishBoxes);
|
||||||
|
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
pPBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
pivotBox.Clean();
|
||||||
|
signalBox.Clean();
|
||||||
|
conditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Trigger Conditions for Specified Signal ...
|
||||||
|
*
|
||||||
|
* @param conditions: XCAEAStrategyConditions instance Reference, Specified Signal Conditions ...
|
||||||
|
* @param maxAllowedSetupAge: specified Setup Age for Expiration (if bigger than Zero) ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectSignalTrigger(
|
||||||
|
XCAEAStrategyConditions &conditions,
|
||||||
|
int maxAllowedSetupAge = 60 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = conditions.IsSetuped();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
datetime setupTime = conditions.setupTime;
|
||||||
|
ENUM_X_DIRECTION setupDir = conditions.dir;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = IsBullish(setupDir);
|
||||||
|
bool isBearish = IsBearish(setupDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIndex = 0;
|
||||||
|
int cIndex = zIndex + 1;
|
||||||
|
int pIndex = cIndex + 1;
|
||||||
|
int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
int loopback = 10;
|
||||||
|
|
||||||
|
//
|
||||||
|
double ask = GetAsk(symbol);
|
||||||
|
double bid = GetBid(symbol);
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Signal Validation ...
|
||||||
|
// IMPORTANT: since all Validations done in SetUp Process ...
|
||||||
|
// here we only Execute Signal ...
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
conditions.triggerTime = cTime;
|
||||||
|
conditions.type = isBullish
|
||||||
|
? X_POSITION_TYPE_LONG
|
||||||
|
: X_POSITION_TYPE_SHORT;
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Guards bsed on Signalling Class ...
|
||||||
|
*
|
||||||
|
* @param guards: XCAEAGuard instance Collection, Holds Provided Guards ...
|
||||||
|
* @param positions: XPosition instance Collection, Provides Signalling Based Positions for Apply Guards on them ...
|
||||||
|
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectGuards(
|
||||||
|
XCAEAGuard &guards[],
|
||||||
|
const XPosition &positions[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Conditions to Conditions Collection if not Exists ...
|
||||||
|
*
|
||||||
|
* @param maxAllowed: int, Specified Max Allowed Holding Conditions ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int AddConditionsIfNotExists(
|
||||||
|
int maxAllowed = 10 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isSetuped = IsValid(mConditions.setupTime) &&
|
||||||
|
HasDirection(mConditions.dir);
|
||||||
|
if (!isSetuped)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(mConditionsCollection);
|
||||||
|
if (IsValidSize(count))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Copy Original Items ...
|
||||||
|
XCAEAStrategyConditions tmpItems[];
|
||||||
|
Copy(
|
||||||
|
mConditionsCollection,
|
||||||
|
tmpItems //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prese Item Data ...
|
||||||
|
bool isBullish = IsBullish(mConditions.dir);
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCAEAStrategyConditions iItem = tmpItems[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canRemove = mConditions.dir == iItem.dir &&
|
||||||
|
mConditions.pivot == iItem.pivot;
|
||||||
|
if (canRemove)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArrayRemove(
|
||||||
|
mConditionsCollection,
|
||||||
|
i,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(tmpItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
mConditions,
|
||||||
|
mConditionsCollection //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Olds ...
|
||||||
|
CleanupArray(
|
||||||
|
mConditionsCollection,
|
||||||
|
maxAllowed //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(mConditionsCollection);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
string symbol;
|
||||||
|
ENUM_TIMEFRAMES period;
|
||||||
|
CArrayObj mObjects;
|
||||||
|
CArrayObj mBarObjects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize ...
|
||||||
|
*/
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
useGuards = false;
|
||||||
|
continuesRFTillTarget = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
barTraker.Init(
|
||||||
|
symbol,
|
||||||
|
period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.Default();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Indicators ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCC ...
|
||||||
|
inputs.ccInputs.showCandles = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCT ...
|
||||||
|
inputs.ctInputs.showCandleTime = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCA ...
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.caInputs.supResSmoothingLength = 7;
|
||||||
|
inputs.caInputs.supResSmoothingMode = X_MA_MODE_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.caInputs.showKI = true;
|
||||||
|
inputs.caInputs.showTKI = false;
|
||||||
|
inputs.caInputs.showSar = false;
|
||||||
|
inputs.caInputs.showVidya = true;
|
||||||
|
inputs.caInputs.showTrend = false;
|
||||||
|
inputs.caInputs.showSwings = false;
|
||||||
|
inputs.caInputs.showLongCycle = false;
|
||||||
|
inputs.caInputs.showHindCycle = false;
|
||||||
|
inputs.caInputs.showFiboLevel1 = false;
|
||||||
|
inputs.caInputs.showFiboLevel2 = false;
|
||||||
|
inputs.caInputs.showFiboLevel3 = false;
|
||||||
|
inputs.caInputs.showShortCycle = false;
|
||||||
|
inputs.caInputs.showMediumCycle = false;
|
||||||
|
inputs.caInputs.showPeaksAndVales = true;
|
||||||
|
inputs.caInputs.showPeakAndValeGolden = false;
|
||||||
|
inputs.caInputs.showSupportAndResistance = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XOSCS ...
|
||||||
|
// inputs.oscsInputs.rsiLength = 5;
|
||||||
|
// inputs.oscsInputs.cciLength = 5;
|
||||||
|
// inputs.oscsInputs.mfiLength = 5;
|
||||||
|
// inputs.oscsInputs.rviLength = 5;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Oscillators Views ...
|
||||||
|
inputs.showCCI = false;
|
||||||
|
inputs.showRSI = false;
|
||||||
|
inputs.showMFI = false;
|
||||||
|
inputs.showRVI = false;
|
||||||
|
inputs.showADX = false;
|
||||||
|
inputs.showMACD = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCAEA Helper ...
|
||||||
|
helper = new XCXCAEAHelper();
|
||||||
|
helper.Init(
|
||||||
|
symbol,
|
||||||
|
period,
|
||||||
|
inputs //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize and Configure Detector ...
|
||||||
|
detector = new XCXCAEAPOIDetector(helper);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Detector ...
|
||||||
|
detector.detectRSIPeakPivots = true;
|
||||||
|
detector.detectRSIValePivots = true;
|
||||||
|
detector.detectCCIPeakPivots = true;
|
||||||
|
detector.detectCCIValePivots = true;
|
||||||
|
detector.detectFVGBullishPivots = true;
|
||||||
|
detector.detectFVGBearishPivots = true;
|
||||||
|
detector.detectValeSupSWLPivots = true;
|
||||||
|
detector.detectPeakResSWHPivots = true;
|
||||||
|
detector.detectPVFVGBullishPivots = true;
|
||||||
|
detector.detectPVFVGBearishPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize and Configure Drawer ...
|
||||||
|
drawer = new XCXCAEAPOIDrawer(detector);
|
||||||
|
|
||||||
|
//
|
||||||
|
drawer.ignoreUpdateOSCTos = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Drawer ...
|
||||||
|
drawer.drawRSIPeakPivots = true;
|
||||||
|
drawer.drawRSIValePivots = true;
|
||||||
|
drawer.drawCCIPeakPivots = true;
|
||||||
|
drawer.drawCCIValePivots = true;
|
||||||
|
drawer.drawFVGBullishPivots = false;
|
||||||
|
drawer.drawFVGBearishPivots = false;
|
||||||
|
drawer.drawValeSupSWLPivots = true;
|
||||||
|
drawer.drawPeakResSWHPivots = true;
|
||||||
|
drawer.drawPVFVGBullishPivots = true;
|
||||||
|
drawer.drawPVFVGBearishPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Widths ...
|
||||||
|
drawer.rsiPeakPivotsWidth = 4;
|
||||||
|
drawer.rsiValePivotsWidth = 4;
|
||||||
|
drawer.cciPeakPivotsWidth = 4;
|
||||||
|
drawer.cciValePivotsWidth = 4;
|
||||||
|
drawer.fvgBullishPivotsWidth = 2;
|
||||||
|
drawer.fvgBearishPivotsWidth = 2;
|
||||||
|
drawer.valeSupSWLPivotsWidth = 1;
|
||||||
|
drawer.peakResSWHPivotsWidth = 1;
|
||||||
|
drawer.pvFVGBullishPivotsWidth = 1;
|
||||||
|
drawer.pvFVGBearishPivotsWidth = 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Colors ...
|
||||||
|
drawer.rsiPeakPivotsColor = clrMagenta;
|
||||||
|
drawer.rsiValePivotsColor = clrAqua;
|
||||||
|
drawer.cciPeakPivotsColor = clrMagenta;
|
||||||
|
drawer.cciValePivotsColor = clrAqua;
|
||||||
|
drawer.fvgBullishPivotsColor = clrLime;
|
||||||
|
drawer.fvgBearishPivotsColor = clrRed;
|
||||||
|
drawer.valeSupSWLPivotsColor = clrAqua;
|
||||||
|
drawer.peakResSWHPivotsColor = clrMagenta;
|
||||||
|
drawer.pvFVGBullishPivotsColor = clrLime;
|
||||||
|
drawer.pvFVGBearishPivotsColor = clrRed;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configures Styles ...
|
||||||
|
drawer.rsiPeakPivotsStyle = STYLE_DASH;
|
||||||
|
drawer.rsiValePivotsStyle = STYLE_DASH;
|
||||||
|
drawer.cciPeakPivotsStyle = STYLE_DASH;
|
||||||
|
drawer.cciValePivotsStyle = STYLE_DASH;
|
||||||
|
drawer.fvgBullishPivotsStyle = STYLE_DASHDOTDOT;
|
||||||
|
drawer.fvgBearishPivotsStyle = STYLE_DASHDOTDOT;
|
||||||
|
drawer.valeSupSWLPivotsStyle = STYLE_SOLID;
|
||||||
|
drawer.peakResSWHPivotsStyle = STYLE_SOLID;
|
||||||
|
drawer.pvFVGBullishPivotsStyle = STYLE_DASHDOTDOT;
|
||||||
|
drawer.pvFVGBearishPivotsStyle = STYLE_DASHDOTDOT;
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeInitialize ...
|
||||||
|
*/
|
||||||
|
void DeInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
inputs.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(drawer);
|
||||||
|
ZeroMemory(helper);
|
||||||
|
ZeroMemory(detector);
|
||||||
|
|
||||||
|
//
|
||||||
|
mConditions.Clean();
|
||||||
|
Clean(mConditionsCollection);
|
||||||
|
|
||||||
|
//
|
||||||
|
mObjects.Clear();
|
||||||
|
mBarObjects.Clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
barTraker.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,573 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XSWLH
|
||||||
|
// Description: XSWLH ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm X121 XSWLH Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XSWLH"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
input int swingLength; // Swing Length
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showSwingLow; // Show Swing Low
|
||||||
|
input bool showSwingHigh; // Show Swing High
|
||||||
|
|
||||||
|
//
|
||||||
|
input int swingLowArrowCode = 225; // Swing Low Arrow Code
|
||||||
|
input int swingHighArrowCode = 226; // Swing High Arrow Code
|
||||||
|
|
||||||
|
//
|
||||||
|
#define emptyValue 0.0
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 2
|
||||||
|
#property indicator_plots 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWING LOW ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define swingLowBufferIndex 0
|
||||||
|
double swingLowBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label1 "SWL"
|
||||||
|
#property indicator_type1 DRAW_ARROW
|
||||||
|
#property indicator_color1 clrGreen
|
||||||
|
#property indicator_width1 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWING HIGH ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define swingHighBufferIndex 1
|
||||||
|
double swingHighBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label2 "SWH"
|
||||||
|
#property indicator_type2 DRAW_ARROW
|
||||||
|
#property indicator_color2 clrRed
|
||||||
|
#property indicator_width2 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define lastBufferIndex 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int firstBarIndex;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// because in some cases we may have more than one input for
|
||||||
|
// calculation and we must prevent any calculation
|
||||||
|
// untill we pass the biggest input length, here we get max Input length
|
||||||
|
// and then wait until pass it ...
|
||||||
|
maxLength = ExtractMaxLengthOfInputs();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Index Buffers ...
|
||||||
|
DefineBuffers();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Indicator ShortName ...
|
||||||
|
SetIndicatorName();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @param reason: Integer, De Initialization Reason ...
|
||||||
|
*/
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Bars ...
|
||||||
|
*
|
||||||
|
* @param rates_total: Integer, Total Bars on Chart ...
|
||||||
|
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
|
||||||
|
* @param time: DateTime Array, History of Open Time ...
|
||||||
|
* @param open: Double Array, History of Open Prices ...
|
||||||
|
* @param high: Double Array, History of High Prices ...
|
||||||
|
* @param low: Double Array, History of Low Prices ...
|
||||||
|
* @param close: Double Array, History of Close Prices ...
|
||||||
|
* @param tick_volume: Long, History of Tick Volumes on Bar ...
|
||||||
|
* @param volume: Long, History of Trade Volumes ...
|
||||||
|
* @param spread: Double, History of Spread Price ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnCalculate(
|
||||||
|
const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const datetime &time[],
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[],
|
||||||
|
const long &tick_volume[],
|
||||||
|
const long &volume[],
|
||||||
|
const int &spread[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Prepare Buffers ...
|
||||||
|
ArraySetAsSeries(time, true);
|
||||||
|
ArraySetAsSeries(open, true);
|
||||||
|
ArraySetAsSeries(high, true);
|
||||||
|
ArraySetAsSeries(low, true);
|
||||||
|
ArraySetAsSeries(close, true);
|
||||||
|
ArraySetAsSeries(tick_volume, true);
|
||||||
|
ArraySetAsSeries(volume, true);
|
||||||
|
ArraySetAsSeries(spread, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateBuffers(
|
||||||
|
i,
|
||||||
|
prev_calculated,
|
||||||
|
rates_total,
|
||||||
|
//
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tick_volume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Input Args for Initialization ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
swingLength > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(result, swingLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWING Low ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE swingLowDrawType = showSwingLow ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(swingLowBuffer, true);
|
||||||
|
SetIndexBuffer(swingLowBufferIndex, swingLowBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(swingLowBufferIndex, PLOT_SHOW_DATA, showSwingLow);
|
||||||
|
PlotIndexSetInteger(swingLowBufferIndex, PLOT_DRAW_TYPE, swingLowDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(swingLowBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
|
||||||
|
PlotIndexSetInteger(swingLowBufferIndex, PLOT_ARROW, swingLowArrowCode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWING High ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE swingHighDrawType = showSwingHigh ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(swingHighBuffer, true);
|
||||||
|
SetIndexBuffer(swingHighBufferIndex, swingHighBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(swingHighBufferIndex, PLOT_SHOW_DATA, showSwingHigh);
|
||||||
|
PlotIndexSetInteger(swingHighBufferIndex, PLOT_DRAW_TYPE, swingHighDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(swingHighBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
|
||||||
|
PlotIndexSetInteger(swingHighBufferIndex, PLOT_ARROW, swingHighArrowCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer ...
|
||||||
|
*/
|
||||||
|
void FillBuffersZero(int barIndex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
swingLowBuffer[barIndex] = emptyValue;
|
||||||
|
swingHighBuffer[barIndex] = emptyValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Custom Buffers ...
|
||||||
|
*
|
||||||
|
* @param bar_index: Integer, Represent Current Bar ...
|
||||||
|
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
|
||||||
|
* @param ratesTotal: Integer, Represents All Available Bars ...
|
||||||
|
* @param open: Double Array, History of Open Prices ...
|
||||||
|
* @param high: Double Array, History of High Prices ...
|
||||||
|
* @param close: Double Array, History of Close Prices ...
|
||||||
|
* @param low: Double Array, History of Low Prices ...
|
||||||
|
* @param tickVolume: Long, History of Tick Volumes on Bar ...
|
||||||
|
*/
|
||||||
|
void CalculateBuffers(
|
||||||
|
int bar_index, // Selected Bar Index
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal,
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &close[],
|
||||||
|
const double &low[],
|
||||||
|
const long &tickVolume[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int barsLimit = startCalculationForLastBars > 0
|
||||||
|
? startCalculationForLastBars
|
||||||
|
: 0;
|
||||||
|
if (barsLimit == 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
barsLimit = ratesTotal;
|
||||||
|
firstBarIndex = barsLimit - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
firstBarIndex = startCalculationForLastBars;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// bool canCalculate = true;
|
||||||
|
bool canCalculate =
|
||||||
|
bar_index <= barsLimit;
|
||||||
|
if (canCalculate)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Calculate Support nad Resistance ...
|
||||||
|
CalculateValues(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FillBuffersZero(bar_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Values ...
|
||||||
|
*
|
||||||
|
* @param bar_index: int, Specified Bar Index ...
|
||||||
|
* @param prevCalculated: int, Provides Previous Calculated Bars ...
|
||||||
|
* @param ratesTotal: int, Provides All Availabled Bars ...
|
||||||
|
* @param open: double Collection, Provides Open Prices Time Series ...
|
||||||
|
* @param high: double Collection, Provides High Prices Time Series ...
|
||||||
|
* @param close: double Collection, Provides Close Prices Time Series ...
|
||||||
|
* @param low: double Collection, Provides Low Prices Time Series ...
|
||||||
|
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
|
||||||
|
*/
|
||||||
|
void CalculateValues(
|
||||||
|
int bar_index, // Selected Bar Index
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal,
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &close[],
|
||||||
|
const double &low[],
|
||||||
|
const long &tickVolume[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check Prev Bar ...
|
||||||
|
//
|
||||||
|
int lastBarIndex = bar_index + 1;
|
||||||
|
bool isFirstBar =
|
||||||
|
startCalculationForLastBars > 0
|
||||||
|
? bar_index == startCalculationForLastBars
|
||||||
|
: bar_index == firstBarIndex;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reading Last Values ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double iSWLPrev =
|
||||||
|
isFirstBar
|
||||||
|
? emptyValue
|
||||||
|
: swingLowBuffer[lastBarIndex];
|
||||||
|
|
||||||
|
//
|
||||||
|
double iSWHPrev =
|
||||||
|
isFirstBar
|
||||||
|
? emptyValue
|
||||||
|
: swingHighBuffer[lastBarIndex];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Swings ...
|
||||||
|
bool isSwingLow = IsSwingLow(high, low, bar_index, swingLength);
|
||||||
|
bool isSwingHigh = IsSwingHigh(high, low, bar_index, swingLength);
|
||||||
|
bool hasSwing = isSwingLow ||
|
||||||
|
isSwingHigh;
|
||||||
|
if (!hasSwing)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// FillBuffersZero(bar_index);
|
||||||
|
|
||||||
|
//
|
||||||
|
swingLowBuffer[bar_index] = iSWLPrev;
|
||||||
|
swingHighBuffer[bar_index] = iSWHPrev;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double iSWL = low[bar_index];
|
||||||
|
double iSWH = high[bar_index];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Act Based on Swing High or Swing Low Detection ...
|
||||||
|
if (isSwingLow && !isSwingHigh)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Detect Swing High based On swing Low ...
|
||||||
|
iSWH = iSWHPrev;
|
||||||
|
}
|
||||||
|
else if (isSwingHigh && !isSwingLow)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Detect Swing Low Based On Swing High ...
|
||||||
|
iSWL = iSWLPrev;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (iSWL > iSWLPrev && iSWH == iSWHPrev)
|
||||||
|
{
|
||||||
|
iSWL = iSWLPrev;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (iSWH < iSWHPrev && iSWL == iSWLPrev)
|
||||||
|
{
|
||||||
|
iSWH = iSWHPrev;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
swingLowBuffer[bar_index] = iSWL;
|
||||||
|
swingHighBuffer[bar_index] = iSWH;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helpers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsSwingLow(
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
int index,
|
||||||
|
int length //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = index + 1 + length <= firstBarIndex;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = index + 1; i <= index + length; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = low[index] < low[i];
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsSwingHigh(
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
int index,
|
||||||
|
int length //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = index + 1 + length <= firstBarIndex;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = index + 1; i <= index + length; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = high[index] > high[i];
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,273 @@
|
|||||||
|
//
|
||||||
|
// Detect SignalBox Trigger ...
|
||||||
|
// Cond1:
|
||||||
|
// - Close Under Min / Max ...
|
||||||
|
// - All Trendings in Direction ...
|
||||||
|
// - Consolidating Trendings ...
|
||||||
|
// - ...
|
||||||
|
bool CanTriggerCond1(
|
||||||
|
XCXCAEAHelper *helper,
|
||||||
|
XBoxZone &box,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
double &sls[],
|
||||||
|
int barIndex = 0,
|
||||||
|
int loopback = 10 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Args ...
|
||||||
|
Clean(sls);
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
loopback = NormalizeInt(loopback, 5);
|
||||||
|
barIndex = NormalizeInt(barIndex, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Decision Box ...
|
||||||
|
result = box.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Market Conditions ...
|
||||||
|
XCAEAConditions conditions;
|
||||||
|
result = helper.GetConditions(
|
||||||
|
conditions,
|
||||||
|
barIndex,
|
||||||
|
loopback //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extract CBar ...
|
||||||
|
XOHCL cBar;
|
||||||
|
result = cBar.Init(
|
||||||
|
conditions.symbol,
|
||||||
|
conditions.period,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cBar.Clean();
|
||||||
|
conditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bar Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION barDir;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ENGULF ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCBarEngulfed = helper
|
||||||
|
.barAnalyser
|
||||||
|
.IsEngulfed(
|
||||||
|
cBar,
|
||||||
|
barDir //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCBarBullishEngulfed =
|
||||||
|
isCBarEngulfed &&
|
||||||
|
IsBullish(barDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCBarBearishEngulfed =
|
||||||
|
isCBarEngulfed &&
|
||||||
|
IsBearish(barDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = box.IsBullish();
|
||||||
|
bool isBearish = box.IsBearish();
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIDX = 0;
|
||||||
|
int cIDX = zIDX + 1;
|
||||||
|
int pIDX = cIDX + 1;
|
||||||
|
int p2IDX = pIDX + 1;
|
||||||
|
int p3IDX = p2IDX + 1;
|
||||||
|
int p4IDX = p3IDX + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reading Values ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// SAR ...
|
||||||
|
double cSAR = conditions.sarBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWH ...
|
||||||
|
double cSWH = conditions.swingHighBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWL ...
|
||||||
|
double cSWL = conditions.swingLowBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// PEAK ...
|
||||||
|
double cPeak = conditions.peakBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// VALE ...
|
||||||
|
double cVale = conditions.valeBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAH ...
|
||||||
|
double cMAH = conditions.mahBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAC ...
|
||||||
|
double cMAC = conditions.macBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAL ...
|
||||||
|
double cMAL = conditions.malBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// KI ...
|
||||||
|
double cKI = conditions.kiBuffer[cIDX];
|
||||||
|
double cKIState = conditions.kiStateBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// TKI ...
|
||||||
|
double cTKI = conditions.tkiBuffer[cIDX];
|
||||||
|
double cTKIState = conditions.tkiStateBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
double cFast = conditions.fastBuffer[cIDX];
|
||||||
|
double cFastState = conditions.fastStateBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// VIDYA ...
|
||||||
|
double cVidya = conditions.vidyaBuffer[cIDX];
|
||||||
|
double cVidyaState = conditions.vidyaStateBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// TREND ...
|
||||||
|
double cTrend = conditions.trendBuffer[cIDX];
|
||||||
|
double cTrendState = conditions.trendStateBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generating Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isSWLOverBox = cSWL > box.lower;
|
||||||
|
bool isSWHUnderBox = cSWH < box.upper;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isValeOverBox = cVale > box.lower;
|
||||||
|
bool isPeakUnderBox = cPeak < box.upper;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool hasBullishPress =
|
||||||
|
// isBullish &&
|
||||||
|
(isSWLOverBox ||
|
||||||
|
isValeOverBox);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool hasBearishPress =
|
||||||
|
// isBearish &&
|
||||||
|
(isSWHUnderBox ||
|
||||||
|
isPeakUnderBox);
|
||||||
|
|
||||||
|
//
|
||||||
|
double trends[] = {
|
||||||
|
cMAH,
|
||||||
|
cMAC,
|
||||||
|
cMAL,
|
||||||
|
cKI,
|
||||||
|
cTKI,
|
||||||
|
cFast,
|
||||||
|
cVidya,
|
||||||
|
cTrend //
|
||||||
|
};
|
||||||
|
double trendMax = GetMax(trends);
|
||||||
|
double trendMin = GetMin(trends);
|
||||||
|
Copy(
|
||||||
|
trends,
|
||||||
|
sls //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCloseOverMax = cBar.close > trendMax;
|
||||||
|
bool isCloseUnderMin = cBar.close < trendMin;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isStateBullish =
|
||||||
|
cKIState > 0 &&
|
||||||
|
cTKIState > 0 &&
|
||||||
|
cFastState > 0 &&
|
||||||
|
cTrendState > 0 &&
|
||||||
|
cVidyaState > 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isStateBearish =
|
||||||
|
cKIState < 0 &&
|
||||||
|
cTKIState < 0 &&
|
||||||
|
cFastState < 0 &&
|
||||||
|
cTrendState < 0 &&
|
||||||
|
cVidyaState < 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool hasBullishTrend =
|
||||||
|
// isBullish &&
|
||||||
|
isStateBullish &&
|
||||||
|
isCloseOverMax;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool hasBearishTrend =
|
||||||
|
// isBearish &&
|
||||||
|
isStateBearish &&
|
||||||
|
isCloseUnderMin;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Summarizing ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canTriggerLong =
|
||||||
|
// isBullish &&
|
||||||
|
hasBullishPress &&
|
||||||
|
hasBullishTrend;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canTriggerShort =
|
||||||
|
// isBearish &&
|
||||||
|
hasBearishPress &&
|
||||||
|
hasBearishTrend;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = canTriggerLong ||
|
||||||
|
canTriggerShort;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir = canTriggerLong
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
|
||||||
|
//
|
||||||
|
Print("Triggered ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
|
||||||
|
//
|
||||||
|
cBar.Clean();
|
||||||
|
Clean(trends);
|
||||||
|
conditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,878 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XCXCAEASignaller ...
|
||||||
|
// Description: Class for XCAEA Signaller ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XCAEA Signaller"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../../Classes/x-saherelm.base.class.mq5"
|
||||||
|
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
|
||||||
|
#include "../Classes/xcaea.x-poi.detector.class.mq5"
|
||||||
|
#include "../Classes/xcaea.x-poi.drawer.class.mq5"
|
||||||
|
#include "../Helpers/xcaea.helper.mq5"
|
||||||
|
#include "../Libraries/xcaea.signaller.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
class XCXCAEASignaller : XCBase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
bool useGuards;
|
||||||
|
XCAEAInputs inputs;
|
||||||
|
XBarTracker barTraker;
|
||||||
|
XCXCAEAHelper *helper;
|
||||||
|
XCXCAEAPOIDrawer *drawer;
|
||||||
|
bool continuesRFTillTarget;
|
||||||
|
XBoxZone unAvailableBoxes[];
|
||||||
|
XCXCAEAPOIDetector *detector;
|
||||||
|
XCAEAStrategyConditions mConditions;
|
||||||
|
XCAEAStrategyConditions mConditionsCollection[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XCXCAEASignaller(
|
||||||
|
string _symbol,
|
||||||
|
ENUM_TIMEFRAMES _period //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
symbol = _symbol;
|
||||||
|
period = _period;
|
||||||
|
|
||||||
|
//
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCXCAEASignaller()
|
||||||
|
{
|
||||||
|
DeInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Properties ...
|
||||||
|
|
||||||
|
string GetSymbol()
|
||||||
|
{
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENUM_TIMEFRAMES GetPeriod()
|
||||||
|
{
|
||||||
|
return period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signaller Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Setup Conditions based on Signalling ...
|
||||||
|
*
|
||||||
|
* @param maxAllowedSLDistanceInPoint: int, Max Allowed SL Distance in Points (if Bigger thn Zero Provided) ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectSignalSetup(
|
||||||
|
double tpReward = 3,
|
||||||
|
double maxAllowedSLDistanceInPoint = 100 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bar Processing ...
|
||||||
|
if (!barTraker.CanProcessBar())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = false;
|
||||||
|
bool isBearish = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIndex = 0;
|
||||||
|
int cIndex = zIndex + 1;
|
||||||
|
int pIndex = cIndex + 1;
|
||||||
|
int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
int loopback = 10;
|
||||||
|
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
double ask = GetAsk(symbol);
|
||||||
|
double bid = GetBid(symbol);
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
XOHCL cBar;
|
||||||
|
XOHCL pBar;
|
||||||
|
XOHCL pPBar;
|
||||||
|
result = zBar.Init(
|
||||||
|
symbol,
|
||||||
|
period,
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
zBar.GetPreviousBar(cBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
cBar.GetPreviousBar(pBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
pBar.GetPreviousBar(pPBar);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
pPBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup Conditions ...
|
||||||
|
XBoxZone boxes[];
|
||||||
|
XBoxZone pivotBox;
|
||||||
|
XBoxZone signalBox;
|
||||||
|
double additionalSL = 0;
|
||||||
|
XBoxZone bullishBoxes[];
|
||||||
|
XBoxZone bearishBoxes[];
|
||||||
|
bool hasSignalBox = false;
|
||||||
|
XCAEAConditions conditions;
|
||||||
|
ENUM_X_DIRECTION signalBoxDir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detecting Pivots ...
|
||||||
|
detector.Update(
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Pivots ...
|
||||||
|
detector.Validate(
|
||||||
|
unAvailableBoxes,
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Founded Pivots ...
|
||||||
|
drawer.Draw(cTime);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Valid Boxes ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish ...
|
||||||
|
int bullishBoxesCount =
|
||||||
|
detector
|
||||||
|
.FillBullishBoxes(bullishBoxes);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish ...
|
||||||
|
int bearishBoxesCount =
|
||||||
|
detector
|
||||||
|
.FillBearishBoxes(bearishBoxes);
|
||||||
|
|
||||||
|
//
|
||||||
|
Copy(
|
||||||
|
bullishBoxes,
|
||||||
|
boxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
bearishBoxes,
|
||||||
|
boxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
int boxesCount = ArraySize(boxes);
|
||||||
|
bool hasBoxes = IsValidSize(boxesCount);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filter UnAvailable Boxes ...
|
||||||
|
if (hasBoxes)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Remove UnAvailable Boxes ...
|
||||||
|
has = HasChild(unAvailableBoxes);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
count = ArraySize(unAvailableBoxes);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = unAvailableBoxes[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
has = FindBoxIndex(
|
||||||
|
idx,
|
||||||
|
iBox,
|
||||||
|
boxes //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArrayRemove(
|
||||||
|
boxes,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
hasBoxes = HasChild(boxes);
|
||||||
|
boxesCount = ArraySize(boxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// if (hasBoxes)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Sinal Box ...
|
||||||
|
hasSignalBox = DetectXCAEAConditions(
|
||||||
|
boxes,
|
||||||
|
conditions,
|
||||||
|
pivotBox,
|
||||||
|
signalBox,
|
||||||
|
additionalSL,
|
||||||
|
signalBoxDir,
|
||||||
|
helper,
|
||||||
|
zIndex,
|
||||||
|
loopback //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make Pivot Box UnAvailable ...
|
||||||
|
if (pivotBox.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
pivotBox,
|
||||||
|
unAvailableBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
isBullish = hasSignalBox &&
|
||||||
|
IsBullish(signalBoxDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
isBearish = hasSignalBox &&
|
||||||
|
IsBearish(signalBoxDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Do What we Want ...
|
||||||
|
barTraker.Waits();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Signal Box ...
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
bool isCreated = helper.poiDrawer.DrawBox(
|
||||||
|
signalBox,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mObjects.Add(iObj);
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
|
||||||
|
//
|
||||||
|
Print("Signal Box ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Conditions ...
|
||||||
|
mConditions.symbol = symbol;
|
||||||
|
mConditions.period = period;
|
||||||
|
|
||||||
|
//
|
||||||
|
double spread = GetSpread(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
double entry =
|
||||||
|
isBullish
|
||||||
|
? signalBox.upper
|
||||||
|
: signalBox.lower;
|
||||||
|
|
||||||
|
//
|
||||||
|
double sl =
|
||||||
|
isBullish
|
||||||
|
? signalBox.lower
|
||||||
|
: signalBox.upper;
|
||||||
|
if (additionalSL > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
sl =
|
||||||
|
isBullish
|
||||||
|
? sl - additionalSL
|
||||||
|
: sl + additionalSL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double risk =
|
||||||
|
isBullish
|
||||||
|
? entry - sl
|
||||||
|
: sl - entry;
|
||||||
|
risk += spread;
|
||||||
|
if (risk >= maxAllowedSLDistanceInPoint * points)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Fix Risk in Big Distances ...
|
||||||
|
double hh5 = zBar.FindHighest(5, MODE_HIGH);
|
||||||
|
double ll5 = zBar.FindLowest(5, MODE_LOW);
|
||||||
|
|
||||||
|
//
|
||||||
|
double hhll5Delta = hh5 - ll5;
|
||||||
|
double riskDelta = hhll5Delta / 2;
|
||||||
|
risk = riskDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double rewardTP = risk * tpReward;
|
||||||
|
|
||||||
|
//
|
||||||
|
double tp =
|
||||||
|
isBullish
|
||||||
|
? entry + rewardTP
|
||||||
|
: entry - rewardTP;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filling ...
|
||||||
|
mConditions.sl = sl;
|
||||||
|
mConditions.tp = tp;
|
||||||
|
mConditions.pivot =
|
||||||
|
isBullish
|
||||||
|
? sl
|
||||||
|
: entry;
|
||||||
|
mConditions.point =
|
||||||
|
isBullish
|
||||||
|
? entry
|
||||||
|
: sl;
|
||||||
|
mConditions.dir = signalBoxDir;
|
||||||
|
mConditions.provider = "XCAEA";
|
||||||
|
mConditions.signalBox = signalBox;
|
||||||
|
mConditions.setupTime = zBar.time;
|
||||||
|
mConditions.conditions = conditions;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select RF Rewards ...
|
||||||
|
if (continuesRFTillTarget)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double rfReward = 1;
|
||||||
|
while (rfReward < tpReward)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double rewardRF = risk * rfReward;
|
||||||
|
double rfTP =
|
||||||
|
isBullish
|
||||||
|
? entry + rewardRF
|
||||||
|
: entry - rewardRF;
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
rfTP,
|
||||||
|
mConditions.targets //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
rfReward++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double rfReward = 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
double rewardRF = risk * rfReward;
|
||||||
|
double rfTP =
|
||||||
|
isBullish
|
||||||
|
? entry + rewardRF
|
||||||
|
: entry - rewardRF;
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
rfTP,
|
||||||
|
mConditions.targets //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resource ...
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(boxes);
|
||||||
|
Clean(bullishBoxes);
|
||||||
|
Clean(bearishBoxes);
|
||||||
|
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
pPBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
pivotBox.Clean();
|
||||||
|
signalBox.Clean();
|
||||||
|
conditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Trigger Conditions for Specified Signal ...
|
||||||
|
*
|
||||||
|
* @param conditions: XCAEAStrategyConditions instance Reference, Specified Signal Conditions ...
|
||||||
|
* @param maxAllowedSetupAge: specified Setup Age for Expiration (if bigger than Zero) ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectSignalTrigger(
|
||||||
|
XCAEAStrategyConditions &conditions,
|
||||||
|
int maxAllowedSetupAge = 60 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = conditions.IsSetuped();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
datetime setupTime = conditions.setupTime;
|
||||||
|
ENUM_X_DIRECTION setupDir = conditions.dir;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = IsBullish(setupDir);
|
||||||
|
bool isBearish = IsBearish(setupDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIndex = 0;
|
||||||
|
int cIndex = zIndex + 1;
|
||||||
|
int pIndex = cIndex + 1;
|
||||||
|
int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
int loopback = 10;
|
||||||
|
|
||||||
|
//
|
||||||
|
double ask = GetAsk(symbol);
|
||||||
|
double bid = GetBid(symbol);
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Signal Validation ...
|
||||||
|
// IMPORTANT: since all Validations done in SetUp Process ...
|
||||||
|
// here we only Execute Signal ...
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
conditions.triggerTime = cTime;
|
||||||
|
conditions.type = isBullish
|
||||||
|
? X_POSITION_TYPE_LONG
|
||||||
|
: X_POSITION_TYPE_SHORT;
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Guards bsed on Signalling Class ...
|
||||||
|
*
|
||||||
|
* @param guards: XCAEAGuard instance Collection, Holds Provided Guards ...
|
||||||
|
* @param positions: XPosition instance Collection, Provides Signalling Based Positions for Apply Guards on them ...
|
||||||
|
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectGuards(
|
||||||
|
XCAEAGuard &guards[],
|
||||||
|
const XPosition &positions[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Conditions to Conditions Collection if not Exists ...
|
||||||
|
*
|
||||||
|
* @param maxAllowed: int, Specified Max Allowed Holding Conditions ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int AddConditionsIfNotExists(
|
||||||
|
int maxAllowed = 10 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isSetuped = IsValid(mConditions.setupTime) &&
|
||||||
|
HasDirection(mConditions.dir);
|
||||||
|
if (!isSetuped)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(mConditionsCollection);
|
||||||
|
if (IsValidSize(count))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Copy Original Items ...
|
||||||
|
XCAEAStrategyConditions tmpItems[];
|
||||||
|
Copy(
|
||||||
|
mConditionsCollection,
|
||||||
|
tmpItems //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prese Item Data ...
|
||||||
|
bool isBullish = IsBullish(mConditions.dir);
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCAEAStrategyConditions iItem = tmpItems[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canRemove = mConditions.dir == iItem.dir &&
|
||||||
|
mConditions.pivot == iItem.pivot;
|
||||||
|
if (canRemove)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArrayRemove(
|
||||||
|
mConditionsCollection,
|
||||||
|
i,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(tmpItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
mConditions,
|
||||||
|
mConditionsCollection //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Olds ...
|
||||||
|
CleanupArray(
|
||||||
|
mConditionsCollection,
|
||||||
|
maxAllowed //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(mConditionsCollection);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
string symbol;
|
||||||
|
ENUM_TIMEFRAMES period;
|
||||||
|
CArrayObj mObjects;
|
||||||
|
CArrayObj mBarObjects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize ...
|
||||||
|
*/
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
useGuards = false;
|
||||||
|
continuesRFTillTarget = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
barTraker.Init(
|
||||||
|
symbol,
|
||||||
|
period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.Default();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Indicators ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCC ...
|
||||||
|
inputs.ccInputs.showCandles = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCT ...
|
||||||
|
inputs.ctInputs.showCandleTime = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCA ...
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.caInputs.supResSmoothingLength = 7;
|
||||||
|
inputs.caInputs.supResSmoothingMode = X_MA_MODE_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.caInputs.showKI = true;
|
||||||
|
inputs.caInputs.showTKI = false;
|
||||||
|
inputs.caInputs.showSar = false;
|
||||||
|
inputs.caInputs.showVidya = true;
|
||||||
|
inputs.caInputs.showTrend = false;
|
||||||
|
inputs.caInputs.showSwings = false;
|
||||||
|
inputs.caInputs.showLongCycle = false;
|
||||||
|
inputs.caInputs.showHindCycle = false;
|
||||||
|
inputs.caInputs.showFiboLevel1 = false;
|
||||||
|
inputs.caInputs.showFiboLevel2 = false;
|
||||||
|
inputs.caInputs.showFiboLevel3 = false;
|
||||||
|
inputs.caInputs.showShortCycle = false;
|
||||||
|
inputs.caInputs.showMediumCycle = false;
|
||||||
|
inputs.caInputs.showPeaksAndVales = true;
|
||||||
|
inputs.caInputs.showPeakAndValeGolden = false;
|
||||||
|
inputs.caInputs.showSupportAndResistance = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XOSCS ...
|
||||||
|
// inputs.oscsInputs.rsiLength = 5;
|
||||||
|
// inputs.oscsInputs.cciLength = 5;
|
||||||
|
// inputs.oscsInputs.mfiLength = 5;
|
||||||
|
// inputs.oscsInputs.rviLength = 5;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Oscillators Views ...
|
||||||
|
inputs.showCCI = false;
|
||||||
|
inputs.showRSI = false;
|
||||||
|
inputs.showMFI = false;
|
||||||
|
inputs.showRVI = false;
|
||||||
|
inputs.showADX = false;
|
||||||
|
inputs.showMACD = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCAEA Helper ...
|
||||||
|
helper = new XCXCAEAHelper();
|
||||||
|
helper.Init(
|
||||||
|
symbol,
|
||||||
|
period,
|
||||||
|
inputs //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize and Configure Detector ...
|
||||||
|
detector = new XCXCAEAPOIDetector(helper);
|
||||||
|
|
||||||
|
//
|
||||||
|
detector.detectSWHPivot = false;
|
||||||
|
detector.detectSWLPivot = false;
|
||||||
|
detector.detectPeakPivot = false;
|
||||||
|
detector.detectValePivot = false;
|
||||||
|
detector.detectRSIPeakPivot = true;
|
||||||
|
detector.detectRSIValePivot = true;
|
||||||
|
detector.detectCCIPeakPivot = true;
|
||||||
|
detector.detectCCIValePivot = true;
|
||||||
|
detector.detectKIBullishPivot = false;
|
||||||
|
detector.detectKIBearishPivot = false;
|
||||||
|
detector.detectFVGBullishPivot = true;
|
||||||
|
detector.detectFVGBearishPivot = true;
|
||||||
|
detector.detectPeakSWHResPivot = true;
|
||||||
|
detector.detectValeSWLSupPivot = true;
|
||||||
|
detector.detectTKIBullishPivot = false;
|
||||||
|
detector.detectCycleSameLLPivot = false;
|
||||||
|
detector.detectCycleSameHHPivot = false;
|
||||||
|
detector.detectTKIBearishPivot = false;
|
||||||
|
detector.detectTrendBullishPivot = false;
|
||||||
|
detector.detectTrendBearishPivot = false;
|
||||||
|
detector.detectTKITRNDBullishPivot = false;
|
||||||
|
detector.detectTKITRNDBearishPivot = false;
|
||||||
|
detector.detectRSICrossedOverOSPivot = false;
|
||||||
|
detector.detectRSICrossedUnderOBPivot = false;
|
||||||
|
detector.detectCCICrossedOverOSPivot = false;
|
||||||
|
detector.detectCCICrossedUnderOBPivot = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize and Configure Drawer ...
|
||||||
|
drawer = new XCXCAEAPOIDrawer(detector);
|
||||||
|
|
||||||
|
//
|
||||||
|
// UnActive Pivots ...
|
||||||
|
drawer.drawSWHPivots = false;
|
||||||
|
drawer.drawSWLPivots = false;
|
||||||
|
drawer.drawPeakPivots = false;
|
||||||
|
drawer.drawValePivots = false;
|
||||||
|
drawer.drawRSIPeakPivots = true; // true;
|
||||||
|
drawer.drawRSIValePivots = true; // true;
|
||||||
|
drawer.drawCCIPeakPivots = false; // true;
|
||||||
|
drawer.drawCCIValePivots = false; // true;
|
||||||
|
drawer.drawKIBullishPivots = false;
|
||||||
|
drawer.drawKIBearishPivots = false;
|
||||||
|
drawer.drawFVGBullishPivots = false;
|
||||||
|
drawer.drawFVGBearishPivots = false;
|
||||||
|
drawer.drawPeakSWHResPivots = false; // true;
|
||||||
|
drawer.drawValeSWLSupPivots = false; // true;
|
||||||
|
drawer.drawTKIBullishPivots = false;
|
||||||
|
drawer.drawTKIBearishPivots = false;
|
||||||
|
drawer.drawPVFVGBullishPivots = false; // true;
|
||||||
|
drawer.drawPVFVGBearishPivots = false; // true;
|
||||||
|
drawer.drawCycleSameLLPivots = false;
|
||||||
|
drawer.drawCycleSameHHPivots = false;
|
||||||
|
drawer.drawTrendBullishPivots = false;
|
||||||
|
drawer.drawTrendBearishPivots = false;
|
||||||
|
drawer.drawTKITRNDBullishPivots = false;
|
||||||
|
drawer.drawTKITRNDBearishPivots = false;
|
||||||
|
drawer.drawRSICrossedOverOSPivots = false;
|
||||||
|
drawer.drawRSICrossedUnderOBPivots = false;
|
||||||
|
drawer.drawCCICrossedOverOSPivots = false;
|
||||||
|
drawer.drawCCICrossedUnderOBPivots = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
drawer.drawTicks = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Width ...
|
||||||
|
drawer.peakPivotWidth = 1;
|
||||||
|
drawer.valePivotWidth = 1;
|
||||||
|
drawer.ticksBullishWidth = 2;
|
||||||
|
drawer.ticksBearishWidth = 2;
|
||||||
|
drawer.fvgBullishPivotWidth = 1;
|
||||||
|
drawer.fvgBearishPivotWidth = 1;
|
||||||
|
drawer.oscsBullishPivotWidth = 2;
|
||||||
|
drawer.oscsBearishPivotWidth = 2;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Colors ...
|
||||||
|
drawer.peakPivotColor = clrMagenta;
|
||||||
|
drawer.valePivotColor = clrAqua;
|
||||||
|
drawer.ticksBullishColor = clrYellow;
|
||||||
|
drawer.ticksBearishColor = clrOrange;
|
||||||
|
drawer.fvgBullishPivotColor = clrLime;
|
||||||
|
drawer.fvgBearishPivotColor = clrRed;
|
||||||
|
drawer.oscsBullishPivotColor = clrAqua;
|
||||||
|
drawer.oscsBearishPivotColor = clrMagenta;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Style ...
|
||||||
|
drawer.peakPivotStyle = STYLE_SOLID;
|
||||||
|
drawer.valePivotStyle = STYLE_SOLID;
|
||||||
|
drawer.ticksBullishStyle = STYLE_DOT;
|
||||||
|
drawer.ticksBearishStyle = STYLE_DOT;
|
||||||
|
drawer.fvgBullishPivotStyle = STYLE_DASH;
|
||||||
|
drawer.fvgBearishPivotStyle = STYLE_DASH;
|
||||||
|
drawer.oscsBullishPivotStyle = STYLE_SOLID;
|
||||||
|
drawer.oscsBearishPivotStyle = STYLE_SOLID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeInitialize ...
|
||||||
|
*/
|
||||||
|
void DeInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
inputs.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(drawer);
|
||||||
|
ZeroMemory(helper);
|
||||||
|
ZeroMemory(detector);
|
||||||
|
|
||||||
|
//
|
||||||
|
mConditions.Clean();
|
||||||
|
Clean(mConditionsCollection);
|
||||||
|
|
||||||
|
//
|
||||||
|
mObjects.Clear();
|
||||||
|
mBarObjects.Clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
barTraker.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,279 @@
|
|||||||
|
<mxfile host="65bd71144e">
|
||||||
|
<diagram id="QReEEfusIJtThQdlE9lK" name="Page-1">
|
||||||
|
<mxGraphModel dx="1382" dy="987" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="15" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="3">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="420" y="100"/>
|
||||||
|
<mxPoint x="100" y="100"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="16" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="6">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="420" y="100"/>
|
||||||
|
<mxPoint x="780" y="100"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="2" value="Position" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="360" y="40" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="17" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="4">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="100" y="340"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="18" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3" target="5">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="100" y="620"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="3" value="States" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="40" y="120" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="27" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="25">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="180" y="420"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="28" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="26">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="180" y="500"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="4" value="InDrawdown" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="120" y="320" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="29" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="23">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="180" y="700"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="30" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="24">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="180" y="780"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="5" value="InProfit" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="120" y="600" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="19" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="8">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="780" y="220"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="20" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="9">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="780" y="300"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="21" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="11">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="780" y="380"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="22" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="6" target="10">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="780" y="460"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="6" value="Events" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="720" y="120" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="31" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="25">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="260" y="220"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="38" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="26">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="520" y="220"/>
|
||||||
|
<mxPoint x="520" y="560"/>
|
||||||
|
<mxPoint x="260" y="560"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="39" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="23">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="220"/>
|
||||||
|
<mxPoint x="560" y="640"/>
|
||||||
|
<mxPoint x="260" y="640"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="43" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8" target="24">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="220"/>
|
||||||
|
<mxPoint x="560" y="840"/>
|
||||||
|
<mxPoint x="260" y="840"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="8" value="Bullish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="640" y="200" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="32" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="25">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="260" y="300"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="37" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="26">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="520" y="300"/>
|
||||||
|
<mxPoint x="520" y="560"/>
|
||||||
|
<mxPoint x="260" y="560"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="40" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="23">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="300"/>
|
||||||
|
<mxPoint x="560" y="640"/>
|
||||||
|
<mxPoint x="260" y="640"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="44" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="9" target="24">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="300"/>
|
||||||
|
<mxPoint x="560" y="840"/>
|
||||||
|
<mxPoint x="260" y="840"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="9" value="Bearish Sign" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="640" y="280" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="34" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="260" y="400" as="targetPoint"/>
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="520" y="460"/>
|
||||||
|
<mxPoint x="520" y="360"/>
|
||||||
|
<mxPoint x="260" y="360"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="35" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="26">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="520" y="460"/>
|
||||||
|
<mxPoint x="520" y="560"/>
|
||||||
|
<mxPoint x="260" y="560"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="42" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="10">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="260" y="680" as="targetPoint"/>
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="460"/>
|
||||||
|
<mxPoint x="560" y="640"/>
|
||||||
|
<mxPoint x="260" y="640"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="46" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="24">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<mxPoint x="260" y="810" as="targetPoint"/>
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="460"/>
|
||||||
|
<mxPoint x="560" y="840"/>
|
||||||
|
<mxPoint x="260" y="840"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="10" value="Bearish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="640" y="440" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="33" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="25">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="520" y="380"/>
|
||||||
|
<mxPoint x="520" y="360"/>
|
||||||
|
<mxPoint x="260" y="360"/>
|
||||||
|
<mxPoint x="260" y="380"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="36" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="26">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="520" y="380"/>
|
||||||
|
<mxPoint x="520" y="560"/>
|
||||||
|
<mxPoint x="260" y="560"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="41" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="23">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="380"/>
|
||||||
|
<mxPoint x="560" y="640"/>
|
||||||
|
<mxPoint x="260" y="640"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="45" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="11" target="24">
|
||||||
|
<mxGeometry relative="1" as="geometry">
|
||||||
|
<Array as="points">
|
||||||
|
<mxPoint x="560" y="380"/>
|
||||||
|
<mxPoint x="560" y="840"/>
|
||||||
|
<mxPoint x="260" y="840"/>
|
||||||
|
</Array>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="11" value="Bullish Pushed Tick" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="640" y="360" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="23" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="200" y="680" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="24" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="200" y="760" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="25" value="Long" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="200" y="400" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="26" value="Short" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="200" y="480" width="120" height="40" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
||||||
@@ -0,0 +1,506 @@
|
|||||||
|
/**
|
||||||
|
* XColor Tools Module ...
|
||||||
|
* a module for handle colorify text contents in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Imports ...
|
||||||
|
const XValueTools = require("./x-value.tools");
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
/**
|
||||||
|
* these are available style which can applied to an string ...
|
||||||
|
*/
|
||||||
|
const AVAILABLE_STYLES = {
|
||||||
|
//
|
||||||
|
Bold: "\x1b[1m",
|
||||||
|
Dim: "\x1b[2m",
|
||||||
|
Underlined: "\x1b[4m",
|
||||||
|
Blink: "\x1b[5m",
|
||||||
|
ReverseFandB: "\x1b[7m",
|
||||||
|
Hidden: "\x1b[8m",
|
||||||
|
//
|
||||||
|
// Commonly used for reset all Styles ...
|
||||||
|
Reset: "\x1b[0m"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available foreground colors which can applied to an string ...
|
||||||
|
*/
|
||||||
|
const AVAILABLE_FOREGROUND_COLORS = {
|
||||||
|
Default: "\x1b[39m",
|
||||||
|
Black: "\x1b[30m",
|
||||||
|
Red: "\x1b[31m",
|
||||||
|
Green: "\x1b[32m",
|
||||||
|
Yellow: "\x1b[33m",
|
||||||
|
Blue: "\x1b[34m",
|
||||||
|
Magenta: "\x1b[35m",
|
||||||
|
Cyan: "\x1b[36m",
|
||||||
|
LightGray: "\x1b[37m",
|
||||||
|
DarkGray: "\x1b[90m",
|
||||||
|
LightRed: "\x1b[91m",
|
||||||
|
LightGreen: "\x1b[92m",
|
||||||
|
LightYellow: "\x1b[93m",
|
||||||
|
LightBlue: "\x1b[94m",
|
||||||
|
LightMagenta: "\x1b[95m",
|
||||||
|
LightCyan: "\x1b[96m",
|
||||||
|
White: "\x1b[97m",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available background colors which can applied to an string ...
|
||||||
|
*/
|
||||||
|
const AVAILABLE_BACKGROUND_COLORS = {
|
||||||
|
Default: "\x1b[49m",
|
||||||
|
Black: "\x1b[40m",
|
||||||
|
Red: "\x1b[41m",
|
||||||
|
Green: "\x1b[42m",
|
||||||
|
Yellow: "\x1b[43m",
|
||||||
|
Blue: "\x1b[44m",
|
||||||
|
Magenta: "\x1b[45m",
|
||||||
|
Cyan: "\x1b[46m",
|
||||||
|
LightGray: "\x1b[47m",
|
||||||
|
DarkGray: "\x1b[100m",
|
||||||
|
LightRed: "\x1b[101m",
|
||||||
|
LightGreen: "\x1b[102m",
|
||||||
|
LightYellow: "\x1b[103m",
|
||||||
|
LightBlue: "\x1b[104m",
|
||||||
|
LightMagenta: "\x1b[105m",
|
||||||
|
LightCyan: "\x1b[106m",
|
||||||
|
White: "\x1b[107m",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available style names, which exports from module and
|
||||||
|
* users can use them ...
|
||||||
|
*/
|
||||||
|
const STYLE_NAMES = {
|
||||||
|
Bold: "Bold",
|
||||||
|
Dim: "Dim",
|
||||||
|
Underlined: "Underlined",
|
||||||
|
Blink: "Blink",
|
||||||
|
ReverseFandB: "ReverseFandB",
|
||||||
|
Hidden: "Hidden",
|
||||||
|
Reset: "Reset",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* these are available color names, which exports from module and
|
||||||
|
* users can use them ...
|
||||||
|
*/
|
||||||
|
const COLOR_NAMES = {
|
||||||
|
Default: "Default",
|
||||||
|
Black: "Black",
|
||||||
|
Red: "Red",
|
||||||
|
Green: "Green",
|
||||||
|
Yellow: "Yellow",
|
||||||
|
Blue: "Blue",
|
||||||
|
Magenta: "Magenta",
|
||||||
|
Cyan: "Cyan",
|
||||||
|
LightGray: "LightGray",
|
||||||
|
DarkGray: "DarkGray",
|
||||||
|
LightRed: "LightRed",
|
||||||
|
LightGreen: "LightGreen",
|
||||||
|
LightYellow: "LightYellow",
|
||||||
|
LightBlue: "LightBlue",
|
||||||
|
LightMagenta: "LightMagenta",
|
||||||
|
LightCyan: "LightCyan",
|
||||||
|
White: "White",
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
/**
|
||||||
|
* apply specified style and color on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specified content for styling ...
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string} styled content ...
|
||||||
|
*/
|
||||||
|
function apply(
|
||||||
|
content,
|
||||||
|
color,
|
||||||
|
style,
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = content;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply specific style on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specific content which going to styled ...
|
||||||
|
* @param {string} style a member of STYLE_NAMES which specified that which style going to applied to content ...
|
||||||
|
* @returns {string} styled content ...
|
||||||
|
*/
|
||||||
|
function applyStyle(content, style) {
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (eStyle === undefined) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return `${eStyle}${content}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply specific foreground color on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specific content which going to colorified ...
|
||||||
|
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
|
||||||
|
* @returns {string} colorified content ...
|
||||||
|
*/
|
||||||
|
function applyForegroundColor(content, color) {
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let eColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (eColor === undefined) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply specific background color on a content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specific content which going to colorified ...
|
||||||
|
* @param {string} color a member of COLOR_NAMES which specified that which color going to applied to content ...
|
||||||
|
* @returns {string} colorified content ...
|
||||||
|
*/
|
||||||
|
function applyBackgroundColor(content, color) {
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let eColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (eColor === undefined) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return `${eColor}${content}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate style and color applier expression ...
|
||||||
|
*
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @param {boolean} reset close applier string by reset styles ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string} style and color applier string ...
|
||||||
|
*/
|
||||||
|
function getApplier(
|
||||||
|
style = "",
|
||||||
|
color = "",
|
||||||
|
reset = false,
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!!reset &&
|
||||||
|
result.length > 0
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate style applier expression ...
|
||||||
|
*
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @param {boolean} reset close applier string by reset styles ...
|
||||||
|
* @returns {string} style applier string ...
|
||||||
|
*/
|
||||||
|
function getStyleApplier(
|
||||||
|
style = "",
|
||||||
|
reset = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!!reset &&
|
||||||
|
result.length > 0
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate color applier expression ...
|
||||||
|
*
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {boolean} reset close applier string by reset styles ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string} color applier string ...
|
||||||
|
*/
|
||||||
|
function getColorApplier(
|
||||||
|
color = "",
|
||||||
|
reset = false,
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!!reset &&
|
||||||
|
result.length > 0
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* colorified specific content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specified content for styling ...
|
||||||
|
* @param {string} color specific color name for using to styling ...
|
||||||
|
* @param {boolean} toForeground apply specified color as foreground ...
|
||||||
|
* @param {boolean} toBackground apply specified color as background ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function colorifyContent(
|
||||||
|
content = "",
|
||||||
|
color = "",
|
||||||
|
toForeground = true,
|
||||||
|
toBackground = false
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = content;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Finde Colors ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Foreground Color and Apply it ...
|
||||||
|
let eFColor = AVAILABLE_FOREGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toForeground
|
||||||
|
&& XValueTools.isValidArg(eFColor)
|
||||||
|
) {
|
||||||
|
result = `${eFColor}${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Background Color and Apply it ...
|
||||||
|
let eBColor = AVAILABLE_BACKGROUND_COLORS[color];
|
||||||
|
if (
|
||||||
|
!!toBackground
|
||||||
|
&& XValueTools.isValidArg(eBColor)
|
||||||
|
) {
|
||||||
|
result = `${eBColor}${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
result.length > 0
|
||||||
|
&& (
|
||||||
|
XValueTools.isValidArg(eFColor) ||
|
||||||
|
XValueTools.isValidArg(eBColor)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apply style on specific content ...
|
||||||
|
*
|
||||||
|
* @param {string} content specified content for styling ...
|
||||||
|
* @param {string} style soecufic style name to use ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function stylifiyContent(
|
||||||
|
content = "",
|
||||||
|
style = "",
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = content;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(content)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect and Validate Style and Apply it ...
|
||||||
|
let eStyle = AVAILABLE_STYLES[style];
|
||||||
|
if (XValueTools.isValidArg(eStyle)) {
|
||||||
|
result = `${eStyle}${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
result.length > 0
|
||||||
|
&& XValueTools.isValidArg(eStyle)
|
||||||
|
) {
|
||||||
|
result = `${result}${AVAILABLE_STYLES.Reset}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
STYLE_NAMES,
|
||||||
|
COLOR_NAMES,
|
||||||
|
//
|
||||||
|
apply,
|
||||||
|
applyStyle,
|
||||||
|
getApplier,
|
||||||
|
getColorApplier,
|
||||||
|
getStyleApplier,
|
||||||
|
colorifyContent,
|
||||||
|
stylifiyContent,
|
||||||
|
applyForegroundColor,
|
||||||
|
applyBackgroundColor,
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,887 @@
|
|||||||
|
/**
|
||||||
|
* XFile Tools Module ...
|
||||||
|
* a module for handle all file/folder manipulating task in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Imports ...
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
const Path = require('path');
|
||||||
|
const http = require('http');
|
||||||
|
const https = require('https');
|
||||||
|
const XValueTools = require('./x-value.tools');
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
/**
|
||||||
|
* current os path separators ...
|
||||||
|
*/
|
||||||
|
const PathSeparator = Path.sep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current directory ...
|
||||||
|
*/
|
||||||
|
const CurrentDir = __dirname;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
//
|
||||||
|
//#region Global ...
|
||||||
|
/**
|
||||||
|
* retrieve a path status ...
|
||||||
|
*
|
||||||
|
* @param {string} path a path value to check ...
|
||||||
|
* @returns an stat object ...
|
||||||
|
*/
|
||||||
|
function getStatus(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return fs.statSync(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve user's Home path ...
|
||||||
|
*
|
||||||
|
* @returns {string} a path ...
|
||||||
|
*/
|
||||||
|
function getHomePath() {
|
||||||
|
return os.homedir();
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Path ...
|
||||||
|
/**
|
||||||
|
* retrieve the base name of specific address path ...
|
||||||
|
*
|
||||||
|
* @param {string} path address of file or folder ...
|
||||||
|
* @returns string ...
|
||||||
|
*/
|
||||||
|
function basename(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = Path.basename(path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* join several path segments together ...
|
||||||
|
*
|
||||||
|
* @param {...string} path path params ...
|
||||||
|
* @returns a joined paths ...
|
||||||
|
*/
|
||||||
|
function joinPath(...path) {
|
||||||
|
return Path.join(...path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resolve a relative path to absolute ...
|
||||||
|
*
|
||||||
|
* @param {string[]} path a path value to check ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function resolvePath(...path) {
|
||||||
|
return Path.resolve(...path);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region File ...
|
||||||
|
/**
|
||||||
|
* determines a path destination is a file or not ...
|
||||||
|
*
|
||||||
|
* @param {string} path a path value to check ...
|
||||||
|
* @returns a boolean value ...
|
||||||
|
*/
|
||||||
|
function isFileExists(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
const stat = getStatus(path);
|
||||||
|
if (!stat) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return stat.isFile();
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path a file path ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function removeFile(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isFileExists(path)) {
|
||||||
|
resolve(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.unlink(path, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy a file to destination path ...
|
||||||
|
*
|
||||||
|
* @param {string} source source file path ...
|
||||||
|
* @param {string} dest dest folder path ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function copyFile(
|
||||||
|
source = '',
|
||||||
|
dest = ''
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!isFileExists(source) ||
|
||||||
|
!isDirectoryExists(dest)
|
||||||
|
) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const destFilePath = Path.join(dest, Path.basename(source));
|
||||||
|
fs.copyFile(source, destFilePath, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reading specified file content ...
|
||||||
|
*
|
||||||
|
* @param {string} path a file path ...
|
||||||
|
* @returns {Promise<string>} file content ...
|
||||||
|
*/
|
||||||
|
function readFile(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isFileExists(path)) {
|
||||||
|
resolve('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readFile(path, 'utf8', (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(undefined);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(content);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write content to a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path a file path ...
|
||||||
|
* @param {string} content the content which going to write to the file ...
|
||||||
|
* @param {bool} overwrite determines file overwrite if exists ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function writeFile(
|
||||||
|
path = '',
|
||||||
|
content = '',
|
||||||
|
overwrite = true
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (isFileExists(path) && !overwrite) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Content ...
|
||||||
|
content = XValueTools.isValidArg(content) ?
|
||||||
|
content :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.writeFile(path, content, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path file path ...
|
||||||
|
* @param {string} fileName file name ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function createFile(
|
||||||
|
path = '',
|
||||||
|
fileName = ''
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
const filePath = Path.join(path, fileName);
|
||||||
|
if (
|
||||||
|
isFileExists(filePath) ||
|
||||||
|
!XValueTools.isValidArg(path) ||
|
||||||
|
!XValueTools.isValidArg(fileName)
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.writeFile(filePath, '', (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
//
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a file name extension ...
|
||||||
|
*
|
||||||
|
* @param {string} name
|
||||||
|
* @returns {string} name without extension ...
|
||||||
|
*/
|
||||||
|
function removeFileExtension(name = '') {
|
||||||
|
return name.substring(0, name.lastIndexOf('.')) || name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a file extension ...
|
||||||
|
*
|
||||||
|
* @param {string} path a path which locate a file ...
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getFileExtension(path = '') {
|
||||||
|
//
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Arg ...
|
||||||
|
if (
|
||||||
|
!XValueTools.isValidArg(path)
|
||||||
|
|| !isFileExists(path)
|
||||||
|
) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve just file name ...
|
||||||
|
const fileName = basename(path);
|
||||||
|
result = fileName.replace(
|
||||||
|
removeFileExtension(fileName),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve all files list recursively from specific path ...
|
||||||
|
*
|
||||||
|
* @param {string} path a source folder path ...
|
||||||
|
* @param {string[]} extensions which file extensions need to be listed, live empty for all files ...
|
||||||
|
* @returns {Promise<string[]>}
|
||||||
|
*/
|
||||||
|
async function getRecursiveFilesList(
|
||||||
|
path = "",
|
||||||
|
extensions = []
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (
|
||||||
|
!XValueTools.isValidArg(path)
|
||||||
|
|| !isDirectoryExists(path)
|
||||||
|
) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const contents = await getDirectoryContents(path);
|
||||||
|
for (const item of contents) {
|
||||||
|
//
|
||||||
|
const itemPath = joinPath(
|
||||||
|
path,
|
||||||
|
item
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
const isItemFile = isFileExists(itemPath);
|
||||||
|
if (isItemFile) {
|
||||||
|
//
|
||||||
|
const itemFileExtension = getFileExtension(itemPath);
|
||||||
|
const isFileInSupportedExtensions =
|
||||||
|
extensions === undefined || extensions.length === 0
|
||||||
|
? true
|
||||||
|
: extensions.includes(itemFileExtension)
|
||||||
|
;
|
||||||
|
if (isFileInSupportedExtensions) {
|
||||||
|
result.push(itemPath);
|
||||||
|
}
|
||||||
|
} else if (isDirectoryExists(itemPath)) {
|
||||||
|
//
|
||||||
|
const itemPathFiles = await getRecursiveFilesList(itemPath, extensions);
|
||||||
|
result.push(...itemPathFiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Specific files from a folder and it's content ...
|
||||||
|
*
|
||||||
|
* @param {string} path Folder Path ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function extractFiles(path = "", ext = [], excludeWorkspaceFolders = []) {
|
||||||
|
//
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!ext || ext.length == 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const pathContent = await getDirectoryContents(path);
|
||||||
|
if (!pathContent || pathContent.length == 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Loop through Content ...
|
||||||
|
for (const c of pathContent) {
|
||||||
|
//
|
||||||
|
// Prepare full path ...
|
||||||
|
const cPath = joinPath(path, c);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check content path is file or not ...
|
||||||
|
const isCFile = isFileExists(cPath);
|
||||||
|
const isCDirectory = isDirectoryExists(cPath);
|
||||||
|
if (isCFile) {
|
||||||
|
//
|
||||||
|
// Check it is MQL file or not ...
|
||||||
|
const cExt = getFileExtension(cPath);
|
||||||
|
if (ext.includes(cExt)) {
|
||||||
|
result.push(cPath);
|
||||||
|
}
|
||||||
|
} else if (isCDirectory) {
|
||||||
|
//
|
||||||
|
const destFolderName = basename(cPath);
|
||||||
|
const isExcluded = excludeWorkspaceFolders.includes(destFolderName);
|
||||||
|
if (isExcluded) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const cFiles = await extractFiles(cPath, ext);
|
||||||
|
if (cFiles && cFiles.length > 0) {
|
||||||
|
result.push(...cFiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Directory ...
|
||||||
|
/**
|
||||||
|
* create a directory ...
|
||||||
|
*
|
||||||
|
* @param {string} path destination path including dir name ...
|
||||||
|
* @param {boolean} recursive create directories recursively ...
|
||||||
|
* @returns action done or not ...
|
||||||
|
*/
|
||||||
|
function createDirectory(
|
||||||
|
path = '',
|
||||||
|
recursive = true
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
isDirectoryExists(path) ||
|
||||||
|
!XValueTools.isValidArg(path)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
//
|
||||||
|
fs.mkdirSync(path, { recursive: recursive });
|
||||||
|
result = true;
|
||||||
|
return result;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a directory ...
|
||||||
|
*
|
||||||
|
* @param {string} path destination path including dir name ...
|
||||||
|
* @param {boolean} recursive removes directories recursively ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
function removeDirectory(
|
||||||
|
path = '',
|
||||||
|
recursive = false
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.rm(path, {
|
||||||
|
recursive
|
||||||
|
}, (err) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines a path destination is a directory or not ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns represent destnation path is Directory or not ...
|
||||||
|
*/
|
||||||
|
function isDirectoryExists(path = '') {
|
||||||
|
//
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
//
|
||||||
|
const isExists = fs.existsSync(path);
|
||||||
|
if (!isExists) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const stat = getStatus(path);
|
||||||
|
if (!stat) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = stat.isDirectory();
|
||||||
|
return result;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a directory content ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns {Promise<string[]>} a collection of folder files ...
|
||||||
|
*/
|
||||||
|
function getDirectoryContents(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readdir(path, (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(content);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a directory files ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns {Promise<string[]>} a collection of folder files ...
|
||||||
|
*/
|
||||||
|
function getDirectoryFiles(
|
||||||
|
path = '',
|
||||||
|
containsHiddenFiles = false
|
||||||
|
) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readdir(path, (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!containsHiddenFiles) {
|
||||||
|
content = content.filter(c => !c.startsWith('.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = [];
|
||||||
|
content
|
||||||
|
.forEach(c => {
|
||||||
|
//
|
||||||
|
const cPath = Path.join(path, c);
|
||||||
|
if (isFileExists(cPath)) {
|
||||||
|
result.push(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve a directory folders ...
|
||||||
|
*
|
||||||
|
* @param {string} path a folder path ...
|
||||||
|
* @returns {Promise<string[]>} a collection of folder names ...
|
||||||
|
*/
|
||||||
|
function getDirectoryFolders(path = '') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
//
|
||||||
|
if (!isDirectoryExists(path)) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
fs.readdir(path, (err, content) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
resolve([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const result = [];
|
||||||
|
content.forEach(c => {
|
||||||
|
//
|
||||||
|
const cPath = Path.join(path, c);
|
||||||
|
if (isDirectoryExists(cPath)) {
|
||||||
|
result.push(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy a folder with all of it's content to dest ...
|
||||||
|
*
|
||||||
|
* @param {string} source source folder path ...
|
||||||
|
* @param {string} dest dest folder path ...
|
||||||
|
* @returns {Promise<boolean>} action done or not ...
|
||||||
|
*/
|
||||||
|
async function copyFolder(
|
||||||
|
source = '',
|
||||||
|
dest = ''
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
!isDirectoryExists(source) ||
|
||||||
|
!XValueTools.isValidArg(dest) ||
|
||||||
|
!XValueTools.isValidArg(source)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const folderName = Path.basename(source);
|
||||||
|
const destPath = Path.join(dest, folderName);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Dest Path folder if not exists ...
|
||||||
|
if (!isDirectoryExists(destPath)) {
|
||||||
|
//
|
||||||
|
let result = createDirectory(destPath, true);
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Files ...
|
||||||
|
const files = await getDirectoryFiles(source);
|
||||||
|
if (files && files.constructor === Array && files.length > 0) {
|
||||||
|
//
|
||||||
|
const filesPromises = files.map(file => copyFile(Path.join(source, file), destPath));
|
||||||
|
const filesResult = (await Promise.all(filesPromises)).every(r => !!r);
|
||||||
|
if (!filesResult) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Folders ...
|
||||||
|
const folders = await getDirectoryFolders(source);
|
||||||
|
if (folders && folders.constructor === Array && folders.length > 0) {
|
||||||
|
//
|
||||||
|
const folderPromises = folders.map(folder => copyFolder(Path.join(source, folder), destPath));
|
||||||
|
const filesResult = (await Promise.all(folderPromises)).every(r => !!r);
|
||||||
|
if (!filesResult) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Downloader ...
|
||||||
|
/**
|
||||||
|
* download a file from specific url and store it ...
|
||||||
|
*
|
||||||
|
* @param {string} filepath the file name and path which required to put download file on it ...
|
||||||
|
* @param {string} url the web url for downloading ...
|
||||||
|
*/
|
||||||
|
function download(filepath, url) {
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (
|
||||||
|
!XValueTools.isValidArg(url)
|
||||||
|
|| !XValueTools.isValidURL(url)
|
||||||
|
|| !XValueTools.isValidArg(filepath)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
var file = fs.createWriteStream(filepath);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (url.startsWith('https:')) {
|
||||||
|
https.get(url, function (response) {
|
||||||
|
response.pipe(file);
|
||||||
|
});
|
||||||
|
} else if (url.startsWith('http:')) {
|
||||||
|
http.get(url, function (response) {
|
||||||
|
response.pipe(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region JSON ...
|
||||||
|
/**
|
||||||
|
* read and parse a JSON content from a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path source file path ...
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
function readJSON(path = "") {
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (!isFileExists(path)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
let result = undefined;
|
||||||
|
try {
|
||||||
|
result = require(path);
|
||||||
|
} catch {
|
||||||
|
result = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write a JSON Object content into a file ...
|
||||||
|
*
|
||||||
|
* @param {string} path dest file path ...
|
||||||
|
* @param {any} content an object which required to write to file ...
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
async function writeJSON(
|
||||||
|
path = "",
|
||||||
|
content = undefined
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
let result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
if (!XValueTools.isValidArg(path)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normallize Content ...
|
||||||
|
if (content === undefined) {
|
||||||
|
content = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const contentString = XValueTools.beautifyJSON(content);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = await writeFile(
|
||||||
|
path,
|
||||||
|
contentString,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
CurrentDir,
|
||||||
|
PathSeparator,
|
||||||
|
|
||||||
|
//
|
||||||
|
getStatus,
|
||||||
|
getHomePath,
|
||||||
|
|
||||||
|
//
|
||||||
|
basename,
|
||||||
|
joinPath,
|
||||||
|
resolvePath,
|
||||||
|
|
||||||
|
//
|
||||||
|
download,
|
||||||
|
|
||||||
|
//
|
||||||
|
readJSON,
|
||||||
|
writeJSON,
|
||||||
|
|
||||||
|
//
|
||||||
|
copyFile,
|
||||||
|
readFile,
|
||||||
|
writeFile,
|
||||||
|
createFile,
|
||||||
|
removeFile,
|
||||||
|
isFileExists,
|
||||||
|
getFileExtension,
|
||||||
|
removeFileExtension,
|
||||||
|
getRecursiveFilesList,
|
||||||
|
extractFiles,
|
||||||
|
|
||||||
|
//
|
||||||
|
copyFolder,
|
||||||
|
createDirectory,
|
||||||
|
removeDirectory,
|
||||||
|
isDirectoryExists,
|
||||||
|
getDirectoryFiles,
|
||||||
|
getDirectoryFolders,
|
||||||
|
getDirectoryContents,
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/**
|
||||||
|
* XShell Tools Module ...
|
||||||
|
* a module for handling shell actions and retrieve OS Info in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Imports ...
|
||||||
|
const os = require('os');
|
||||||
|
const process = require('process');
|
||||||
|
const { exec } = require("child_process");
|
||||||
|
const XFileTools = require('./x-file.tools');
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
//
|
||||||
|
const OS = {
|
||||||
|
Aix: 'aix',
|
||||||
|
Darwin: 'darwin',
|
||||||
|
FreeBSD: 'freebsd',
|
||||||
|
Linux: 'linux',
|
||||||
|
OpenBSD: 'openbsd',
|
||||||
|
SnOS: 'sunos',
|
||||||
|
Windows: 'win32'
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
const isWindows = process.platform === OS.Windows;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
//
|
||||||
|
//#region Pure shell commands ...
|
||||||
|
/**
|
||||||
|
* execute a command using NodeJS on shell ...
|
||||||
|
*
|
||||||
|
* @param {string} cmd command to execute ...
|
||||||
|
* @param {string} cwd working directory ...
|
||||||
|
*
|
||||||
|
* @returns Promise<any, errr> instance ...
|
||||||
|
*/
|
||||||
|
function execute(cmd, cwd) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
//
|
||||||
|
if (!cmd || cmd.toString().length === 0 || (cwd && !XFileTools.isDirectoryExists(cwd))) {
|
||||||
|
reject('invalid args ...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
exec(cmd, { cwd }, (err, result, stdError) => {
|
||||||
|
//
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (stdError) {
|
||||||
|
//
|
||||||
|
// reject(stdError);
|
||||||
|
// return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines a command exists on host or not ...
|
||||||
|
*
|
||||||
|
* @param {string} name specific command name ...
|
||||||
|
*
|
||||||
|
* @returns boolean Promise ...
|
||||||
|
*/
|
||||||
|
function checkCommandExists(name) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
//
|
||||||
|
if (!name) {
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
const cmd = isWindows ? `${name} >nul 2>&1` : `type ${name} >/dev/null 2>&1`;
|
||||||
|
execute(cmd).then(result => {
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
resolve(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region required commands state ...
|
||||||
|
/**
|
||||||
|
* check al required commands exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function isRequiredCommandsExists() {
|
||||||
|
//
|
||||||
|
let result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// const isTarExists = await isTarCommandExists();
|
||||||
|
// const isCatExists = await isCatCommandExists();
|
||||||
|
// const isGrepExists = await isGrepCommandExists();
|
||||||
|
// const isSedExists = await isSedCommandExists();
|
||||||
|
const isNpmExists = await isNpmCommandExists();
|
||||||
|
const isNgExists = await isNgCommandExists();
|
||||||
|
const isIonicExists = await isIonicCommandExists();
|
||||||
|
const isCordovaExists = await isCordovaCommandExists();
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isNpmExists
|
||||||
|
&& isNgExists
|
||||||
|
&& isIonicExists
|
||||||
|
&& isCordovaExists
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve required commands state object ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async function getRequiredCommandsStates() {
|
||||||
|
//
|
||||||
|
const result = {};
|
||||||
|
|
||||||
|
//
|
||||||
|
// const isTarExists = await isTarCommandExists();
|
||||||
|
// const isCatExists = await isCatCommandExists();
|
||||||
|
// const isGrepExists = await isGrepCommandExists();
|
||||||
|
// const isSedExists = await isSedCommandExists();
|
||||||
|
const isNpmExists = await isNpmCommandExists();
|
||||||
|
const isNgExists = await isNgCommandExists();
|
||||||
|
const isIonicExists = await isIonicCommandExists();
|
||||||
|
const isCordovaExists = await isCordovaCommandExists();
|
||||||
|
|
||||||
|
//
|
||||||
|
result['npm'] = isNpmExists;
|
||||||
|
result['ng'] = isNgExists;
|
||||||
|
result['ionic'] = isIonicExists;
|
||||||
|
result['cordova'] = isCordovaExists;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Commonly used Command Checkers ...
|
||||||
|
/**
|
||||||
|
* determines npm command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNpmCommandExists() {
|
||||||
|
return checkCommandExists('npm');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines ng command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNgCommandExists() {
|
||||||
|
return checkCommandExists('ng');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines ionic command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isIonicCommandExists() {
|
||||||
|
return checkCommandExists('ionic');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines cordova command exists or not ...
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isCordovaCommandExists() {
|
||||||
|
return checkCommandExists('cordova');
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
execute,
|
||||||
|
checkCommandExists,
|
||||||
|
isRequiredCommandsExists,
|
||||||
|
getRequiredCommandsStates,
|
||||||
|
|
||||||
|
//
|
||||||
|
isNgCommandExists,
|
||||||
|
isIonicCommandExists,
|
||||||
|
isCordovaCommandExists,
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
/**
|
||||||
|
* DataType Tools Module ...
|
||||||
|
* a module for manipulate and detect supported data types in node js ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (hadi_khazaee_asl@yahoo.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Constants ...
|
||||||
|
/**
|
||||||
|
* all supported data types ...
|
||||||
|
*/
|
||||||
|
const DataTypes = {
|
||||||
|
Null: 'null',
|
||||||
|
Date: 'date',
|
||||||
|
Array: 'array',
|
||||||
|
Object: 'object',
|
||||||
|
String: 'string',
|
||||||
|
Number: 'number',
|
||||||
|
Unknown: 'unknown',
|
||||||
|
Boolean: 'boolean',
|
||||||
|
Function: 'function',
|
||||||
|
Undefined: 'undefined',
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Actions ...
|
||||||
|
/**
|
||||||
|
* detect type of a content ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getType(value) {
|
||||||
|
//
|
||||||
|
const type = typeof value;
|
||||||
|
|
||||||
|
//
|
||||||
|
let result = DataTypes.Unknown;
|
||||||
|
let dateIdentifier = '[object Date]';
|
||||||
|
let constructor = value && value.constructor ?
|
||||||
|
value.constructor.toString() :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
switch (type) {
|
||||||
|
//
|
||||||
|
case 'undefined':
|
||||||
|
result = DataTypes.Undefined;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'boolean':
|
||||||
|
result = DataTypes.Boolean;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'string':
|
||||||
|
result = DataTypes.String;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'number':
|
||||||
|
result = DataTypes.Number;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'function':
|
||||||
|
result = DataTypes.Function;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case 'object':
|
||||||
|
//
|
||||||
|
// Null ...
|
||||||
|
if (value === null) {
|
||||||
|
result = DataTypes.Null;
|
||||||
|
} else
|
||||||
|
//
|
||||||
|
// Array ...
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
result = DataTypes.Array;
|
||||||
|
} else
|
||||||
|
//
|
||||||
|
// Data ...
|
||||||
|
if (
|
||||||
|
value instanceof Date ||
|
||||||
|
isFunction(value.getMonth) ||
|
||||||
|
constructor.includes(dateIdentifier) ||
|
||||||
|
Object.prototype.toString.call(value) === dateIdentifier
|
||||||
|
) {
|
||||||
|
result = DataTypes.Date;
|
||||||
|
} else
|
||||||
|
//
|
||||||
|
// Object ...
|
||||||
|
{
|
||||||
|
result = DataTypes.Object;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
default:
|
||||||
|
result = DataTypes.Unknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve an object constructor ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getConstructor(value) {
|
||||||
|
//
|
||||||
|
const result = value && value.constructor ?
|
||||||
|
value.constructor.toString() :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieve an object prototype ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getPrototype(value) {
|
||||||
|
//
|
||||||
|
const result = value ?
|
||||||
|
Object.prototype.toString.call(value) :
|
||||||
|
'';
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is null or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNull(value) {
|
||||||
|
return getType(value) === DataTypes.Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is undefined or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isUndefined(value) {
|
||||||
|
return getType(value) === DataTypes.Undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is null or undefined or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNullOrUndefined(value) {
|
||||||
|
return isNull(value) || isUndefined(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is a date or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isDate(value) {
|
||||||
|
return getType(value) === DataTypes.Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is number or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isNumber(value) {
|
||||||
|
return getType(value) === DataTypes.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is string or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isString(value) {
|
||||||
|
return getType(value) === DataTypes.String;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is boolean or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isBoolean(value) {
|
||||||
|
return getType(value) === DataTypes.Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is an Array or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isArray(value) {
|
||||||
|
return getType(value) === DataTypes.Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is and Object or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isObject(value) {
|
||||||
|
return getType(value) === DataTypes.Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check an object is a Function or not ...
|
||||||
|
*
|
||||||
|
* @param {any} value the content which going to check ...
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function isFunction(value) {
|
||||||
|
return getType(value) === DataTypes.Function;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//
|
||||||
|
//#region Module Exports ...
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
DataTypes,
|
||||||
|
|
||||||
|
//
|
||||||
|
getType,
|
||||||
|
getConstructor,
|
||||||
|
getPrototype,
|
||||||
|
isNull,
|
||||||
|
isUndefined,
|
||||||
|
isNullOrUndefined,
|
||||||
|
isDate,
|
||||||
|
isNumber,
|
||||||
|
isString,
|
||||||
|
isBoolean,
|
||||||
|
isArray,
|
||||||
|
isObject,
|
||||||
|
isFunction,
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,221 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// Detect Signals Based On XPV Indicator Golden Zones ...
|
||||||
|
//
|
||||||
|
bool HasTMPConditions(
|
||||||
|
ENUM_X_CYCLES cycle,
|
||||||
|
XBoxZone &box,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
X121SMCStrategySignalProviderData &provider,
|
||||||
|
int barIndex = 0 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.Clean();
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fil Selected Data ...
|
||||||
|
XPOIState cState;
|
||||||
|
X121Conditions cXConditions;
|
||||||
|
XPOIStateEvents cStateEvents;
|
||||||
|
XC121SMCCycleHelper *cHelper;
|
||||||
|
X121SMCCycleConditions cConditions;
|
||||||
|
result = provider.SelectCycle(
|
||||||
|
cycle,
|
||||||
|
cState,
|
||||||
|
cStateEvents,
|
||||||
|
cXConditions,
|
||||||
|
cHelper,
|
||||||
|
cConditions //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
cStateEvents.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Args ...
|
||||||
|
|
||||||
|
//
|
||||||
|
if (barIndex < 0)
|
||||||
|
{
|
||||||
|
barIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIDX = barIndex;
|
||||||
|
int cIDX = zIDX + 1;
|
||||||
|
int pIDX = cIDX + 1;
|
||||||
|
int ppIDX = pIDX + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = false;
|
||||||
|
bool isBearish = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
XOHCL cBar;
|
||||||
|
XOHCL pBar;
|
||||||
|
XOHCL pPBar;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial Bars ...
|
||||||
|
result = zBar.Init(
|
||||||
|
cState.symbol,
|
||||||
|
cState.period,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
zBar.GetPreviousBar(cBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
cBar.GetPreviousBar(pBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
pBar.GetPreviousBar(pPBar);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
cState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Summarize Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
isBullish =
|
||||||
|
//
|
||||||
|
false
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
isBearish =
|
||||||
|
//
|
||||||
|
false
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filling Requirements ...
|
||||||
|
result =
|
||||||
|
isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.dir = dir;
|
||||||
|
box.from = pPBar.time;
|
||||||
|
box.to = TimeCurrent();
|
||||||
|
box.symbol = cBar.symbol;
|
||||||
|
box.period = cBar.period;
|
||||||
|
|
||||||
|
//
|
||||||
|
double points = GetPoints(box.symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Usually is Preffered SL ...
|
||||||
|
double pivot = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Usually is Current Price or Entry Price ...
|
||||||
|
double point = GetEntry(
|
||||||
|
cBar.symbol,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
box.upper =
|
||||||
|
isBullish
|
||||||
|
? point
|
||||||
|
: pivot;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.lower =
|
||||||
|
isBullish
|
||||||
|
? pivot
|
||||||
|
: point;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer;
|
||||||
|
bool drawBoxes = true;
|
||||||
|
if (drawBoxes)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (box.IsValid()) {
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
bool isCreated = drawer.DrawBox(
|
||||||
|
box,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isCreated) {
|
||||||
|
//
|
||||||
|
// TODO: ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check All Conditions ...
|
||||||
|
result =
|
||||||
|
box.IsValid() &&
|
||||||
|
HasDirection(dir) &&
|
||||||
|
(isBullish ||
|
||||||
|
isBearish);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
pPBar.Clean();
|
||||||
|
cState.Clean();
|
||||||
|
cConditions.Clean();
|
||||||
|
cConditions.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cStateEvents.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
bool DetectPivot(
|
||||||
|
int barIndex,
|
||||||
|
XOHCL &zBar,
|
||||||
|
XOHCL &cBar,
|
||||||
|
XOHCL &pBar,
|
||||||
|
XOHCL &p2Bar,
|
||||||
|
XCAEAConditions &conditions //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Args ...
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
barIndex >= 0 &&
|
||||||
|
zBar.IsValid() &&
|
||||||
|
cBar.IsValid() &&
|
||||||
|
pBar.IsValid() &&
|
||||||
|
p2Bar.IsValid() &&
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Requirements ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIDX = 0;
|
||||||
|
int cIDX = zIDX + 1;
|
||||||
|
int pIDX = cIDX + 1;
|
||||||
|
int p2IDX = pIDX + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCAPviot pivot;
|
||||||
|
datetime cTime = zBar.time;
|
||||||
|
string symbol = zBar.symbol;
|
||||||
|
string period = zBar.period;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reading Conditional Values ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Conditinal Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool hasStartCondition = false;
|
||||||
|
bool hasContinuationCondition = false;
|
||||||
|
bool hasEndCondition = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ReInstance Pivot ...
|
||||||
|
if (hasStartConditions)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate and Fill Pivot Requirements ...
|
||||||
|
if (hasContinuationCondition)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// End up Pivot and Store it ...
|
||||||
|
if (hasEndCondition)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
pivot.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,542 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center XTest MQL5 Expert Advisor
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XEATemplate
|
||||||
|
// Description: a Template For Exper Advisors
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////x
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm XEATemplate"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "XEATemplate"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.xalert.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||||
|
#include "../Helpers/x-saherelm.xcc.helper.mq5"
|
||||||
|
#include "../Helpers/x-saherelm.xct.helper.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
input group "Common";
|
||||||
|
input long eaMagicNumber = 78692110; // Magic Number
|
||||||
|
input int eaSlippage = 10; // Slippgae
|
||||||
|
input string eaLogSuffix = ""; // Log Suffix
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert ...
|
||||||
|
// Here we Provider All Requirements for
|
||||||
|
// Configuring Alert Provider ...
|
||||||
|
input group "Alert";
|
||||||
|
input bool eAEnableAlerts = true; // Enable Alerts
|
||||||
|
input bool eALogAlerts = true; // Log Alerts
|
||||||
|
input bool eAMailAlerts = false; // Mail Alerts
|
||||||
|
input bool eAPushAlerts = false; // Push Alerts
|
||||||
|
input bool eATerminalAlerts = false; // Terminal Alerts
|
||||||
|
|
||||||
|
//
|
||||||
|
// Time Report ...
|
||||||
|
input group "Reports";
|
||||||
|
input bool eaReportNewMonths = false; // Report New Month
|
||||||
|
input bool eaReportNewWeeks = false; // Report New Weeks
|
||||||
|
input bool eaReportNewDays = false; // Report New Days
|
||||||
|
input bool eaReportNewHours = false; // Report New Hours
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Local Variables ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string eaLogTag; // EA Log Prefix ...
|
||||||
|
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
||||||
|
XSCTrade *eaTrader; // Trader of Expert Adviser ...
|
||||||
|
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
|
||||||
|
XSCXCTHelper *eaCHelper; // Bar Timer Indicator Helper class ...
|
||||||
|
XSCXCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization ...
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs and Required Parameters
|
||||||
|
// for EA to Works fine ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Timer ...
|
||||||
|
if (!InitTimer()) {
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize all Requirements ...
|
||||||
|
if (!InitEA())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize all GUI Objects and Classes ...
|
||||||
|
if (!InitGUI())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert Initialization ...
|
||||||
|
string msg = "Initialized Successfully ...";
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DeInitialization ...
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy Timer ...
|
||||||
|
DestroyTimer();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy all GUI Requirements ...
|
||||||
|
DestroyGUI();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert De Initialization Succeeded ...
|
||||||
|
string msg = "De Initialized Successfully ...";
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy all EA Requirements ...
|
||||||
|
DestroyEA();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Tick Handler ...
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
UpdateGUI();
|
||||||
|
HandleReportTime();
|
||||||
|
UpdatePositionsState();
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implemetn Tick Processors Algorithm ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle On Trade Event ...
|
||||||
|
void OnTrade()
|
||||||
|
{
|
||||||
|
eaTrader.HandleOnTrade();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Timer ...
|
||||||
|
void OnTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement Time Based Functionalities ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chart Event Handler ...
|
||||||
|
void OnChartEvent(
|
||||||
|
const int id,
|
||||||
|
const long &lparam,
|
||||||
|
const double &dparam,
|
||||||
|
const string &sparam //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Handle OnClick Event ...
|
||||||
|
if (id == CHARTEVENT_OBJECT_CLICK)
|
||||||
|
{
|
||||||
|
HandleOnClickEvent(sparam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle StopLoss Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal ...
|
||||||
|
*/
|
||||||
|
void OnStopLossTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Take Profit Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal ...
|
||||||
|
*/
|
||||||
|
void OnTakeProfitTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Force Close a Position ...
|
||||||
|
*
|
||||||
|
* @param ticket: Position Ticket ...
|
||||||
|
* @param position: XPosition ...
|
||||||
|
* @param comment: Closing Comment ...
|
||||||
|
*/
|
||||||
|
void OnPositionForceClosed(
|
||||||
|
const ulong ticket,
|
||||||
|
const XPosition &position,
|
||||||
|
const string comment //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate all Inputs of Expert Adviser ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
string errMessage = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCommonValid = (
|
||||||
|
//
|
||||||
|
eaSlippage > 0 &&
|
||||||
|
eaMagicNumber > 0
|
||||||
|
//
|
||||||
|
);
|
||||||
|
if (!isCommonValid)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
errMessage += "common configurations error;" + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
isCommonValid &&
|
||||||
|
//
|
||||||
|
// Otere ...
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
||||||
|
Print(ShortName + " Errors: \n", errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Timer ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitTimer() {
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Initialize Timer if necessary ...
|
||||||
|
// result = EventSetTimer(1);
|
||||||
|
// result = EventSetMillisecondTimer(100);
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy Timer ...
|
||||||
|
*/
|
||||||
|
void DestroyTimer() {
|
||||||
|
//
|
||||||
|
// TODO: Use This ...
|
||||||
|
// EventKillTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all Requirements for Working Fine ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locally Apply Changes on Prefix ...
|
||||||
|
eaLogTag = ShortName + ">" + eaLogSuffix;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bar Timer ...
|
||||||
|
XCTInputs ctInputs;
|
||||||
|
ctInputs.Default(); // Default Configurations ...
|
||||||
|
eaCHelper = new XSCXCTHelper();
|
||||||
|
result = eaCHelper.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
ctInputs //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bar Styles ...
|
||||||
|
XCCInputs ccInputs;
|
||||||
|
ccInputs.Default(); // Default Configurations ...
|
||||||
|
eaCCHelper = new XSCXCCHelper();
|
||||||
|
result = eaCCHelper.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
ccInputs //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Instance of Alert Class and Configure it ...
|
||||||
|
eaAlert = new XSCAlert();
|
||||||
|
eaAlert.SetPrefix(eaLogTag);
|
||||||
|
eaAlert.SetLogAlerts(eALogAlerts);
|
||||||
|
eaAlert.SetMailAlerts(eAMailAlerts);
|
||||||
|
eaAlert.SetPushAlerts(eAPushAlerts);
|
||||||
|
eaAlert.SetEnableAlerts(eAEnableAlerts);
|
||||||
|
eaAlert.SetTerminalAlerts(eATerminalAlerts);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Trader Instance and Configure it ...
|
||||||
|
eaTrader = new XSCTrade(
|
||||||
|
eaSlippage,
|
||||||
|
eaMagicNumber //
|
||||||
|
);
|
||||||
|
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
|
||||||
|
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
||||||
|
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all Initialized EA Requirements ...
|
||||||
|
*/
|
||||||
|
void DestroyEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
delete eaCHelper;
|
||||||
|
delete eaCCHelper;
|
||||||
|
|
||||||
|
//
|
||||||
|
delete eaAlert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all GUI Requirements for EA ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Fix This ...
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update GUI based on Each Ticks ...
|
||||||
|
*/
|
||||||
|
void UpdateGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement this ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all Initialized GUi Requirements ...
|
||||||
|
*/
|
||||||
|
void DestroyGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Complete this ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Others ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Positions States ...
|
||||||
|
*/
|
||||||
|
void UpdatePositionsState()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement this ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle On Click Event for GUI Components ...
|
||||||
|
*
|
||||||
|
* @param name: Object Name ...
|
||||||
|
*/
|
||||||
|
void HandleOnClickEvent(string name)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!IsValid(name))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isClicked = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implement Chart Objects On Click ...
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isClicked)
|
||||||
|
{
|
||||||
|
UpdateGUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report Account Balance ...
|
||||||
|
*/
|
||||||
|
void HandleReportBalance()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!IsRunningOnTestMode())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
|
||||||
|
eaAlert.Log(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time Reporting based on Inputs ...
|
||||||
|
*/
|
||||||
|
void HandleReportTime()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Monthly Report ....
|
||||||
|
if (eaReportNewMonths &&
|
||||||
|
eaTimeTracker.IsNewMonth())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Month ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weekly Report ....
|
||||||
|
if (eaReportNewWeeks &&
|
||||||
|
eaTimeTracker.IsNewWeek())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Week ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Daily Report ....
|
||||||
|
if (eaReportNewDays &&
|
||||||
|
eaTimeTracker.IsNewDay())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Day ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hourly Report ....
|
||||||
|
if (eaReportNewHours &&
|
||||||
|
eaTimeTracker.IsNewHour())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Hour ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,575 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center XTest MQL5 Expert Advisor
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XPanelEA
|
||||||
|
// Description: an Exper Advisor which used Panels
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////x
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm XPanelEA"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "XPANELEA"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.x-app-dialog.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.xalert.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||||
|
#include "../Helpers/x-saherelm.xcc.helper.mq5"
|
||||||
|
#include "../Helpers/x-saherelm.xct.helper.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
input group "Common";
|
||||||
|
input long eaMagicNumber = 78692110; // Magic Number
|
||||||
|
input int eaSlippage = 10; // Slippgae
|
||||||
|
input string eaLogSuffix = ""; // Log Suffix
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert ...
|
||||||
|
// Here we Provider All Requirements for
|
||||||
|
// Configuring Alert Provider ...
|
||||||
|
input group "Alert";
|
||||||
|
input bool eAEnableAlerts = true; // Enable Alerts
|
||||||
|
input bool eALogAlerts = true; // Log Alerts
|
||||||
|
input bool eAMailAlerts = false; // Mail Alerts
|
||||||
|
input bool eAPushAlerts = false; // Push Alerts
|
||||||
|
input bool eATerminalAlerts = false; // Terminal Alerts
|
||||||
|
|
||||||
|
//
|
||||||
|
// Time Report ...
|
||||||
|
input group "Reports";
|
||||||
|
input bool eaReportNewMonths = false; // Report New Month
|
||||||
|
input bool eaReportNewWeeks = false; // Report New Weeks
|
||||||
|
input bool eaReportNewDays = false; // Report New Days
|
||||||
|
input bool eaReportNewHours = false; // Report New Hours
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Local Variables ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string eaLogTag; // EA Log Prefix ...
|
||||||
|
XSCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
||||||
|
XSCTrade *eaTrader; // Trader of Expert Adviser ...
|
||||||
|
XTimeTracker eaTimeTracker; // Time Tracker for Providing Reports ...
|
||||||
|
XSCXCTHelper *eaCTHelper; // Bar Timer Indicator Helper class ...
|
||||||
|
XSCXCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
|
||||||
|
|
||||||
|
//
|
||||||
|
XCAppDialog eaMainWindow; // EA Main Dialog ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization ...
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs and Required Parameters
|
||||||
|
// for EA to Works fine ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Timer ...
|
||||||
|
if (!InitTimer())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize all Requirements ...
|
||||||
|
if (!InitEA())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize all GUI Objects and Classes ...
|
||||||
|
if (!InitGUI())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert Initialization ...
|
||||||
|
string msg = "Initialized Successfully ...";
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DeInitialization ...
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy Timer ...
|
||||||
|
DestroyTimer();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy all GUI Requirements ...
|
||||||
|
DestroyGUI();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert De Initialization Succeeded ...
|
||||||
|
string msg = "De Initialized Successfully ...";
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy all EA Requirements ...
|
||||||
|
DestroyEA();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Tick Handler ...
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
UpdateGUI();
|
||||||
|
HandleReportTime();
|
||||||
|
UpdatePositionsState();
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implemetn Tick Processors Algorithm ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle On Trade Event ...
|
||||||
|
void OnTrade()
|
||||||
|
{
|
||||||
|
eaTrader.HandleOnTrade();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Timer ...
|
||||||
|
void OnTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement Time Based Functionalities ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chart Event Handler ...
|
||||||
|
void OnChartEvent(
|
||||||
|
const int id,
|
||||||
|
const long &lparam,
|
||||||
|
const double &dparam,
|
||||||
|
const string &sparam //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Apply Chart Event on Main Window ...
|
||||||
|
eaMainWindow.ChartEvent(id, lparam, dparam, sparam);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle OnClick Event ...
|
||||||
|
if (id == CHARTEVENT_OBJECT_CLICK)
|
||||||
|
{
|
||||||
|
HandleOnClickEvent(sparam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle StopLoss Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal ...
|
||||||
|
*/
|
||||||
|
void OnStopLossTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Take Profit Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal ...
|
||||||
|
*/
|
||||||
|
void OnTakeProfitTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Force Close a Position ...
|
||||||
|
*
|
||||||
|
* @param ticket: Position Ticket ...
|
||||||
|
* @param position: XPosition ...
|
||||||
|
* @param comment: Closing Comment ...
|
||||||
|
*/
|
||||||
|
void OnPositionForceClosed(
|
||||||
|
const ulong ticket,
|
||||||
|
const XPosition &position,
|
||||||
|
const string comment //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
HandleReportBalance();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate all Inputs of Expert Adviser ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
string errMessage = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCommonValid = (
|
||||||
|
//
|
||||||
|
eaSlippage > 0 &&
|
||||||
|
eaMagicNumber > 0
|
||||||
|
//
|
||||||
|
);
|
||||||
|
if (!isCommonValid)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
errMessage += "common configurations error;" + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
isCommonValid &&
|
||||||
|
//
|
||||||
|
// Otere ...
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
||||||
|
Print(ShortName + " Errors: \n", errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Timer ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Initialize Timer if necessary ...
|
||||||
|
// result = EventSetTimer(1);
|
||||||
|
// result = EventSetMillisecondTimer(100);
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy Timer ...
|
||||||
|
*/
|
||||||
|
void DestroyTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Use This ...
|
||||||
|
// EventKillTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all Requirements for Working Fine ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locally Apply Changes on Prefix ...
|
||||||
|
eaLogTag = ShortName + ">" + eaLogSuffix;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bar Timer ...
|
||||||
|
XCTInputs ctInputs;
|
||||||
|
ctInputs.Default(); // Default Configurations ...
|
||||||
|
eaCTHelper = new XSCXCTHelper();
|
||||||
|
result = eaCTHelper.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
ctInputs //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bar Styles ...
|
||||||
|
XCCInputs ccInputs;
|
||||||
|
ccInputs.Default(); // Default Configurations ...
|
||||||
|
eaCCHelper = new XSCXCCHelper();
|
||||||
|
result = eaCCHelper.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
ccInputs //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Instance of Alert Class and Configure it ...
|
||||||
|
eaAlert = new XSCAlert();
|
||||||
|
eaAlert.SetPrefix(eaLogTag);
|
||||||
|
eaAlert.SetLogAlerts(eALogAlerts);
|
||||||
|
eaAlert.SetMailAlerts(eAMailAlerts);
|
||||||
|
eaAlert.SetPushAlerts(eAPushAlerts);
|
||||||
|
eaAlert.SetEnableAlerts(eAEnableAlerts);
|
||||||
|
eaAlert.SetTerminalAlerts(eATerminalAlerts);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Trader Instance and Configure it ...
|
||||||
|
eaTrader = new XSCTrade(
|
||||||
|
eaSlippage,
|
||||||
|
eaMagicNumber //
|
||||||
|
);
|
||||||
|
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
|
||||||
|
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
||||||
|
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all Initialized EA Requirements ...
|
||||||
|
*/
|
||||||
|
void DestroyEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
delete eaCTHelper;
|
||||||
|
delete eaCCHelper;
|
||||||
|
|
||||||
|
//
|
||||||
|
delete eaAlert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all GUI Requirements for EA ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Application Main Window ...
|
||||||
|
result = eaMainWindow.Create(
|
||||||
|
ChartID(),
|
||||||
|
ShortName, // Dialog Name ...
|
||||||
|
0, // SubWindow ...
|
||||||
|
10, // X1 ...
|
||||||
|
35, // Y1 ...
|
||||||
|
300, // X2 ...
|
||||||
|
200 // Y2 ...
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configuring Dialog ...
|
||||||
|
// eaMainWindow.MinimizeButton(false); // Hide Minimize Button ...
|
||||||
|
// eaMainWindow.CloseButton(false); // Hide Close Button ...
|
||||||
|
eaMainWindow.BackgroundColor(clrBlack);
|
||||||
|
// result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try To Run Main Window ...
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
eaMainWindow.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update GUI based on Each Ticks ...
|
||||||
|
*/
|
||||||
|
void UpdateGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement this ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all Initialized GUi Requirements ...
|
||||||
|
*/
|
||||||
|
void DestroyGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaMainWindow.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Others ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Positions States ...
|
||||||
|
*/
|
||||||
|
void UpdatePositionsState()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement this ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle On Click Event for GUI Components ...
|
||||||
|
*
|
||||||
|
* @param name: Object Name ...
|
||||||
|
*/
|
||||||
|
void HandleOnClickEvent(string name)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!IsValid(name))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isClicked = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implement Chart Objects On Click ...
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isClicked)
|
||||||
|
{
|
||||||
|
UpdateGUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report Account Balance ...
|
||||||
|
*/
|
||||||
|
void HandleReportBalance()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!IsRunningOnTestMode())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance());
|
||||||
|
eaAlert.Log(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time Reporting based on Inputs ...
|
||||||
|
*/
|
||||||
|
void HandleReportTime()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Monthly Report ....
|
||||||
|
if (eaReportNewMonths &&
|
||||||
|
eaTimeTracker.IsNewMonth())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Month ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weekly Report ....
|
||||||
|
if (eaReportNewWeeks &&
|
||||||
|
eaTimeTracker.IsNewWeek())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Week ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Daily Report ....
|
||||||
|
if (eaReportNewDays &&
|
||||||
|
eaTimeTracker.IsNewDay())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Day ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hourly Report ....
|
||||||
|
if (eaReportNewHours &&
|
||||||
|
eaTimeTracker.IsNewHour())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Hour ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// Senario 3:
|
||||||
|
// ----------
|
||||||
|
bool useSenario3 = false;
|
||||||
|
bool isSenario3Happend = false;
|
||||||
|
bool isSenario3Bullish = false;
|
||||||
|
bool isSenario3Bearish = false;
|
||||||
|
if (useSenario3)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Senario 3 Bullish Conditions ...
|
||||||
|
isSenario3Bullish = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Senario 3 Bearish Conditions ...
|
||||||
|
isSenario3Bearish = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filling Requirements using Senario 3 ...
|
||||||
|
isSenario3Happend =
|
||||||
|
isSenario3Bullish ||
|
||||||
|
isSenario3Bearish;
|
||||||
|
if (isSenario3Happend)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isSenario3Bullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.dir = dir;
|
||||||
|
box.to = TimeCurrent();
|
||||||
|
box.symbol = provider
|
||||||
|
.decisionXConditions
|
||||||
|
.symbol;
|
||||||
|
box.period = provider
|
||||||
|
.decisionXConditions
|
||||||
|
.period;
|
||||||
|
|
||||||
|
//
|
||||||
|
int fromIDX = -1;
|
||||||
|
if (isSenario3Bullish)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double vale = provider
|
||||||
|
.decisionXConditions
|
||||||
|
.valesBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
box.lower = vale;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.upper = provider
|
||||||
|
.decisionXConditions
|
||||||
|
.valesGoldenBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
int lowerValeIDX = -1;
|
||||||
|
double lowerVale = provider
|
||||||
|
.decisionCycleHelper
|
||||||
|
.mX121Helper
|
||||||
|
.xpvHelper
|
||||||
|
.GetLowerVale(
|
||||||
|
lowerValeIDX,
|
||||||
|
vale,
|
||||||
|
cBar.Index() //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
int higherValeIDX = -1;
|
||||||
|
double higherVale = provider
|
||||||
|
.decisionCycleHelper
|
||||||
|
.mX121Helper
|
||||||
|
.xpvHelper
|
||||||
|
.GetHigherVale(
|
||||||
|
higherValeIDX,
|
||||||
|
vale,
|
||||||
|
cBar.Index() //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (IsValidIndex(lowerValeIDX) &&
|
||||||
|
IsValidIndex(higherValeIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX =
|
||||||
|
lowerValeIDX < higherValeIDX
|
||||||
|
? lowerValeIDX
|
||||||
|
: higherValeIDX;
|
||||||
|
}
|
||||||
|
else if (IsValidIndex(lowerValeIDX) &&
|
||||||
|
!IsValidIndex(higherValeIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX = lowerValeIDX;
|
||||||
|
}
|
||||||
|
else if (!IsValidIndex(lowerValeIDX) &&
|
||||||
|
IsValidIndex(higherValeIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX = higherValeIDX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double peak = provider
|
||||||
|
.decisionXConditions
|
||||||
|
.peaksBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
box.upper = peak;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.lower = provider
|
||||||
|
.decisionXConditions
|
||||||
|
.peaksGoldenBuffer[cIDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
int lowerPeakIDX = -1;
|
||||||
|
double lowerPeak = provider
|
||||||
|
.decisionCycleHelper
|
||||||
|
.mX121Helper
|
||||||
|
.xpvHelper
|
||||||
|
.GetLowerPeak(
|
||||||
|
lowerPeakIDX,
|
||||||
|
peak,
|
||||||
|
cBar.Index() //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
int higherPeakIDX = -1;
|
||||||
|
double higherPeak = provider
|
||||||
|
.decisionCycleHelper
|
||||||
|
.mX121Helper
|
||||||
|
.xpvHelper
|
||||||
|
.GetHigherPeak(
|
||||||
|
higherPeakIDX,
|
||||||
|
peak,
|
||||||
|
cBar.Index() //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (IsValidIndex(lowerPeakIDX) &&
|
||||||
|
IsValidIndex(higherPeakIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX =
|
||||||
|
lowerPeakIDX < higherPeakIDX
|
||||||
|
? lowerPeakIDX
|
||||||
|
: higherPeakIDX;
|
||||||
|
}
|
||||||
|
else if (IsValidIndex(lowerPeakIDX) &&
|
||||||
|
!IsValidIndex(higherPeakIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX = lowerPeakIDX;
|
||||||
|
}
|
||||||
|
else if (!IsValidIndex(lowerPeakIDX) &&
|
||||||
|
IsValidIndex(higherPeakIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX = higherPeakIDX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (IsValidIndex(fromIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
box.from = iTime(
|
||||||
|
zBar.symbol,
|
||||||
|
zBar.period,
|
||||||
|
fromIDX //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
box.from = pBar.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
signalProvider = X121SMC_XWZ_PROVIDER_ACTIVATED_BOX;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,816 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| X121_Strategy_EA.mq5 |
|
||||||
|
//| Copyright 2023, SaherElm IT |
|
||||||
|
//| https://saherelm.ir/ |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "EA based on X121 XCA and X3MA indicators"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
// Include Common Library
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
#include <Trade/Trade.mqh>
|
||||||
|
|
||||||
|
// Indicator handles
|
||||||
|
int xcaHandle = INVALID_HANDLE;
|
||||||
|
int x3maHandle = INVALID_HANDLE;
|
||||||
|
|
||||||
|
// Indicator buffers for XCA
|
||||||
|
double xcaTrendBuffer[];
|
||||||
|
double xcaTrendColorBuffer[];
|
||||||
|
double xcaKIBuffer[];
|
||||||
|
double xcaKIColorBuffer[];
|
||||||
|
double xcaVidyaBuffer[];
|
||||||
|
double xcaVidyaColorBuffer[];
|
||||||
|
double xcaSwingLowBuffer[];
|
||||||
|
double xcaSwingHighBuffer[];
|
||||||
|
double xcaSupportBuffer[];
|
||||||
|
double xcaResistanceBuffer[];
|
||||||
|
double xcaSLBuffer[]; // Short Cycle Low
|
||||||
|
double xcaSHBuffer[]; // Short Cycle High
|
||||||
|
double xcaMLBuffer[]; // Medium Cycle Low
|
||||||
|
double xcaMHBuffer[]; // Medium Cycle High
|
||||||
|
double xcaFiboLevel2Buffer[]; // 50% Fibo level
|
||||||
|
|
||||||
|
// Indicator buffers for X3MA
|
||||||
|
double x3maFastBuffer[];
|
||||||
|
double x3maFastColorBuffer[];
|
||||||
|
double x3maMediumBuffer[];
|
||||||
|
double x3maMediumColorBuffer[];
|
||||||
|
double x3maSlowBuffer[];
|
||||||
|
double x3maSlowColorBuffer[];
|
||||||
|
|
||||||
|
// Trade parameters
|
||||||
|
input group "Trade Settings" input double LotSize = 0.1; // Fixed Lot Size
|
||||||
|
input bool UseAutoLotSize = false; // Use Auto Lot Size
|
||||||
|
input double RiskPercent = 1.0; // Risk Percent (for Auto Lot)
|
||||||
|
input int StopLoss = 100; // Stop Loss in points
|
||||||
|
input int TakeProfit = 200; // Take Profit in points
|
||||||
|
input bool UseTrailingStop = true; // Use Trailing Stop
|
||||||
|
input int TrailingStop = 50; // Trailing Stop in points
|
||||||
|
input int TrailingStep = 10; // Trailing Step in points
|
||||||
|
|
||||||
|
input group "Strategy Parameters" input bool UseSwingPoints = true; // Use Swing Points for Entry
|
||||||
|
input bool UseFiboLevels = true; // Use Fibonacci Levels
|
||||||
|
input bool UseMAAlignment = true; // Require All MAs Alignment
|
||||||
|
input bool UseKIConfirmation = true; // Require KI Confirmation
|
||||||
|
input bool UseVidyaConfirmation = true; // Require VIDYA Confirmation
|
||||||
|
input bool UseTrendConfirmation = true; // Require Trend Confirmation
|
||||||
|
|
||||||
|
input group "Money Management" input bool UseMultipleTargets = true; // Use Multiple Profit Targets
|
||||||
|
input double Target1Percent = 33.0; // First Target Percentage
|
||||||
|
input double Target2Percent = 33.0; // Second Target Percentage
|
||||||
|
input double Target3Percent = 34.0; // Third Target Percentage
|
||||||
|
|
||||||
|
input group "Time Filter" input bool UseTimeFilter = false; // Use Time Filter
|
||||||
|
input string StartTradeTime = "08:00"; // Start Trading Time (Server Time)
|
||||||
|
input string EndTradeTime = "16:00"; // End Trading Time (Server Time)
|
||||||
|
|
||||||
|
// Global variables
|
||||||
|
int magicNumber = 12121;
|
||||||
|
bool isTradingAllowed = true;
|
||||||
|
datetime lastBarTime = 0;
|
||||||
|
int barsTotalPrev = 0;
|
||||||
|
|
||||||
|
// Trade objects
|
||||||
|
CTrade trade;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
// Initialize trade object
|
||||||
|
trade.SetExpertMagicNumber(magicNumber);
|
||||||
|
|
||||||
|
// Initialize XCA indicator
|
||||||
|
xcaHandle = iCustom(_Symbol, _Period, "x-saherelm.x121.xca");
|
||||||
|
if (xcaHandle == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
Print("Failed to create handle of the XCA indicator");
|
||||||
|
return (INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize X3MA indicator
|
||||||
|
x3maHandle = iCustom(_Symbol, _Period, "x-saherelm.x121.x3ma");
|
||||||
|
if (x3maHandle == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
Print("Failed to create handle of the X3MA indicator");
|
||||||
|
return (INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up arrays as series
|
||||||
|
ArraySetAsSeries(xcaTrendBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaTrendColorBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaKIBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaKIColorBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaVidyaBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaVidyaColorBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaSwingLowBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaSwingHighBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaSupportBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaResistanceBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaSLBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaSHBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaMLBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaMHBuffer, true);
|
||||||
|
ArraySetAsSeries(xcaFiboLevel2Buffer, true);
|
||||||
|
|
||||||
|
ArraySetAsSeries(x3maFastBuffer, true);
|
||||||
|
ArraySetAsSeries(x3maFastColorBuffer, true);
|
||||||
|
ArraySetAsSeries(x3maMediumBuffer, true);
|
||||||
|
ArraySetAsSeries(x3maMediumColorBuffer, true);
|
||||||
|
ArraySetAsSeries(x3maSlowBuffer, true);
|
||||||
|
ArraySetAsSeries(x3maSlowColorBuffer, true);
|
||||||
|
|
||||||
|
return (INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
// Release indicator handles
|
||||||
|
if (xcaHandle != INVALID_HANDLE)
|
||||||
|
IndicatorRelease(xcaHandle);
|
||||||
|
|
||||||
|
if (x3maHandle != INVALID_HANDLE)
|
||||||
|
IndicatorRelease(x3maHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
// Check if we're allowed to trade based on time filter
|
||||||
|
if (UseTimeFilter && !IsTradeTimeAllowed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get current bar time
|
||||||
|
datetime currentBarTime = iTime(_Symbol, _Period, 0);
|
||||||
|
|
||||||
|
// Only process on new bar
|
||||||
|
if (currentBarTime == lastBarTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastBarTime = currentBarTime;
|
||||||
|
|
||||||
|
// Update indicator buffers
|
||||||
|
if (!UpdateIndicatorBuffers())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check for open positions and manage them
|
||||||
|
ManageOpenPositions();
|
||||||
|
|
||||||
|
// Check for new trade signals
|
||||||
|
CheckForTradeSignals();
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Update all indicator buffers |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool UpdateIndicatorBuffers()
|
||||||
|
{
|
||||||
|
// Copy XCA indicator buffers
|
||||||
|
if (CopyBuffer(xcaHandle, 18, 0, 3, xcaTrendBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 19, 0, 3, xcaTrendColorBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 20, 0, 3, xcaKIBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 21, 0, 3, xcaKIColorBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 26, 0, 3, xcaVidyaBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 27, 0, 3, xcaVidyaColorBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 22, 0, 3, xcaSwingLowBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 23, 0, 3, xcaSwingHighBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 8, 0, 3, xcaSupportBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 9, 0, 3, xcaResistanceBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 0, 0, 3, xcaSHBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 1, 0, 3, xcaSLBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 2, 0, 3, xcaMHBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 3, 0, 3, xcaMLBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(xcaHandle, 15, 0, 3, xcaFiboLevel2Buffer) < 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Copy X3MA indicator buffers
|
||||||
|
if (CopyBuffer(x3maHandle, 0, 0, 3, x3maFastBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(x3maHandle, 1, 0, 3, x3maFastColorBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(x3maHandle, 2, 0, 3, x3maMediumBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(x3maHandle, 3, 0, 3, x3maMediumColorBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(x3maHandle, 4, 0, 3, x3maSlowBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
if (CopyBuffer(x3maHandle, 5, 0, 3, x3maSlowColorBuffer) < 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check if current time is within allowed trading hours |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool IsTradeTimeAllowed()
|
||||||
|
{
|
||||||
|
// If time filter is not enabled, always allow trading
|
||||||
|
if (!UseTimeFilter)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Get current server time
|
||||||
|
datetime serverTime = TimeCurrent();
|
||||||
|
MqlDateTime currentTime;
|
||||||
|
TimeToStruct(serverTime, currentTime);
|
||||||
|
|
||||||
|
// Convert start and end time strings to hours and minutes
|
||||||
|
int startHour = 0, startMinute = 0;
|
||||||
|
int endHour = 0, endMinute = 0;
|
||||||
|
|
||||||
|
// Parse start time
|
||||||
|
string startTimeParts[];
|
||||||
|
if (StringSplit(StartTradeTime, ':', startTimeParts) == 2)
|
||||||
|
{
|
||||||
|
startHour = (int)StringToInteger(startTimeParts[0]);
|
||||||
|
startMinute = (int)StringToInteger(startTimeParts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse end time
|
||||||
|
string endTimeParts[];
|
||||||
|
if (StringSplit(EndTradeTime, ':', endTimeParts) == 2)
|
||||||
|
{
|
||||||
|
endHour = (int)StringToInteger(endTimeParts[0]);
|
||||||
|
endMinute = (int)StringToInteger(endTimeParts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert current time, start time and end time to minutes for easy comparison
|
||||||
|
int currentTimeInMinutes = currentTime.hour * 60 + currentTime.min;
|
||||||
|
int startTimeInMinutes = startHour * 60 + startMinute;
|
||||||
|
int endTimeInMinutes = endHour * 60 + endMinute;
|
||||||
|
|
||||||
|
// Check if current time is within trading hours
|
||||||
|
bool isAllowed = false;
|
||||||
|
|
||||||
|
// If end time is greater than start time (same day trading session)
|
||||||
|
if (endTimeInMinutes > startTimeInMinutes)
|
||||||
|
{
|
||||||
|
isAllowed = (currentTimeInMinutes >= startTimeInMinutes &&
|
||||||
|
currentTimeInMinutes <= endTimeInMinutes);
|
||||||
|
}
|
||||||
|
// If end time is less than start time (overnight trading session)
|
||||||
|
else if (endTimeInMinutes < startTimeInMinutes)
|
||||||
|
{
|
||||||
|
isAllowed = (currentTimeInMinutes >= startTimeInMinutes ||
|
||||||
|
currentTimeInMinutes <= endTimeInMinutes);
|
||||||
|
}
|
||||||
|
// If start time equals end time (24-hour trading)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isAllowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check for new trade signals |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CheckForTradeSignals()
|
||||||
|
{
|
||||||
|
// Don't open new trades if we already have open positions
|
||||||
|
if (CountOpenPositions() > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check for buy signal
|
||||||
|
if (IsBuySignal())
|
||||||
|
{
|
||||||
|
OpenBuyPosition();
|
||||||
|
}
|
||||||
|
// Check for sell signal
|
||||||
|
else if (IsSellSignal())
|
||||||
|
{
|
||||||
|
OpenSellPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check if we have a valid buy signal |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool IsBuySignal()
|
||||||
|
{
|
||||||
|
// 1. Trend Confirmation
|
||||||
|
bool trendConfirmation = true;
|
||||||
|
if (UseTrendConfirmation)
|
||||||
|
{
|
||||||
|
// X3MA: Fast MA crosses above Medium MA
|
||||||
|
bool fastCrossingAboveMedium = x3maFastBuffer[1] <= x3maMediumBuffer[1] &&
|
||||||
|
x3maFastBuffer[0] > x3maMediumBuffer[0];
|
||||||
|
|
||||||
|
// X3MA: All three MAs are in bullish alignment
|
||||||
|
bool maAlignment = true;
|
||||||
|
if (UseMAAlignment)
|
||||||
|
{
|
||||||
|
maAlignment = x3maFastBuffer[0] > x3maMediumBuffer[0] &&
|
||||||
|
x3maMediumBuffer[0] > x3maSlowBuffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// XCA: VIDYA line shows bullish color
|
||||||
|
bool vidyaBullish = true;
|
||||||
|
if (UseVidyaConfirmation)
|
||||||
|
{
|
||||||
|
vidyaBullish = xcaVidyaColorBuffer[0] == 1; // 1 is bullish color index
|
||||||
|
}
|
||||||
|
|
||||||
|
// XCA: Trend line shows bullish color
|
||||||
|
bool trendBullish = xcaTrendColorBuffer[0] == 1; // 1 is bullish color index
|
||||||
|
|
||||||
|
trendConfirmation = (fastCrossingAboveMedium || maAlignment) &&
|
||||||
|
(vidyaBullish || !UseVidyaConfirmation) &&
|
||||||
|
trendBullish;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Cycle Analysis
|
||||||
|
bool cycleAnalysis = true;
|
||||||
|
{
|
||||||
|
// XCA: Price is above the Short Cycle low
|
||||||
|
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||||
|
bool priceAboveSL = currentPrice > xcaSLBuffer[0];
|
||||||
|
|
||||||
|
// XCA: Medium Cycle is in uptrend phase
|
||||||
|
bool mediumCycleUptrend = xcaMLBuffer[0] > xcaMLBuffer[1];
|
||||||
|
|
||||||
|
// XCA: Support level is established and holding
|
||||||
|
bool supportHolding = currentPrice > xcaSupportBuffer[0];
|
||||||
|
|
||||||
|
cycleAnalysis = priceAboveSL && mediumCycleUptrend && supportHolding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Entry Timing
|
||||||
|
bool entryTiming = true;
|
||||||
|
{
|
||||||
|
// XCA: A swing low is identified
|
||||||
|
bool swingLowFound = UseSwingPoints ? xcaSwingLowBuffer[0] != 0 : true;
|
||||||
|
|
||||||
|
// XCA: Price is near but above the Fibonacci level 2 (50% retracement)
|
||||||
|
bool nearFiboLevel = true;
|
||||||
|
if (UseFiboLevels)
|
||||||
|
{
|
||||||
|
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||||
|
double fiboLevel = xcaFiboLevel2Buffer[0];
|
||||||
|
double priceDiff = MathAbs(currentPrice - fiboLevel);
|
||||||
|
double priceRange = xcaResistanceBuffer[0] - xcaSupportBuffer[0];
|
||||||
|
nearFiboLevel = priceDiff < priceRange * 0.1 && currentPrice > fiboLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XCA: KI line shows bullish color
|
||||||
|
bool kiBullish = true;
|
||||||
|
if (UseKIConfirmation)
|
||||||
|
{
|
||||||
|
kiBullish = xcaKIColorBuffer[0] == 1; // 1 is bullish color index
|
||||||
|
}
|
||||||
|
|
||||||
|
entryTiming = swingLowFound && (nearFiboLevel || !UseFiboLevels) &&
|
||||||
|
(kiBullish || !UseKIConfirmation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return trendConfirmation && cycleAnalysis && entryTiming;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Check if we have a valid sell signal |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool IsSellSignal()
|
||||||
|
{
|
||||||
|
// 1. Trend Confirmation
|
||||||
|
bool trendConfirmation = true;
|
||||||
|
if (UseTrendConfirmation)
|
||||||
|
{
|
||||||
|
// X3MA: Fast MA crosses below Medium MA
|
||||||
|
bool fastCrossingBelowMedium = x3maFastBuffer[1] >= x3maMediumBuffer[1] &&
|
||||||
|
x3maFastBuffer[0] < x3maMediumBuffer[0];
|
||||||
|
|
||||||
|
// X3MA: All three MAs are in bearish alignment
|
||||||
|
bool maAlignment = true;
|
||||||
|
if (UseMAAlignment)
|
||||||
|
{
|
||||||
|
maAlignment = x3maFastBuffer[0] < x3maMediumBuffer[0] &&
|
||||||
|
x3maMediumBuffer[0] < x3maSlowBuffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// XCA: VIDYA line shows bearish color
|
||||||
|
bool vidyaBearish = true;
|
||||||
|
if (UseVidyaConfirmation)
|
||||||
|
{
|
||||||
|
vidyaBearish = xcaVidyaColorBuffer[0] == 2; // 2 is bearish color index
|
||||||
|
}
|
||||||
|
|
||||||
|
// XCA: Trend line shows bearish color
|
||||||
|
bool trendBearish = xcaTrendColorBuffer[0] == 2; // 2 is bearish color index
|
||||||
|
|
||||||
|
trendConfirmation = (fastCrossingBelowMedium || maAlignment) &&
|
||||||
|
(vidyaBearish || !UseVidyaConfirmation) &&
|
||||||
|
trendBearish;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Cycle Analysis
|
||||||
|
bool cycleAnalysis = true;
|
||||||
|
{
|
||||||
|
// XCA: Price is below the Short Cycle high
|
||||||
|
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||||
|
bool priceBelowSH = currentPrice < xcaSHBuffer[0];
|
||||||
|
|
||||||
|
// XCA: Medium Cycle is in downtrend phase
|
||||||
|
bool mediumCycleDowntrend = xcaMHBuffer[0] < xcaMHBuffer[1];
|
||||||
|
|
||||||
|
// XCA: Resistance level is established and holding
|
||||||
|
bool resistanceHolding = currentPrice < xcaResistanceBuffer[0];
|
||||||
|
|
||||||
|
cycleAnalysis = priceBelowSH && mediumCycleDowntrend && resistanceHolding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Entry Timing
|
||||||
|
bool entryTiming = true;
|
||||||
|
{
|
||||||
|
// XCA: A swing high is identified
|
||||||
|
bool swingHighFound = UseSwingPoints ? xcaSwingHighBuffer[0] != 0 : true;
|
||||||
|
|
||||||
|
// XCA: Price is near but below the Fibonacci level 2 (50% retracement)
|
||||||
|
bool nearFiboLevel = true;
|
||||||
|
if (UseFiboLevels)
|
||||||
|
{
|
||||||
|
double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||||
|
double fiboLevel = xcaFiboLevel2Buffer[0];
|
||||||
|
double priceDiff = MathAbs(currentPrice - fiboLevel);
|
||||||
|
double priceRange = xcaResistanceBuffer[0] - xcaSupportBuffer[0];
|
||||||
|
nearFiboLevel = priceDiff < priceRange * 0.1 && currentPrice < fiboLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XCA: KI line shows bearish color
|
||||||
|
bool kiBearish = true;
|
||||||
|
if (UseKIConfirmation)
|
||||||
|
{
|
||||||
|
kiBearish = xcaKIColorBuffer[0] == 2; // 2 is bearish color index
|
||||||
|
}
|
||||||
|
|
||||||
|
entryTiming = swingHighFound && (nearFiboLevel || !UseFiboLevels) &&
|
||||||
|
(kiBearish || !UseKIConfirmation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return trendConfirmation && cycleAnalysis && entryTiming;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Count open positions with our magic number |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int CountOpenPositions()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int total = PositionsTotal();
|
||||||
|
|
||||||
|
for (int i = 0; i < total; i++)
|
||||||
|
{
|
||||||
|
ulong ticket = PositionGetTicket(i);
|
||||||
|
if (ticket <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if position belongs to current symbol and our EA
|
||||||
|
if (PositionGetString(POSITION_SYMBOL) == _Symbol &&
|
||||||
|
PositionGetInteger(POSITION_MAGIC) == magicNumber)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Manage open positions (trailing stops, partial closes) |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void ManageOpenPositions()
|
||||||
|
{
|
||||||
|
int total = PositionsTotal();
|
||||||
|
|
||||||
|
// Loop through all open positions
|
||||||
|
for (int i = total - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
ulong ticket = PositionGetTicket(i);
|
||||||
|
if (ticket <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if position belongs to current symbol and our EA
|
||||||
|
if (PositionGetString(POSITION_SYMBOL) != _Symbol ||
|
||||||
|
PositionGetInteger(POSITION_MAGIC) != magicNumber)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Get position details
|
||||||
|
double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||||
|
double currentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
|
||||||
|
double stopLoss = PositionGetDouble(POSITION_SL);
|
||||||
|
double takeProfit = PositionGetDouble(POSITION_TP);
|
||||||
|
double positionVolume = PositionGetDouble(POSITION_VOLUME);
|
||||||
|
ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
||||||
|
|
||||||
|
// Check for exit signals
|
||||||
|
bool exitSignal = false;
|
||||||
|
|
||||||
|
// For BUY positions
|
||||||
|
if (positionType == POSITION_TYPE_BUY)
|
||||||
|
{
|
||||||
|
// Exit if Fast MA crosses below Medium MA
|
||||||
|
if (x3maFastBuffer[1] > x3maMediumBuffer[1] && x3maFastBuffer[0] <= x3maMediumBuffer[0])
|
||||||
|
exitSignal = true;
|
||||||
|
|
||||||
|
// Apply trailing stop if enabled
|
||||||
|
if (UseTrailingStop && !exitSignal)
|
||||||
|
{
|
||||||
|
// Calculate new stop loss level
|
||||||
|
double newStopLoss = 0;
|
||||||
|
|
||||||
|
// Use the most recent swing low as trailing stop if available
|
||||||
|
if (xcaSwingLowBuffer[0] > 0 && xcaSwingLowBuffer[0] < currentPrice)
|
||||||
|
{
|
||||||
|
newStopLoss = xcaSwingLowBuffer[0] - 5 * _Point;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Traditional trailing stop
|
||||||
|
double trailingLevel = currentPrice - TrailingStop * _Point;
|
||||||
|
if (trailingLevel > stopLoss + TrailingStep * _Point)
|
||||||
|
newStopLoss = trailingLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update stop loss if we have a better level
|
||||||
|
if (newStopLoss > stopLoss && newStopLoss > 0)
|
||||||
|
{
|
||||||
|
trade.PositionModify(ticket, newStopLoss, takeProfit);
|
||||||
|
Print("Updated BUY trailing stop to: ", newStopLoss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle multiple targets
|
||||||
|
if (UseMultipleTargets && positionVolume > LotSize * 0.5)
|
||||||
|
{
|
||||||
|
// First target: When price reaches resistance or initial TP
|
||||||
|
if (currentPrice >= xcaResistanceBuffer[0] && xcaResistanceBuffer[0] > openPrice)
|
||||||
|
{
|
||||||
|
double closeVolume = NormalizeDouble(positionVolume * Target1Percent / 100, 2);
|
||||||
|
if (closeVolume > 0)
|
||||||
|
{
|
||||||
|
trade.PositionClosePartial(ticket, closeVolume);
|
||||||
|
Print("First target reached for BUY position. Partially closed: ", closeVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second target: When price reaches Fibonacci level 3 (76.4%)
|
||||||
|
double fiboLevel3Buffer[];
|
||||||
|
ArraySetAsSeries(fiboLevel3Buffer, true);
|
||||||
|
if (CopyBuffer(xcaHandle, 16, 0, 1, fiboLevel3Buffer) > 0)
|
||||||
|
{
|
||||||
|
double fiboLevel3 = fiboLevel3Buffer[0];
|
||||||
|
if (fiboLevel3 > 0 && currentPrice >= fiboLevel3 && fiboLevel3 > openPrice)
|
||||||
|
{
|
||||||
|
double closeVolume = NormalizeDouble(positionVolume * Target2Percent / 100, 2);
|
||||||
|
if (closeVolume > 0)
|
||||||
|
{
|
||||||
|
trade.PositionClosePartial(ticket, closeVolume);
|
||||||
|
Print("Second target reached for BUY position. Partially closed: ", closeVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// For SELL positions
|
||||||
|
else if (positionType == POSITION_TYPE_SELL)
|
||||||
|
{
|
||||||
|
// Exit if Fast MA crosses above Medium MA
|
||||||
|
if (x3maFastBuffer[1] < x3maMediumBuffer[1] && x3maFastBuffer[0] >= x3maMediumBuffer[0])
|
||||||
|
exitSignal = true;
|
||||||
|
|
||||||
|
// Apply trailing stop if enabled
|
||||||
|
if (UseTrailingStop && !exitSignal)
|
||||||
|
{
|
||||||
|
// Calculate new stop loss level
|
||||||
|
double newStopLoss = 0;
|
||||||
|
|
||||||
|
// Use the most recent swing high as trailing stop if available
|
||||||
|
if (xcaSwingHighBuffer[0] > 0 && xcaSwingHighBuffer[0] > currentPrice)
|
||||||
|
{
|
||||||
|
newStopLoss = xcaSwingHighBuffer[0] + 5 * _Point;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Traditional trailing stop
|
||||||
|
double trailingLevel = currentPrice + TrailingStop * _Point;
|
||||||
|
if (trailingLevel < stopLoss - TrailingStep * _Point || stopLoss == 0)
|
||||||
|
newStopLoss = trailingLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update stop loss if we have a better level
|
||||||
|
if ((newStopLoss < stopLoss || stopLoss == 0) && newStopLoss > 0)
|
||||||
|
{
|
||||||
|
trade.PositionModify(ticket, newStopLoss, takeProfit);
|
||||||
|
Print("Updated SELL trailing stop to: ", newStopLoss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle multiple targets
|
||||||
|
if (UseMultipleTargets && positionVolume > LotSize * 0.5)
|
||||||
|
{
|
||||||
|
// First target: When price reaches support or initial TP
|
||||||
|
if (currentPrice <= xcaSupportBuffer[0] && xcaSupportBuffer[0] < openPrice)
|
||||||
|
{
|
||||||
|
double closeVolume = NormalizeDouble(positionVolume * Target1Percent / 100, 2);
|
||||||
|
if (closeVolume > 0)
|
||||||
|
{
|
||||||
|
trade.PositionClosePartial(ticket, closeVolume);
|
||||||
|
Print("First target reached for SELL position. Partially closed: ", closeVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second target: When price reaches Fibonacci level 3 (76.4%)
|
||||||
|
double fiboLevel3Buffer[];
|
||||||
|
ArraySetAsSeries(fiboLevel3Buffer, true);
|
||||||
|
if (CopyBuffer(xcaHandle, 16, 0, 1, fiboLevel3Buffer) > 0)
|
||||||
|
{
|
||||||
|
double fiboLevel3 = fiboLevel3Buffer[0];
|
||||||
|
if (fiboLevel3 > 0 && currentPrice <= fiboLevel3 && fiboLevel3 < openPrice)
|
||||||
|
{
|
||||||
|
double closeVolume = NormalizeDouble(positionVolume * Target2Percent / 100, 2);
|
||||||
|
if (closeVolume > 0)
|
||||||
|
{
|
||||||
|
trade.PositionClosePartial(ticket, closeVolume);
|
||||||
|
Print("Second target reached for SELL position. Partially closed: ", closeVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close position if exit signal is triggered
|
||||||
|
if (exitSignal)
|
||||||
|
{
|
||||||
|
trade.PositionClose(ticket);
|
||||||
|
Print("Exit signal triggered. Position closed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Open a buy position with proper risk management |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OpenBuyPosition()
|
||||||
|
{
|
||||||
|
double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||||
|
double stopLossPrice = 0;
|
||||||
|
double takeProfitPrice = 0;
|
||||||
|
|
||||||
|
// Calculate stop loss price
|
||||||
|
if (StopLoss > 0)
|
||||||
|
{
|
||||||
|
// Use either the specified stop loss or the swing low, whichever is closer
|
||||||
|
double swingLowPrice = xcaSwingLowBuffer[0];
|
||||||
|
double slByPoints = entryPrice - StopLoss * _Point;
|
||||||
|
|
||||||
|
// If we have a valid swing low and it's not too far
|
||||||
|
if (swingLowPrice > 0 && entryPrice - swingLowPrice < StopLoss * 2 * _Point)
|
||||||
|
stopLossPrice = swingLowPrice - 5 * _Point; // Place SL slightly below swing low
|
||||||
|
else
|
||||||
|
stopLossPrice = slByPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate take profit price
|
||||||
|
if (TakeProfit > 0)
|
||||||
|
{
|
||||||
|
// If using multiple targets, we'll set the first one here and manage the rest in position management
|
||||||
|
if (UseMultipleTargets)
|
||||||
|
{
|
||||||
|
// Use resistance level as first target if available
|
||||||
|
if (xcaResistanceBuffer[0] > entryPrice)
|
||||||
|
takeProfitPrice = xcaResistanceBuffer[0];
|
||||||
|
else
|
||||||
|
takeProfitPrice = entryPrice + TakeProfit * _Point;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
takeProfitPrice = entryPrice + TakeProfit * _Point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate position size
|
||||||
|
double volume = LotSize;
|
||||||
|
if (UseAutoLotSize && stopLossPrice > 0)
|
||||||
|
{
|
||||||
|
double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100;
|
||||||
|
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) *
|
||||||
|
(SymbolInfoDouble(_Symbol, SYMBOL_POINT) / SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
|
||||||
|
double pipDistance = MathAbs(entryPrice - stopLossPrice) / SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||||
|
|
||||||
|
if (pipDistance > 0 && pipValue > 0)
|
||||||
|
volume = NormalizeDouble(riskAmount / (pipDistance * pipValue), 2);
|
||||||
|
|
||||||
|
// Ensure volume is within allowed limits
|
||||||
|
double minVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||||
|
double maxVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||||
|
double volumeStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
||||||
|
|
||||||
|
volume = MathMax(minVolume, MathMin(maxVolume, volume));
|
||||||
|
volume = NormalizeDouble(volume / volumeStep, 0) * volumeStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the trade
|
||||||
|
trade.Buy(volume, _Symbol, 0, stopLossPrice, takeProfitPrice, "X121 Strategy Buy");
|
||||||
|
|
||||||
|
// Log the trade
|
||||||
|
Print("BUY Signal: Opening position at ", entryPrice,
|
||||||
|
", SL: ", stopLossPrice,
|
||||||
|
", TP: ", takeProfitPrice,
|
||||||
|
", Volume: ", volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Open a sell position with proper risk management |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OpenSellPosition()
|
||||||
|
{
|
||||||
|
double entryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||||
|
double stopLossPrice = 0;
|
||||||
|
double takeProfitPrice = 0;
|
||||||
|
|
||||||
|
// Calculate stop loss price
|
||||||
|
if (StopLoss > 0)
|
||||||
|
{
|
||||||
|
// Use either the specified stop loss or the swing high, whichever is closer
|
||||||
|
double swingHighPrice = xcaSwingHighBuffer[0];
|
||||||
|
double slByPoints = entryPrice + StopLoss * _Point;
|
||||||
|
|
||||||
|
// If we have a valid swing high and it's not too far
|
||||||
|
if (swingHighPrice > 0 && swingHighPrice - entryPrice < StopLoss * 2 * _Point)
|
||||||
|
stopLossPrice = swingHighPrice + 5 * _Point; // Place SL slightly above swing high
|
||||||
|
else
|
||||||
|
stopLossPrice = slByPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate take profit price
|
||||||
|
if (TakeProfit > 0)
|
||||||
|
{
|
||||||
|
// If using multiple targets, we'll set the first one here and manage the rest in position management
|
||||||
|
if (UseMultipleTargets)
|
||||||
|
{
|
||||||
|
// Use support level as first target if available
|
||||||
|
if (xcaSupportBuffer[0] > 0 && xcaSupportBuffer[0] < entryPrice)
|
||||||
|
takeProfitPrice = xcaSupportBuffer[0];
|
||||||
|
else
|
||||||
|
takeProfitPrice = entryPrice - TakeProfit * _Point;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
takeProfitPrice = entryPrice - TakeProfit * _Point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate position size
|
||||||
|
double volume = LotSize;
|
||||||
|
if (UseAutoLotSize && stopLossPrice > 0)
|
||||||
|
{
|
||||||
|
double riskAmount = AccountInfoDouble(ACCOUNT_BALANCE) * RiskPercent / 100;
|
||||||
|
double pipValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) *
|
||||||
|
(SymbolInfoDouble(_Symbol, SYMBOL_POINT) / SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE));
|
||||||
|
double pipDistance = MathAbs(entryPrice - stopLossPrice) / SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
||||||
|
|
||||||
|
if (pipDistance > 0 && pipValue > 0)
|
||||||
|
volume = NormalizeDouble(riskAmount / (pipDistance * pipValue), 2);
|
||||||
|
|
||||||
|
// Ensure volume is within allowed limits
|
||||||
|
double minVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
||||||
|
double maxVolume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
||||||
|
double volumeStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
||||||
|
|
||||||
|
volume = MathMax(minVolume, MathMin(maxVolume, volume));
|
||||||
|
volume = NormalizeDouble(volume / volumeStep, 0) * volumeStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the trade
|
||||||
|
trade.Sell(volume, _Symbol, 0, stopLossPrice, takeProfitPrice, "X121 Strategy Sell");
|
||||||
|
|
||||||
|
// Log the trade
|
||||||
|
Print("SELL Signal: Opening position at ", entryPrice,
|
||||||
|
", SL: ", stopLossPrice,
|
||||||
|
", TP: ", takeProfitPrice,
|
||||||
|
", Volume: ", volume);
|
||||||
|
}
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center XTest MQL5 Expert Advisor
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XRRToolsEA
|
||||||
|
// Description: a Template For Exper Advisors
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////x
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm XRRToolsEA"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "XRRTools"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.x-rm.panel.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.x-trade.class.mq5"
|
||||||
|
#include "../Helpers/x-saherelm.x121.xcc.helper.mq5"
|
||||||
|
#include "../Helpers/x-saherelm.x121.xct.helper.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
input group "Common";
|
||||||
|
input long eaMagicNumber = 78692110; // Magic Number
|
||||||
|
input int eaSlippage = 10; // Slippgae
|
||||||
|
input string eaLogSuffix = ""; // Log Suffix
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert ...
|
||||||
|
// Here we Provider All Requirements for
|
||||||
|
// Configuring Alert Provider ...
|
||||||
|
input group "Alert";
|
||||||
|
input bool eAEnableAlerts = true; // Enable Alerts
|
||||||
|
input bool eALogAlerts = true; // Log Alerts
|
||||||
|
input bool eAMailAlerts = false; // Mail Alerts
|
||||||
|
input bool eAPushAlerts = false; // Push Alerts
|
||||||
|
input bool eATerminalAlerts = false; // Terminal Alerts
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Local Variables ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string eaLogTag; // EA Log Prefix ...
|
||||||
|
XCAlert *eaAlert; // Alert Provider for Expert Adviser ...
|
||||||
|
XCTrade *eaTrader; // Trader of Expert Adviser ...
|
||||||
|
XCRMPanel eaMainWindow; // Main Window ...
|
||||||
|
XCX121XCTHelper *eaCTHelper; // Bar Timer Indicator Helper class ...
|
||||||
|
XCX121XCCHelper *eaCCHelper; // Chart Styler Indicator Helper Class ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization ...
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs and Required Parameters
|
||||||
|
// for EA to Works fine ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Timer ...
|
||||||
|
if (!InitTimer())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize all Requirements ...
|
||||||
|
if (!InitEA())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize all GUI Objects and Classes ...
|
||||||
|
if (!InitGUI())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert Initialization ...
|
||||||
|
string msg = "Initialized Successfully ...";
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DeInitialization ...
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy Timer ...
|
||||||
|
DestroyTimer();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy all GUI Requirements ...
|
||||||
|
DestroyGUI();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert De Initialization Succeeded ...
|
||||||
|
string msg = "De Initialized Successfully ...";
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy all EA Requirements ...
|
||||||
|
DestroyEA();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Tick Handler ...
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
UpdateGUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle On Trade Event ...
|
||||||
|
void OnTrade()
|
||||||
|
{
|
||||||
|
eaTrader.HandleOnTrade();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Timer ...
|
||||||
|
void OnTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Implement Time Based Functionalities ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chart Event Handler ...
|
||||||
|
void OnChartEvent(
|
||||||
|
const int id,
|
||||||
|
const long &lparam,
|
||||||
|
const double &dparam,
|
||||||
|
const string &sparam //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Apply Chart Event on Main Window ...
|
||||||
|
eaMainWindow.ChartEvent(id, lparam, dparam, sparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle StopLoss Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal ...
|
||||||
|
*/
|
||||||
|
void OnStopLossTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Take Profit Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal ...
|
||||||
|
*/
|
||||||
|
void OnTakeProfitTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Force Close a Position ...
|
||||||
|
*
|
||||||
|
* @param ticket: Position Ticket ...
|
||||||
|
* @param position: XPosition ...
|
||||||
|
* @param comment: Closing Comment ...
|
||||||
|
*/
|
||||||
|
void OnPositionForceClosed(
|
||||||
|
const ulong ticket,
|
||||||
|
const XPosition &position,
|
||||||
|
const string comment //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate all Inputs of Expert Adviser ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
string errMessage = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCommonValid = (
|
||||||
|
//
|
||||||
|
eaSlippage > 0 &&
|
||||||
|
eaMagicNumber > 0
|
||||||
|
//
|
||||||
|
);
|
||||||
|
if (!isCommonValid)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
errMessage += "common configurations error;" + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
isCommonValid &&
|
||||||
|
//
|
||||||
|
// Otere ...
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
||||||
|
Print(ShortName + " Errors: \n", errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Timer ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Initialize Timer if necessary ...
|
||||||
|
// result = EventSetTimer(1);
|
||||||
|
// result = EventSetMillisecondTimer(100);
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy Timer ...
|
||||||
|
*/
|
||||||
|
void DestroyTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Use This ...
|
||||||
|
// EventKillTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all Requirements for Working Fine ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locally Apply Changes on Prefix ...
|
||||||
|
eaLogTag = ShortName + ">" + eaLogSuffix;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bar Timer ...
|
||||||
|
X121XCTInputs ctInputs;
|
||||||
|
ctInputs.Default(); // Default Configurations ...
|
||||||
|
eaCTHelper = new XCX121XCTHelper();
|
||||||
|
result = eaCTHelper.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
ctInputs //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bar Styles ...
|
||||||
|
X121XCCInputs ccInputs;
|
||||||
|
ccInputs.Default(); // Default Configurations ...
|
||||||
|
eaCCHelper = new XCX121XCCHelper();
|
||||||
|
result = eaCCHelper.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
ccInputs //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Instance of Alert Class and Configure it ...
|
||||||
|
eaAlert = new XCAlert();
|
||||||
|
eaAlert.SetPrefix(eaLogTag);
|
||||||
|
eaAlert.SetLogAlerts(eALogAlerts);
|
||||||
|
eaAlert.SetMailAlerts(eAMailAlerts);
|
||||||
|
eaAlert.SetPushAlerts(eAPushAlerts);
|
||||||
|
eaAlert.SetEnableAlerts(eAEnableAlerts);
|
||||||
|
eaAlert.SetTerminalAlerts(eATerminalAlerts);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create Trader Instance and Configure it ...
|
||||||
|
eaTrader = new XCTrade(
|
||||||
|
eaSlippage,
|
||||||
|
eaMagicNumber //
|
||||||
|
);
|
||||||
|
eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered);
|
||||||
|
eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
||||||
|
eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all Initialized EA Requirements ...
|
||||||
|
*/
|
||||||
|
void DestroyEA()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
delete eaCTHelper;
|
||||||
|
delete eaCCHelper;
|
||||||
|
|
||||||
|
//
|
||||||
|
delete eaAlert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all GUI Requirements for EA ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Application Main Window ...
|
||||||
|
result = eaMainWindow.Create(
|
||||||
|
ChartID(),
|
||||||
|
ShortName, // Dialog Name ...
|
||||||
|
0, // SubWindow ...
|
||||||
|
10, // X1 ...
|
||||||
|
35, // Y1 ...
|
||||||
|
300, // X2 ...
|
||||||
|
200 // Y2 ...
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try To Run Main Window ...
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
eaMainWindow.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update GUI based on Each Ticks ...
|
||||||
|
*/
|
||||||
|
void UpdateGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaMainWindow.UpdateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all Initialized GUi Requirements ...
|
||||||
|
*/
|
||||||
|
void DestroyGUI()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaMainWindow.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,745 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center XCAEA MQL5 Expert Advisor
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XCAEA
|
||||||
|
// Description: an Exper Advisor which used Panels
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm XCAEA EA"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.x-alert.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.x-trade.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.x-volume.class.mq5"
|
||||||
|
#include "../XCAEA/Classes/xcaea.x-trade.manager.class.mq5"
|
||||||
|
#include "../XCAEA/Signals/xcaea.signaller.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "XCAEAEA"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
input group "Common";
|
||||||
|
input long eaMagicNumber = 78692110; // Magic Number
|
||||||
|
input int eaSlippage = 10; // Slippgae
|
||||||
|
input string eaLogSuffix = ""; // Log Suffix
|
||||||
|
|
||||||
|
//
|
||||||
|
// Volume ...
|
||||||
|
input group "Volume";
|
||||||
|
input ENUM_X_VOLUME_SELECT_TYPE eaVolumeSelect = X_VOLUME_EQUITY; // Volume Applying Type
|
||||||
|
input double eaStaticVoluem = 0.0; // 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.5; // Constant Percent of Balance Per Trade
|
||||||
|
input double eaConstantBalance = 0.0; // Constant Balance for Calculations
|
||||||
|
|
||||||
|
//
|
||||||
|
// Management ...
|
||||||
|
input group "Management";
|
||||||
|
input bool eaAllowTrade = true; // Allow Trade on Signals
|
||||||
|
input bool eaAllowLongs = true; // Allow Long Trades
|
||||||
|
input bool eaAllowShorts = true; // Allow Short Trades
|
||||||
|
input int eaMaxAllowedTradesPerDay = 3; // Max Allowed Trades per Day
|
||||||
|
input int eaMaxAllowedSLsPerDay = 2; // Max Allowed SL(s) per Day
|
||||||
|
input string eaSessionStartTime = ""; // Trade Start Time
|
||||||
|
input string eaSessionEndTime = ""; // Trade End Time
|
||||||
|
input int eaMaxAllowedPositions = 5; // Max Allowed Same Time Trades
|
||||||
|
input double eaMaxAllowedSpread = 25; // Max Allowed Spread For Trade
|
||||||
|
input double eaMaxAllowedDrawdownFactor = 0.3; // Max Allowed DrawDown for Trade
|
||||||
|
input string eaCloseAllOpenTradesAt = ""; // Close All Open Trades per Day At Specified Time
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert ...
|
||||||
|
// Here we Provider All Requirements for
|
||||||
|
// Configuring Alert Provider ...
|
||||||
|
input group "Alert";
|
||||||
|
input bool eaEnableAlerts = true; // Enable Alerts
|
||||||
|
input bool eaLogAlerts = true; // Log Alerts
|
||||||
|
input bool eaMailAlerts = false; // Mail Alerts
|
||||||
|
input bool eaPushAlerts = false; // Push Alerts
|
||||||
|
input bool eaTerminalAlerts = false; // Terminal Alerts
|
||||||
|
|
||||||
|
//
|
||||||
|
// Time Report ...
|
||||||
|
input group "Reports";
|
||||||
|
input bool eaReportNewMonths = false; // Report New Month
|
||||||
|
input bool eaReportNewWeeks = false; // Report New Weeks
|
||||||
|
input bool eaReportNewDays = true; // Report New Days
|
||||||
|
input bool eaReportNewHours = false; // Report New Hours
|
||||||
|
input bool eaReportTrades = true; // Report Trades
|
||||||
|
input bool eaReportSignals = true; // Report Signals
|
||||||
|
input bool eaReportProtector = true; // Report Protector Actions
|
||||||
|
input bool eaReportAfterTradesBalance = true; // Report Balance after a Trade Finished
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Instances ...
|
||||||
|
XCAlert *eaAlert;
|
||||||
|
XCTrade *eaTrade;
|
||||||
|
XSignal eaSignal;
|
||||||
|
XCVolume *eaVolume;
|
||||||
|
XTimeTracker eaTimeTracker;
|
||||||
|
XCXCAEASignaller *eaSignaller;
|
||||||
|
XCXCAEATradeManager *eaTradeManager;
|
||||||
|
XCAEAStrategyConditions eaConditions;
|
||||||
|
|
||||||
|
//
|
||||||
|
string eaTag = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization ...
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs and Required Parameters
|
||||||
|
// for EA to Works fine ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Timer ...
|
||||||
|
if (!InitTimer())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial Requirements ...
|
||||||
|
InitRequirements();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Volume Manger ...
|
||||||
|
if (!InitVolume())
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DeInitialization ...
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
|
||||||
|
//
|
||||||
|
// eaSignaller.DeInit();
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(eaAlert);
|
||||||
|
ZeroMemory(eaTrade);
|
||||||
|
ZeroMemory(eaVolume);
|
||||||
|
ZeroMemory(eaSignaller);
|
||||||
|
|
||||||
|
//
|
||||||
|
eaSignal.Clean();
|
||||||
|
eaConditions.Clean();
|
||||||
|
eaTimeTracker.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
DestroyTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Tick Handler ...
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
HandleTimeReport();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle Position Management / Protections ...
|
||||||
|
eaTradeManager.Manage();
|
||||||
|
|
||||||
|
//
|
||||||
|
eaSignal.Clean();
|
||||||
|
eaConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
double r2r = 4;
|
||||||
|
string provider = "XCAEA";
|
||||||
|
ENUM_POSITION_TYPE type = POSITION_TYPE_BUY;
|
||||||
|
ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool hasLong = false;
|
||||||
|
bool hasShort = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start Calculations ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Common Data ...
|
||||||
|
string symbol = eaSignaller.GetSymbol();
|
||||||
|
ENUM_TIMEFRAMES period = eaSignaller.GetPeriod();
|
||||||
|
|
||||||
|
//
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Required Value For SL/TP Calculations ...
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
double pip = GetPipPrice(symbol);
|
||||||
|
double pip2 = 2 * pip;
|
||||||
|
|
||||||
|
//
|
||||||
|
has = eaSignaller.DetectSignalSetup(
|
||||||
|
r2r,
|
||||||
|
300 // Max Allowed SL Distance ...
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
count = eaSignaller
|
||||||
|
.AddConditionsIfNotExists();
|
||||||
|
|
||||||
|
//
|
||||||
|
eaSignaller.mConditions.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Setuped Conditions Exists ...
|
||||||
|
count = ArraySize(eaSignaller.mConditionsCollection);
|
||||||
|
has = IsValidSize(count);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
has = eaSignaller
|
||||||
|
.DetectSignalTrigger(eaSignaller
|
||||||
|
.mConditionsCollection[i]);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If Triggered ...
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = i;
|
||||||
|
eaConditions = eaSignaller.mConditionsCollection[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Condition Validation ...
|
||||||
|
has = eaSignaller.mConditionsCollection[i].IsValid() &&
|
||||||
|
eaSignaller.mConditionsCollection[i].IsSetuped();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Setuped Condition if provided IDX ...
|
||||||
|
has = IsValidIndex(idx);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArrayRemove(
|
||||||
|
eaSignaller.mConditionsCollection,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check EA Conditions is Valid or not ...
|
||||||
|
has = eaConditions.IsSetuped() &&
|
||||||
|
eaConditions.CanTrigger();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaConditions.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setting Time to Conditions ...
|
||||||
|
eaConditions.time = cTime;
|
||||||
|
has = ToPositionType(
|
||||||
|
type,
|
||||||
|
eaConditions.type //
|
||||||
|
);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaSignal.Clean();
|
||||||
|
eaConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Trigger Direction ...
|
||||||
|
hasLong = eaConditions.HasBullishSignal();
|
||||||
|
hasShort = eaConditions.HasBearishSignal();
|
||||||
|
has = hasLong ||
|
||||||
|
hasShort;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaSignal.Clean();
|
||||||
|
eaConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Preparing Signal ...
|
||||||
|
//
|
||||||
|
eaSignal.mode = mode;
|
||||||
|
eaSignal.type = type;
|
||||||
|
eaSignal.entry = GetEntry(
|
||||||
|
eaConditions.symbol,
|
||||||
|
eaConditions.dir //
|
||||||
|
);
|
||||||
|
eaSignal.provider = provider;
|
||||||
|
eaSignal.sl = eaConditions.sl;
|
||||||
|
eaSignal.tp = eaConditions.tp;
|
||||||
|
eaSignal.volume = X_MIN_VOLUME;
|
||||||
|
eaSignal.time = eaConditions.time;
|
||||||
|
eaSignal.symbol = eaConditions.symbol;
|
||||||
|
eaSignal.period = eaConditions.period;
|
||||||
|
eaSignal.partialCloseOnTPLevel = eaConditions.partialCloseOnTPLevel;
|
||||||
|
eaSignal.partialCloseMultiplier = eaConditions.partialCloseMultiplier;
|
||||||
|
|
||||||
|
//
|
||||||
|
Copy(
|
||||||
|
eaConditions.targets,
|
||||||
|
eaSignal.targets //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
has = eaSignal.IsValid();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaSignal.Clean();
|
||||||
|
eaConditions.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle Volume Management ...
|
||||||
|
double iVolume = eaVolume.CalculateVolume(eaSignal);
|
||||||
|
if (iVolume > X_MIN_VOLUME &&
|
||||||
|
iVolume != eaSignal.volume)
|
||||||
|
{
|
||||||
|
eaSignal.volume = iVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Signal ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Execute Signal ...
|
||||||
|
|
||||||
|
//
|
||||||
|
has = eaTradeManager.Execute(
|
||||||
|
eaSignal,
|
||||||
|
eaConditions //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
eaSignal.Clean();
|
||||||
|
eaConditions.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle On Trade Event ...
|
||||||
|
void OnTrade()
|
||||||
|
{
|
||||||
|
eaTrade.HandleOnTrade();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Timer ...
|
||||||
|
void OnTimer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chart Event Handler ...
|
||||||
|
void OnChartEvent(
|
||||||
|
const int id,
|
||||||
|
const long &lparam,
|
||||||
|
const double &dparam,
|
||||||
|
const string &sparam //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Listeners ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle StopLoss Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal instance ...
|
||||||
|
*/
|
||||||
|
void OnStopLossTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
eaTradeManager.HandleSL(deal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Take Profit Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal instance ...
|
||||||
|
*/
|
||||||
|
void OnTakeProfitTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
eaTradeManager.HandleTP(deal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Force Close a Position ...
|
||||||
|
*
|
||||||
|
* @param ticket: ULONG ...
|
||||||
|
* @param position: XPosition instance ...
|
||||||
|
* @param comment: String ...
|
||||||
|
*/
|
||||||
|
void OnPositionForceClosed(
|
||||||
|
const ulong ticket,
|
||||||
|
const XPosition &position,
|
||||||
|
const string comment //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
eaTradeManager.HandleForceClose(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Deals Changes ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
void OnDealsChanged(int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Orders Changes ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
void OnOrdersChanged(int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Positions Changes ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
void OnPositionsChanged(int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate all Inputs of Expert Adviser ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
string errMessage = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCommonValid = (
|
||||||
|
//
|
||||||
|
eaSlippage > 0 &&
|
||||||
|
eaMagicNumber > 0
|
||||||
|
//
|
||||||
|
);
|
||||||
|
if (!isCommonValid)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
errMessage += "common configurations error;" + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
isCommonValid &&
|
||||||
|
//
|
||||||
|
// Otere ...
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Since here Logger not Initiallized, we Use Raw Print Command ...
|
||||||
|
Print(ShortName + " Errors: \n", errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Timer ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Initialize Timer if necessary ...
|
||||||
|
// result = EventSetTimer(1);
|
||||||
|
// result = EventSetMillisecondTimer(100);
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy Timer ...
|
||||||
|
*/
|
||||||
|
void DestroyTimer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// TODO: Use This ...
|
||||||
|
// EventKillTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial Volume Manager Class Based on Given Configuration ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitVolume()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
eaVolume = new XCVolume();
|
||||||
|
|
||||||
|
//
|
||||||
|
result = eaVolume.Init(
|
||||||
|
eaVolumeSelect,
|
||||||
|
eaStaticVoluem,
|
||||||
|
eaDynamicVolumeStepBalance,
|
||||||
|
eaDynamicVolumeStepVolume,
|
||||||
|
eaConstantRiskBalance,
|
||||||
|
eaConstantPercent,
|
||||||
|
eaConstantBalance //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial Requirements of EA ...
|
||||||
|
*/
|
||||||
|
void InitRequirements()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Preparing Tags ...
|
||||||
|
eaTag =
|
||||||
|
(IsValid(eaLogSuffix)
|
||||||
|
? eaLogSuffix + "_"
|
||||||
|
: "") +
|
||||||
|
ShortName;
|
||||||
|
|
||||||
|
//
|
||||||
|
// EA Alert ...
|
||||||
|
eaAlert = new XCAlert(
|
||||||
|
eaTag,
|
||||||
|
eaEnableAlerts,
|
||||||
|
eaLogAlerts,
|
||||||
|
eaTerminalAlerts,
|
||||||
|
eaMailAlerts,
|
||||||
|
eaPushAlerts //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// EA Trade ...
|
||||||
|
eaTrade = new XCTrade(
|
||||||
|
eaSlippage,
|
||||||
|
eaMagicNumber,
|
||||||
|
eaMaxAllowedSpread,
|
||||||
|
eaMaxAllowedPositions,
|
||||||
|
eaMaxAllowedDrawdownFactor //
|
||||||
|
);
|
||||||
|
eaTrade.AddOnStopLossEventHandler(OnStopLossTriggered);
|
||||||
|
eaTrade.AddOnTakeProfitEventHandler(OnTakeProfitTriggered);
|
||||||
|
eaTrade.AddOnForceClosePositionEventHandler(OnPositionForceClosed);
|
||||||
|
|
||||||
|
//
|
||||||
|
// EA Trae Manager ...
|
||||||
|
eaTradeManager = new XCXCAEATradeManager(
|
||||||
|
eaTrade //
|
||||||
|
);
|
||||||
|
eaTradeManager.SaveTrades(true);
|
||||||
|
eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts);
|
||||||
|
eaTradeManager.SetAlertPrefix(eaTag);
|
||||||
|
eaTradeManager.SetAlertLogAlerts(eaLogAlerts);
|
||||||
|
eaTradeManager.SetAlertMailAlerts(eaMailAlerts);
|
||||||
|
eaTradeManager.SetAlertPushAlerts(eaPushAlerts);
|
||||||
|
eaTradeManager.SetAlertTerminalAlerts(eaTerminalAlerts);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setting Trade Reports ...
|
||||||
|
eaTradeManager
|
||||||
|
.SetTradeReports(
|
||||||
|
eaReportTrades,
|
||||||
|
eaReportSignals,
|
||||||
|
eaReportProtector,
|
||||||
|
eaReportAfterTradesBalance //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setting Trade Permissions ...
|
||||||
|
eaTradeManager
|
||||||
|
.SetTradePermissions(
|
||||||
|
eaAllowTrade,
|
||||||
|
eaAllowLongs,
|
||||||
|
eaAllowShorts //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// eaMaxAllowedTradesPerDay
|
||||||
|
// eaMaxAllowedSLsPerDay
|
||||||
|
// eaSessionStartTime
|
||||||
|
// eaSessionEndTime
|
||||||
|
|
||||||
|
//
|
||||||
|
// EA Signaller ...
|
||||||
|
eaSignaller = new XCXCAEASignaller(
|
||||||
|
_Symbol,
|
||||||
|
_Period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handling Time Reporting ...
|
||||||
|
*/
|
||||||
|
void HandleTimeReport()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Monthly Report ....
|
||||||
|
if (eaReportNewMonths &&
|
||||||
|
eaTimeTracker.IsNewMonth())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Month ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weekly Report ....
|
||||||
|
if (eaReportNewWeeks &&
|
||||||
|
eaTimeTracker.IsNewWeek())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Week ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Daily Report ....
|
||||||
|
bool isNewDay = eaTimeTracker.IsNewDay();
|
||||||
|
if (isNewDay)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Handle New Day on Trade Manager ...
|
||||||
|
eaTradeManager.HandleNewDay();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reporting New Day if Reuired ...
|
||||||
|
if (eaReportNewDays)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Day ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hourly Report ....
|
||||||
|
if (eaReportNewHours &&
|
||||||
|
eaTimeTracker.IsNewHour())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string msg = "New Hour ...";
|
||||||
|
|
||||||
|
//
|
||||||
|
eaAlert.Alert(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,252 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Helper Class Library
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Name: XSCX121XCCHelper
|
||||||
|
// Description: provides all 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
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.x-helper.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Input Models ...
|
||||||
|
struct X121XCCInputs
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chart Style ...
|
||||||
|
ENUM_CHART_MODE mode; // Mode
|
||||||
|
color upColor; // Up Color
|
||||||
|
color downColor; // Down Color
|
||||||
|
color lineColor; // Line mode and Doji candlestick Color
|
||||||
|
color bearishColor; // Bullish Color
|
||||||
|
color bullishColor; // Bearish Color
|
||||||
|
color volumesColor; // Volumes Color
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
bool showCandles; // Show Candles
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor(s) ...
|
||||||
|
X121XCCInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean ...
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mode = CHART_CANDLES;
|
||||||
|
|
||||||
|
//
|
||||||
|
upColor = CLR_NONE;
|
||||||
|
downColor = CLR_NONE;
|
||||||
|
lineColor = CLR_NONE;
|
||||||
|
bearishColor = CLR_NONE;
|
||||||
|
bullishColor = CLR_NONE;
|
||||||
|
volumesColor = CLR_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
showCandles = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default ...
|
||||||
|
void Default()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mode = CHART_CANDLES;
|
||||||
|
|
||||||
|
//
|
||||||
|
upColor = clrLime;
|
||||||
|
downColor = clrRed;
|
||||||
|
lineColor = clrLime;
|
||||||
|
bearishColor = clrRed;
|
||||||
|
bullishColor = clrLime;
|
||||||
|
volumesColor = clrGreen;
|
||||||
|
//
|
||||||
|
showCandles = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ...
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve MAx Length ...
|
||||||
|
int Max()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(0, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class ...
|
||||||
|
class XCX121XCCHelper : public XCBaseHelper
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructors ...
|
||||||
|
XCX121XCCHelper()
|
||||||
|
: XCBaseHelper(_Symbol, _Period)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCX121XCCHelper()
|
||||||
|
{
|
||||||
|
mInputs.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
bool Init(
|
||||||
|
string symbol, // Trading Symbol
|
||||||
|
ENUM_TIMEFRAMES period, // Trading Period
|
||||||
|
X121XCCInputs &inputs // Inputs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
mSymbol = symbol;
|
||||||
|
mPeriod = period;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = inputs.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
mInputs = inputs;
|
||||||
|
|
||||||
|
//
|
||||||
|
mHandler = iCustom(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
"x-saherelm.x121.xcc",
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
//
|
||||||
|
// Chart Style ...
|
||||||
|
"",
|
||||||
|
mInputs.mode, // Mode
|
||||||
|
mInputs.upColor, // Up Color
|
||||||
|
mInputs.downColor, // Down Color
|
||||||
|
mInputs.lineColor, // Line mode and Doji candlestick Color
|
||||||
|
mInputs.bullishColor, // Bearish Color
|
||||||
|
mInputs.bearishColor, // Bullish Color
|
||||||
|
mInputs.volumesColor, // Volumes Color
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
"",
|
||||||
|
mInputs.showCandles // Show Candles
|
||||||
|
//
|
||||||
|
);
|
||||||
|
result = mHandler != INVALID_HANDLE;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
X121XCCInputs GetInputs()
|
||||||
|
{
|
||||||
|
return mInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool SetInputs(
|
||||||
|
X121XCCInputs &inputs // Configs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
return Init(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
inputs
|
||||||
|
//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
X121XCCInputs mInputs; // Inputs ...
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Helper Class Library
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Name: XSCX121XCTHelper
|
||||||
|
// Description: provides all 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
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Classes/x-saherelm.x-helper.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Input Models ...
|
||||||
|
struct X121XCTInputs
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string font; // Font
|
||||||
|
int fontSize; // Font Size;
|
||||||
|
color clr; // Text Color
|
||||||
|
ENUM_BASE_CORNER corner; // Text Position
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
bool showCandleTime; // Show Candle Time
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor(s) ...
|
||||||
|
X121XCTInputs()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean ...
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
font = NULL;
|
||||||
|
fontSize = 15;
|
||||||
|
clr = CLR_NONE;
|
||||||
|
corner = CORNER_RIGHT_LOWER;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
showCandleTime = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default ...
|
||||||
|
void Default()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
font = "Arial";
|
||||||
|
fontSize = 15;
|
||||||
|
clr = clrYellow;
|
||||||
|
corner = CORNER_RIGHT_LOWER;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
showCandleTime = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ...
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve MAx Length ...
|
||||||
|
int Max()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(0, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class ...
|
||||||
|
class XCX121XCTHelper : public XCBaseHelper
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructors ...
|
||||||
|
XCX121XCTHelper()
|
||||||
|
: XCBaseHelper(_Symbol, _Period)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCX121XCTHelper()
|
||||||
|
{
|
||||||
|
mInputs.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
bool Init(
|
||||||
|
string symbol, // Trading Symbol
|
||||||
|
ENUM_TIMEFRAMES period, // Trading Period
|
||||||
|
X121XCTInputs &inputs // Inputs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
mSymbol = symbol;
|
||||||
|
mPeriod = period;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = inputs.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
mInputs = inputs;
|
||||||
|
|
||||||
|
//
|
||||||
|
mHandler = iCustom(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
"x-saherelm.x121.xct",
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
mInputs.fontSize, // Font Size ...
|
||||||
|
mInputs.font, // Font ...
|
||||||
|
mInputs.clr, // Text Color ...
|
||||||
|
mInputs.corner, // Text Position ...
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
"",
|
||||||
|
mInputs.showCandleTime // Show Candle Time
|
||||||
|
//
|
||||||
|
);
|
||||||
|
result = mHandler != INVALID_HANDLE;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
X121XCTInputs GetInputs()
|
||||||
|
{
|
||||||
|
return mInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool SetInputs(
|
||||||
|
X121XCTInputs &inputs // Configs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
return Init(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
inputs
|
||||||
|
//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
X121XCTInputs mInputs; // Inputs ...
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,788 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 X3MA
|
||||||
|
// Description: X3MA ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm X121 X3MA Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 X3MA"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast ...
|
||||||
|
input group "Fast";
|
||||||
|
input int fastLength = 6; // Length
|
||||||
|
input ENUM_MA_METHOD fastMethod = MODE_SMA; // Method
|
||||||
|
input ENUM_APPLIED_PRICE fastAppliedTo = PRICE_CLOSE; // Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
// Medium ...
|
||||||
|
input group "Medium";
|
||||||
|
input int mediumLength = 21; // Length
|
||||||
|
input ENUM_MA_METHOD mediumMethod = MODE_SMA; // Method
|
||||||
|
input ENUM_APPLIED_PRICE mediumAppliedTo = PRICE_CLOSE; // Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow ...
|
||||||
|
input group "Slow";
|
||||||
|
input int slowLength = 34; // Length
|
||||||
|
input ENUM_MA_METHOD slowMethod = MODE_SMA; // Method
|
||||||
|
input ENUM_APPLIED_PRICE slowAppliedTo = PRICE_CLOSE; // Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool applyColor = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showFast = true; // Show Fast
|
||||||
|
input bool showMedium = true; // Show Medium
|
||||||
|
input bool showSlow = true; // Show Slow
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#define bullishState 1
|
||||||
|
#define neuturalState 0
|
||||||
|
#define bearishState -1
|
||||||
|
|
||||||
|
//
|
||||||
|
#define emptyValue 0.0
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 9
|
||||||
|
#property indicator_plots 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define fastBufferIndex 0
|
||||||
|
double fastBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define fastColorBufferIndex 1
|
||||||
|
double fastColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label1 "X121 X3MA Fast"
|
||||||
|
#property indicator_type1 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color1 CLR_NONE, clrYellow, clrChocolate, clrGray
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
#property indicator_width1 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define mediumBufferIndex 2
|
||||||
|
double mediumBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define mediumColorBufferIndex 3
|
||||||
|
double mediumColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label2 "X121 X3MA Medium"
|
||||||
|
#property indicator_type2 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color2 CLR_NONE, clrAqua, clrMagenta, clrGray
|
||||||
|
#property indicator_style2 STYLE_DASHDOTDOT
|
||||||
|
#property indicator_width2 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define slowBufferIndex 4
|
||||||
|
double slowBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define slowColorBufferIndex 5
|
||||||
|
double slowColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label3 "X121 X3MA Slow"
|
||||||
|
#property indicator_type3 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color3 CLR_NONE, clrLime, clrRed, clrGray
|
||||||
|
#property indicator_style3 STYLE_DASH
|
||||||
|
#property indicator_width3 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
#define mLastBufferIndex 5
|
||||||
|
|
||||||
|
//
|
||||||
|
#define fastStateBufferIndex mLastBufferIndex + 1
|
||||||
|
double fastStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define mediumStateBufferIndex mLastBufferIndex + 2
|
||||||
|
double mediumStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define slowStateBufferIndex mLastBufferIndex + 3
|
||||||
|
double slowStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
int fastHandler = INVALID_HANDLE;
|
||||||
|
int mediumHandler = INVALID_HANDLE;
|
||||||
|
int slowHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
fastHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
fastLength,
|
||||||
|
0,
|
||||||
|
fastMethod,
|
||||||
|
fastAppliedTo //
|
||||||
|
);
|
||||||
|
bool isInited = fastHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
mediumHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
mediumLength,
|
||||||
|
0,
|
||||||
|
mediumMethod,
|
||||||
|
mediumAppliedTo //
|
||||||
|
);
|
||||||
|
isInited = mediumHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
slowHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
slowLength,
|
||||||
|
0,
|
||||||
|
slowMethod,
|
||||||
|
slowAppliedTo //
|
||||||
|
);
|
||||||
|
isInited = slowHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// because in some cases we may have more than one input for
|
||||||
|
// calculation and we must prevent any calculation
|
||||||
|
// untill we pass the biggest input length, here we get max Input length
|
||||||
|
// and then wait until pass it ...
|
||||||
|
maxLength = ExtractMaxLengthOfInputs();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Index Buffers ...
|
||||||
|
DefineBuffers();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Indicator ShortName ...
|
||||||
|
SetIndicatorName();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @param reason: Integer, De Initialization Reason ...
|
||||||
|
*/
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
|
||||||
|
//
|
||||||
|
IndicatorRelease(fastHandler);
|
||||||
|
IndicatorRelease(mediumHandler);
|
||||||
|
IndicatorRelease(slowHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Bars ...
|
||||||
|
*
|
||||||
|
* @param rates_total: Integer, Total Bars on Chart ...
|
||||||
|
* @param prev_calculated: Integer, Total Calculated Bars on Charts ...
|
||||||
|
* @param time: DateTime Array, History of Open Time ...
|
||||||
|
* @param open: Double Array, History of Open Prices ...
|
||||||
|
* @param high: Double Array, History of High Prices ...
|
||||||
|
* @param low: Double Array, History of Low Prices ...
|
||||||
|
* @param close: Double Array, History of Close Prices ...
|
||||||
|
* @param tick_volume: Long, History of Tick Volumes on Bar ...
|
||||||
|
* @param volume: Long, History of Trade Volumes ...
|
||||||
|
* @param spread: Double, History of Spread Price ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnCalculate(
|
||||||
|
const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const datetime &time[],
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[],
|
||||||
|
const long &tick_volume[],
|
||||||
|
const long &volume[],
|
||||||
|
const int &spread[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Prepare Buffers ...
|
||||||
|
ArraySetAsSeries(time, true);
|
||||||
|
ArraySetAsSeries(open, true);
|
||||||
|
ArraySetAsSeries(high, true);
|
||||||
|
ArraySetAsSeries(low, true);
|
||||||
|
ArraySetAsSeries(close, true);
|
||||||
|
ArraySetAsSeries(tick_volume, true);
|
||||||
|
ArraySetAsSeries(volume, true);
|
||||||
|
ArraySetAsSeries(spread, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Calculated Bars ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
int fastCalculatedBars = BarsCalculated(fastHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
int mediumCalculatedBars = BarsCalculated(mediumHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
int slowCalculatedBars = BarsCalculated(slowHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isPassedRequiredCalculatedBars =
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
fastCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
mediumCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
slowCalculatedBars >= maxLength
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCalculatedBars)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
int copiedFasts = CopyBuffer(fastHandler, 0, 0, limit, fastBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
int copiedMediumss = CopyBuffer(mediumHandler, 0, 0, limit, mediumBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
int copiedSlows = CopyBuffer(slowHandler, 0, 0, limit, slowBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Copied Items ...
|
||||||
|
bool isPassedRequiredCopiedItems =
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
copiedFasts >= limit &&
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
copiedMediumss >= limit &&
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
copiedSlows >= limit
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCopiedItems)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateBuffers(
|
||||||
|
i,
|
||||||
|
prev_calculated,
|
||||||
|
rates_total,
|
||||||
|
//
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tick_volume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Input Args for Initialization ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
fastLength > 2 &&
|
||||||
|
mediumLength > 2 &&
|
||||||
|
slowLength > 2 &&
|
||||||
|
mediumLength > fastLength &&
|
||||||
|
mediumLength < slowLength
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(fastLength, mediumLength);
|
||||||
|
result = MathMax(result, slowLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(fastBuffer, true);
|
||||||
|
SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(fastBufferIndex, PLOT_SHOW_DATA, showFast);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(fastBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(fastColorBuffer, true);
|
||||||
|
SetIndexBuffer(fastColorBufferIndex, fastColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(mediumBuffer, true);
|
||||||
|
SetIndexBuffer(mediumBufferIndex, mediumBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(mediumBufferIndex, PLOT_SHOW_DATA, showMedium);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(mediumBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(mediumColorBuffer, true);
|
||||||
|
SetIndexBuffer(mediumColorBufferIndex, mediumColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(slowBuffer, true);
|
||||||
|
SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(slowBufferIndex, PLOT_SHOW_DATA, showSlow);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(slowBufferIndex, PLOT_EMPTY_VALUE, emptyValue);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(slowColorBuffer, true);
|
||||||
|
SetIndexBuffer(slowColorBufferIndex, slowColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST State ...
|
||||||
|
ArraySetAsSeries(fastStateBuffer, true);
|
||||||
|
SetIndexBuffer(fastStateBufferIndex, fastStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM State ...
|
||||||
|
ArraySetAsSeries(mediumStateBuffer, true);
|
||||||
|
SetIndexBuffer(mediumStateBufferIndex, mediumStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW State ...
|
||||||
|
ArraySetAsSeries(slowStateBuffer, true);
|
||||||
|
SetIndexBuffer(slowStateBufferIndex, slowStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Custom Buffers ...
|
||||||
|
*
|
||||||
|
* @param bar_index: Integer, Represent Current Bar ...
|
||||||
|
* @param prevCalculated: Integer, Represent Previous Calculated Bars ...
|
||||||
|
* @param ratesTotal: Integer, Represents All Available Bars ...
|
||||||
|
* @param open: Double Array, History of Open Prices ...
|
||||||
|
* @param high: Double Array, History of High Prices ...
|
||||||
|
* @param close: Double Array, History of Close Prices ...
|
||||||
|
* @param low: Double Array, History of Low Prices ...
|
||||||
|
* @param tickVolume: Long, History of Tick Volumes on Bar ...
|
||||||
|
*/
|
||||||
|
void CalculateBuffers(
|
||||||
|
int bar_index, // Selected Bar Index
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal,
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &close[],
|
||||||
|
const double &low[],
|
||||||
|
const long &tickVolume[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int barsLimit = startCalculationForLastBars > 0
|
||||||
|
? startCalculationForLastBars
|
||||||
|
: 0;
|
||||||
|
//
|
||||||
|
// bool canCalculate = true;
|
||||||
|
bool canCalculate =
|
||||||
|
barsLimit == 0 ||
|
||||||
|
bar_index <= barsLimit;
|
||||||
|
if (canCalculate)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Calculate Values ...
|
||||||
|
CalculateValues(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FillBuffersZero(bar_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer ...
|
||||||
|
*/
|
||||||
|
void FillBuffersZero(int barIndex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
fastBuffer[barIndex] = emptyValue;
|
||||||
|
fastColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
fastStateBuffer[barIndex] = neuturalState;
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
mediumBuffer[barIndex] = emptyValue;
|
||||||
|
mediumColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
mediumStateBuffer[barIndex] = neuturalState;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
slowBuffer[barIndex] = emptyValue;
|
||||||
|
slowColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
slowStateBuffer[barIndex] = neuturalState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Values ...
|
||||||
|
*
|
||||||
|
* @param bar_index: int, Specified Bar Index ...
|
||||||
|
* @param prevCalculated: int, Provides Previous Calculated Bars ...
|
||||||
|
* @param ratesTotal: int, Provides All Availabled Bars ...
|
||||||
|
* @param open: double Collection, Provides Open Prices Time Series ...
|
||||||
|
* @param high: double Collection, Provides High Prices Time Series ...
|
||||||
|
* @param close: double Collection, Provides Close Prices Time Series ...
|
||||||
|
* @param low: double Collection, Provides Low Prices Time Series ...
|
||||||
|
* @param tickVolume: long Collection, Provides Ticks Volume Prices Time Series ...
|
||||||
|
*/
|
||||||
|
void CalculateValues(
|
||||||
|
int bar_index, // Selected Bar Index
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal,
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &close[],
|
||||||
|
const double &low[],
|
||||||
|
const long &tickVolume[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check Prev Bar ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int lastBarIndex = bar_index + 1;
|
||||||
|
bool isFirstBar =
|
||||||
|
startCalculationForLastBars > 0
|
||||||
|
? bar_index == startCalculationForLastBars
|
||||||
|
: bar_index == ratesTotal;
|
||||||
|
|
||||||
|
//
|
||||||
|
double iLow = low[bar_index];
|
||||||
|
double iHigh = high[bar_index];
|
||||||
|
double iClose = close[bar_index];
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double iFast = fastBuffer[bar_index];
|
||||||
|
|
||||||
|
//
|
||||||
|
double iFastState =
|
||||||
|
iLow > iFast
|
||||||
|
? bullishState
|
||||||
|
: iHigh < iFast
|
||||||
|
? bearishState
|
||||||
|
: neuturalState;
|
||||||
|
double iFastColor = hideColorIDX;
|
||||||
|
if (showFast)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (applyColor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iFastColor =
|
||||||
|
iFastState == bullishState
|
||||||
|
? bullishColorIDX
|
||||||
|
: iFastState == bearishState
|
||||||
|
? bearishColorIDX
|
||||||
|
: neuturalColorIDX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iFastColor = bullishColorIDX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fastColorBuffer[bar_index] = iFastColor;
|
||||||
|
fastStateBuffer[bar_index] = iFastState;
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double iMedium = mediumBuffer[bar_index];
|
||||||
|
|
||||||
|
//
|
||||||
|
double iMediumState =
|
||||||
|
iLow > iMedium
|
||||||
|
? bullishState
|
||||||
|
: iHigh < iMedium
|
||||||
|
? bearishState
|
||||||
|
: neuturalState;
|
||||||
|
double iMediumColor = hideColorIDX;
|
||||||
|
if (showMedium)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (applyColor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iMediumColor =
|
||||||
|
iMediumState == bullishState
|
||||||
|
? bullishColorIDX
|
||||||
|
: iMediumState == bearishState
|
||||||
|
? bearishColorIDX
|
||||||
|
: neuturalColorIDX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iMediumColor = bullishColorIDX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mediumColorBuffer[bar_index] = iMediumColor;
|
||||||
|
mediumStateBuffer[bar_index] = iMediumState;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double iSlow = slowBuffer[bar_index];
|
||||||
|
|
||||||
|
//
|
||||||
|
double iSlowState =
|
||||||
|
iLow > iSlow
|
||||||
|
? bullishState
|
||||||
|
: iHigh < iSlow
|
||||||
|
? bearishState
|
||||||
|
: neuturalState;
|
||||||
|
double iSlowColor = hideColorIDX;
|
||||||
|
if (showSlow)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (applyColor)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iSlowColor =
|
||||||
|
iSlowState == bullishState
|
||||||
|
? bullishColorIDX
|
||||||
|
: iSlowState == bearishState
|
||||||
|
? bearishColorIDX
|
||||||
|
: neuturalColorIDX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iSlowColor = bullishColorIDX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slowColorBuffer[bar_index] = iSlowColor;
|
||||||
|
slowStateBuffer[bar_index] = iSlowState;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,437 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Candle Styles
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// Name: X121 XCC
|
||||||
|
// Description: Candle Styles ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm X121 XCC Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Constants ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Indicator Short Name ...
|
||||||
|
#define ShortName "X121 XCC"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Holds an SnapShot of Charts Configuration ...
|
||||||
|
struct XChartStyle
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// chart's ID ...
|
||||||
|
long chartId;
|
||||||
|
//
|
||||||
|
// chart's mode ...
|
||||||
|
ENUM_CHART_MODE mode;
|
||||||
|
//
|
||||||
|
// show bid line ...
|
||||||
|
bool showBidLine;
|
||||||
|
//
|
||||||
|
// show ask line ...
|
||||||
|
bool showAskLine;
|
||||||
|
//
|
||||||
|
// show grids on chart ...
|
||||||
|
bool showGrid;
|
||||||
|
//
|
||||||
|
// show volumes ...
|
||||||
|
bool showVolumes;
|
||||||
|
//
|
||||||
|
// Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) ...
|
||||||
|
bool showTradeLevels;
|
||||||
|
//
|
||||||
|
// chart autoscroll ...
|
||||||
|
bool autoScroll;
|
||||||
|
//
|
||||||
|
// chart quick navigation state ...
|
||||||
|
bool quickNavigation;
|
||||||
|
//
|
||||||
|
// chart's foreground color ...
|
||||||
|
color foreGroundColor;
|
||||||
|
//
|
||||||
|
// chart's background color ...
|
||||||
|
color backGroundColor;
|
||||||
|
//
|
||||||
|
// Up Color ...
|
||||||
|
color upColor;
|
||||||
|
//
|
||||||
|
// Down Color ...
|
||||||
|
color downColor;
|
||||||
|
//
|
||||||
|
// Bullish color ...
|
||||||
|
color bullishColor;
|
||||||
|
//
|
||||||
|
// Bearish color ...
|
||||||
|
color bearishColor;
|
||||||
|
//
|
||||||
|
// grid color ...
|
||||||
|
color gridColor;
|
||||||
|
//
|
||||||
|
// bid line color ...
|
||||||
|
color bidLineColor;
|
||||||
|
//
|
||||||
|
// ask line color ...
|
||||||
|
color askLineColor;
|
||||||
|
//
|
||||||
|
// line mode and doji candlestick color ...
|
||||||
|
color lineColor;
|
||||||
|
//
|
||||||
|
// Color of stop order levels (Stop Loss and Take Profit) ...
|
||||||
|
color stopColor;
|
||||||
|
//
|
||||||
|
// volumes color ...
|
||||||
|
color volumesColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Constants ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Inputs ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "Chart Style";
|
||||||
|
input ENUM_CHART_MODE mode = CHART_CANDLES; // Mode
|
||||||
|
input color upColor = clrGreen; // Up Color
|
||||||
|
input color downColor = clrRed; // Down Color
|
||||||
|
input color lineColor = clrGreen; // Line mode and Doji candlestick Color
|
||||||
|
input color bullishColor = clrGreen; // Bullish Color
|
||||||
|
input color bearishColor = clrRed; // Bearish Color
|
||||||
|
input color volumesColor = clrGreen; // Volumes Color
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "Presentation";
|
||||||
|
input bool showCandles = true; // Show Candles
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Inputs ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Includes and Imports ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Draw Library ...
|
||||||
|
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Includes and Imports ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Buffers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 0
|
||||||
|
#property indicator_plots 0
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Buffers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Global Definitions: Variables, Properties and etc ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
XChartStyle chartStyle;
|
||||||
|
XChartStyle clearStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Global Definitions: Variables, Properties and etc ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Event Handlers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization ...
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
drawPrefix = ShortName;
|
||||||
|
|
||||||
|
//
|
||||||
|
// because in some cases we may have more than one input for
|
||||||
|
// calculation and we must prevent any calculation
|
||||||
|
// untill we pass the biggest input length, here we get max Input length
|
||||||
|
// and then wait until pass it ...
|
||||||
|
maxLength = ExtractMaxLengthOfInputs();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Index Buffers ...
|
||||||
|
DefineBuffers();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Indicator ShortName ...
|
||||||
|
SetIndicatorName();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Apply Chart Style ...
|
||||||
|
ApplyCustomChartStyle();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DeInitialization ...
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculating what we want ...
|
||||||
|
int OnCalculate(
|
||||||
|
const int rates_total, // Total Bars on Chart ...
|
||||||
|
const int prev_calculated, // Total Calculated Bars on Charts ...
|
||||||
|
const datetime &time[], // History of Open Time ...
|
||||||
|
const double &open[], // History of Open Price ...
|
||||||
|
const double &high[], // History of High Price ...
|
||||||
|
const double &low[], // History of Low Price ...
|
||||||
|
const double &close[], // History of Close Price ...
|
||||||
|
const long &tick_volume[], // History of Tick Volumes on Bar ...
|
||||||
|
const long &volume[], // History of Trade Volumes ...
|
||||||
|
const int &spread[] // History of Spread Price ...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Prepare Buffers ...
|
||||||
|
ArraySetAsSeries(time, true);
|
||||||
|
ArraySetAsSeries(open, true);
|
||||||
|
ArraySetAsSeries(high, true);
|
||||||
|
ArraySetAsSeries(low, true);
|
||||||
|
ArraySetAsSeries(close, true);
|
||||||
|
ArraySetAsSeries(tick_volume, true);
|
||||||
|
ArraySetAsSeries(volume, true);
|
||||||
|
ArraySetAsSeries(spread, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||||
|
{
|
||||||
|
CalculateBuffers(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Event Handlers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Functions ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Input Args for Initialization ...
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve all Exists Input Max Length ...
|
||||||
|
// use for Start Of Drawing ...
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Indexes and Styles ...
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate Buffers ...
|
||||||
|
void CalculateBuffers(
|
||||||
|
int bar_index // Selected Bar Index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Apply Custom Chart Style ...
|
||||||
|
void ApplyCustomChartStyle()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Read Current Chart Config and Store it ...
|
||||||
|
ReadChartStyle();
|
||||||
|
|
||||||
|
//
|
||||||
|
// After Reading Current Chart Style ...
|
||||||
|
// we have to Save Configs and Change Styles ...
|
||||||
|
clearStyle = chartStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
clearStyle.upColor = CLR_NONE;
|
||||||
|
clearStyle.downColor = CLR_NONE;
|
||||||
|
clearStyle.lineColor = CLR_NONE;
|
||||||
|
clearStyle.bullishColor = CLR_NONE;
|
||||||
|
clearStyle.bearishColor = CLR_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Decide to Show or not Candles based on User Input ...
|
||||||
|
if (showCandles)
|
||||||
|
{
|
||||||
|
SetChartStyle(chartStyle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetChartStyle(clearStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read Previous Chart Style ...
|
||||||
|
void ReadChartStyle()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Retrieve Current Chart ID ...
|
||||||
|
long chartId = ChartID();
|
||||||
|
chartStyle.chartId = chartId;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Chart Mode ...
|
||||||
|
chartStyle.mode = (ENUM_CHART_MODE)ChartGetInteger(chartId, CHART_MODE);
|
||||||
|
|
||||||
|
//
|
||||||
|
chartStyle.showBidLine = (bool)ChartGetInteger(chartId, CHART_SHOW_BID_LINE);
|
||||||
|
chartStyle.showAskLine = (bool)ChartGetInteger(chartId, CHART_SHOW_ASK_LINE);
|
||||||
|
chartStyle.showGrid = (bool)ChartGetInteger(chartId, CHART_SHOW_GRID);
|
||||||
|
chartStyle.showVolumes = (bool)ChartGetInteger(chartId, CHART_SHOW_VOLUMES);
|
||||||
|
chartStyle.showTradeLevels = (bool)ChartGetInteger(chartId, CHART_SHOW_TRADE_LEVELS);
|
||||||
|
chartStyle.autoScroll = (bool)ChartGetInteger(chartId, CHART_AUTOSCROLL);
|
||||||
|
chartStyle.quickNavigation = (bool)ChartGetInteger(chartId, CHART_QUICK_NAVIGATION);
|
||||||
|
|
||||||
|
//
|
||||||
|
chartStyle.foreGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_FOREGROUND);
|
||||||
|
chartStyle.backGroundColor = (color)ChartGetInteger(chartId, CHART_COLOR_BACKGROUND);
|
||||||
|
chartStyle.upColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_UP);
|
||||||
|
chartStyle.downColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_DOWN);
|
||||||
|
chartStyle.bullishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BULL);
|
||||||
|
chartStyle.bearishColor = (color)ChartGetInteger(chartId, CHART_COLOR_CANDLE_BEAR);
|
||||||
|
chartStyle.gridColor = (color)ChartGetInteger(chartId, CHART_COLOR_GRID);
|
||||||
|
chartStyle.bidLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_BID);
|
||||||
|
chartStyle.askLineColor = (color)ChartGetInteger(chartId, CHART_COLOR_ASK);
|
||||||
|
chartStyle.stopColor = (color)ChartGetInteger(chartId, CHART_COLOR_STOP_LEVEL);
|
||||||
|
chartStyle.lineColor = (color)ChartGetInteger(chartId, CHART_COLOR_CHART_LINE);
|
||||||
|
chartStyle.volumesColor = (color)ChartGetInteger(chartId, CHART_COLOR_VOLUME);
|
||||||
|
|
||||||
|
//
|
||||||
|
chartStyle.mode = mode;
|
||||||
|
chartStyle.upColor = upColor;
|
||||||
|
chartStyle.downColor = downColor;
|
||||||
|
chartStyle.lineColor = lineColor;
|
||||||
|
chartStyle.bearishColor = bearishColor;
|
||||||
|
chartStyle.bullishColor = bullishColor;
|
||||||
|
chartStyle.volumesColor = volumesColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Chart Style ...
|
||||||
|
void SetChartStyle(
|
||||||
|
XChartStyle &mChartStyle // Chart Style to Apply
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ApplyChartStyle(
|
||||||
|
mChartStyle.chartId,
|
||||||
|
mChartStyle.mode,
|
||||||
|
mChartStyle.showBidLine,
|
||||||
|
mChartStyle.showAskLine,
|
||||||
|
mChartStyle.showGrid,
|
||||||
|
mChartStyle.showVolumes,
|
||||||
|
mChartStyle.showTradeLevels,
|
||||||
|
mChartStyle.autoScroll,
|
||||||
|
mChartStyle.quickNavigation,
|
||||||
|
mChartStyle.foreGroundColor,
|
||||||
|
mChartStyle.backGroundColor,
|
||||||
|
mChartStyle.upColor,
|
||||||
|
mChartStyle.downColor,
|
||||||
|
mChartStyle.bullishColor,
|
||||||
|
mChartStyle.bearishColor,
|
||||||
|
mChartStyle.gridColor,
|
||||||
|
mChartStyle.bidLineColor,
|
||||||
|
mChartStyle.askLineColor,
|
||||||
|
mChartStyle.lineColor,
|
||||||
|
mChartStyle.stopColor,
|
||||||
|
mChartStyle.volumesColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Functions ...
|
||||||
|
//
|
||||||
@@ -0,0 +1,262 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// ---------------------------------------------
|
||||||
|
// Name: X121 XCT
|
||||||
|
// Description: Trend Magic Indicator ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm X121 XCT Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Constants ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XCT"
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Constants ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Inputs ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
input int fontSize = 15; // Font Size
|
||||||
|
input string font = "Arial"; // Font
|
||||||
|
input color clr = clrYellow; // Text Color
|
||||||
|
input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; // Text Position
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "Presentation";
|
||||||
|
input bool showTimer = true; // Show Candle Time
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Inputs ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Buffers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 0
|
||||||
|
#property indicator_plots 0
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Buffers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Global Definitions: Variables, Properties and etc ...
|
||||||
|
//
|
||||||
|
bool isCreatedObject;
|
||||||
|
string tag;
|
||||||
|
//
|
||||||
|
// END Global Definitions: Variables, Properties and etc ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Event Handlers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialization ...
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
tag = ShortName + _Symbol + ToString(_Period);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Indicator ShortName ...
|
||||||
|
SetIndicatorName();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init Succeed ...
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// DeInitialization ...
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function
|
||||||
|
// REASON_REMOVE 1 Program removed from a chart
|
||||||
|
// REASON_RECOMPILE 2 Program recompiled
|
||||||
|
// REASON_CHARTCHANGE 3 A symbol or a chart period is changed
|
||||||
|
// REASON_CHARTCLOSE 4 Chart closed
|
||||||
|
// REASON_PARAMETERS 5 Inputs changed by a user
|
||||||
|
// REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings
|
||||||
|
// REASON_TEMPLATE 7 Another chart template applied
|
||||||
|
// REASON_INITFAILED 8 The OnInit() handler returned a non-zero value
|
||||||
|
// REASON_CLOSE 9 Terminal closed
|
||||||
|
|
||||||
|
//
|
||||||
|
// Delete Object ...
|
||||||
|
ObjectDelete(0, tag);
|
||||||
|
|
||||||
|
//
|
||||||
|
Comment("");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculating what we want ...
|
||||||
|
int OnCalculate(
|
||||||
|
const int rates_total, // Total Bars on Chart ...
|
||||||
|
const int prev_calculated, // Total Calculated Bars on Charts ...
|
||||||
|
const datetime &time[], // History of Open Time ...
|
||||||
|
const double &open[], // History of Open Price ...
|
||||||
|
const double &high[], // History of High Price ...
|
||||||
|
const double &low[], // History of Low Price ...
|
||||||
|
const double &close[], // History of Close Price ...
|
||||||
|
const long &tick_volume[], // History of Tick Volumes on Bar ...
|
||||||
|
const long &volume[], // History of Trade Volumes ...
|
||||||
|
const int &spread[] // History of Spread Price ...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!showTimer)
|
||||||
|
{
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XBarRemainsTime barRemains;
|
||||||
|
barRemains.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period
|
||||||
|
//
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
string msg = barRemains
|
||||||
|
.ToString(
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
":",
|
||||||
|
true
|
||||||
|
//
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
|
||||||
|
|
||||||
|
//
|
||||||
|
string _sp = "";
|
||||||
|
if (mSpread < 10)
|
||||||
|
_sp = "..";
|
||||||
|
else if (mSpread < 100)
|
||||||
|
_sp = ".";
|
||||||
|
|
||||||
|
//
|
||||||
|
string objText = "Spread: " + IntegerToString(mSpread) + _sp + ", Next Bar in: " + msg;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (IsValid(tag) && !isCreatedObject)
|
||||||
|
{
|
||||||
|
CreateIndicatorObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isCreatedObject)
|
||||||
|
{
|
||||||
|
ObjectSetString(0, tag, OBJPROP_TEXT, objText);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Event Handlers ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// START Functions ...
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void CreateIndicatorObject()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!showTimer ||
|
||||||
|
!IsValid(tag))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
isCreatedObject = ObjectCreate(0, tag, OBJ_LABEL, 0, 0, 0);
|
||||||
|
ObjectSetInteger(0, tag, OBJPROP_CORNER, corner);
|
||||||
|
ObjectSetInteger(0, tag, OBJPROP_XDISTANCE, 10);
|
||||||
|
ObjectSetInteger(0, tag, OBJPROP_YDISTANCE, 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER;
|
||||||
|
switch (corner)
|
||||||
|
{
|
||||||
|
case CORNER_LEFT_UPPER:
|
||||||
|
Anchor = ANCHOR_LEFT_UPPER;
|
||||||
|
break;
|
||||||
|
case CORNER_RIGHT_UPPER:
|
||||||
|
Anchor = ANCHOR_RIGHT_UPPER;
|
||||||
|
break;
|
||||||
|
case CORNER_LEFT_LOWER:
|
||||||
|
Anchor = ANCHOR_LEFT_LOWER;
|
||||||
|
break;
|
||||||
|
case CORNER_RIGHT_LOWER:
|
||||||
|
Anchor = ANCHOR_RIGHT_LOWER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int mFontSize = fontSize > 0
|
||||||
|
? fontSize
|
||||||
|
: 10;
|
||||||
|
|
||||||
|
//
|
||||||
|
string mFont = IsValid(font)
|
||||||
|
? font
|
||||||
|
: "Arial";
|
||||||
|
|
||||||
|
//
|
||||||
|
ObjectSetString(0, tag, OBJPROP_FONT, mFont);
|
||||||
|
ObjectSetInteger(0, tag, OBJPROP_COLOR, clr);
|
||||||
|
ObjectSetInteger(0, tag, OBJPROP_ANCHOR, Anchor);
|
||||||
|
ObjectSetInteger(0, tag, OBJPROP_FONTSIZE, mFontSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// END Functions ...
|
||||||
|
//
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,157 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Common Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: XCommonLib
|
||||||
|
// Description: provide all commonly used functions ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 "../Libraries/x-saherelm.common.extensions.lib.mq5"
|
||||||
|
#include "../Libraries/x-saherelm.common.models.lib.mq5"
|
||||||
|
#include "../Libraries/x-saherelm.x-ohcl.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Models ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Consolidation Zone ...
|
||||||
|
struct XConsolidationZone
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string symbol; // Symbol ...
|
||||||
|
ENUM_TIMEFRAMES period; // Period ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double upper; // Upper ...
|
||||||
|
double lower; // Lower ...
|
||||||
|
|
||||||
|
//
|
||||||
|
datetime from; // Start Date
|
||||||
|
datetime to; // Breake Date
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION dir; // Break Direction ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XConsolidationZone()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup ...
|
||||||
|
*/
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
upper = 0;
|
||||||
|
lower = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
to = NULL;
|
||||||
|
from = NULL;
|
||||||
|
symbol = NULL;
|
||||||
|
period = NULL;
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
upper > 0 &&
|
||||||
|
lower > 0 &&
|
||||||
|
IsValid(to) &&
|
||||||
|
IsValid(from) &&
|
||||||
|
IsValid(symbol) &&
|
||||||
|
IsValid(period) &&
|
||||||
|
HasDirection(dir)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSameAs(
|
||||||
|
XConsolidationZone &item //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsValid() &&
|
||||||
|
item.IsValid() &&
|
||||||
|
dir == item.dir &&
|
||||||
|
from == item.from &&
|
||||||
|
upper == item.upper &&
|
||||||
|
lower == item.lower &&
|
||||||
|
symbol == item.symbol &&
|
||||||
|
period == item.period;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve Unique Identifier ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GetTag()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result =
|
||||||
|
//
|
||||||
|
"XCZONE" + "_" +
|
||||||
|
ToString(dir) + "_" +
|
||||||
|
symbol + "_" +
|
||||||
|
ToString(period) + "_" +
|
||||||
|
ToString(upper) + "_" +
|
||||||
|
ToString(lower)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,392 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Common Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: XModelsLib
|
||||||
|
// Description: provide all commonly used functions ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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.extensions.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Use To Parse Symbols for
|
||||||
|
// Ignore Brokers Additional Suffixes ...
|
||||||
|
struct XSymbolParser
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string version; // Temp ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbol Parsing ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Forext ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsEURUSD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"EUR",
|
||||||
|
"USD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsUSDJPY(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"USD",
|
||||||
|
"JPY" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsEURJPY(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"EUR",
|
||||||
|
"JPY" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsUSDCHF(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"USD",
|
||||||
|
"CHF" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsEURCHF(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"EUR",
|
||||||
|
"CHF" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsGBPUSD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"GBP",
|
||||||
|
"USD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsEURGBP(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"EUR",
|
||||||
|
"GBP" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsAUDUSD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"AUD",
|
||||||
|
"USD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsEURAUD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"EUR",
|
||||||
|
"AUD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsUSDCAD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"USD",
|
||||||
|
"CAD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsEURCAD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"EUR",
|
||||||
|
"CAD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsNZDUSD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"NZD",
|
||||||
|
"USD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsEURNZD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"EUR",
|
||||||
|
"NZD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Metals ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsXAUUSD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"XAU",
|
||||||
|
"USD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsXAGUSD(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbolIdentifiers[] = {
|
||||||
|
"XAG",
|
||||||
|
"USD" //
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
symbolIdentifiers,
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Indexes ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsDowJones(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
"DowJones30",
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Oil ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool IsBrent(string symbol)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = Contains(
|
||||||
|
"BRENT",
|
||||||
|
symbol //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbol Finder ...
|
||||||
|
string GetEURUSDSymbol()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
string symbols[];
|
||||||
|
int symbolsCount = GetAllSymbols(
|
||||||
|
symbols //
|
||||||
|
);
|
||||||
|
if (!IsValidSize(symbolsCount))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < symbolsCount; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string iSymbol = symbols[i];
|
||||||
|
if (IsEURUSD(iSymbol))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = iSymbol;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,167 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XCXCAEADataCollector ...
|
||||||
|
// Description: Class for XCAEA Data Collector ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XCAEA Data Collector"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../../Classes/x-saherelm.base.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementation ...
|
||||||
|
class XCXCAEADataCollector : public XCBase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Constructors ...
|
||||||
|
XCXCAEADataCollector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCXCAEADataCollector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Properties ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string Path()
|
||||||
|
{
|
||||||
|
return mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void Path(string value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Normalizing Collector Path ...
|
||||||
|
if (IsValid(value))
|
||||||
|
{
|
||||||
|
mPath = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPath = "XCXCAEADataCollector";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string GetFilePath(string fileName)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = "";
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string mPath; // Base Collector Path ...
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,932 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XCXCAEAPOIDrawer ...
|
||||||
|
// Description: Class for XCAEA POI Drawer ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XCAEA POI Drawer"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
||||||
|
#include "../Classes/xcaea.x-poi.detector.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
struct XCAPivotStyle
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Properties ...
|
||||||
|
int width;
|
||||||
|
color clr;
|
||||||
|
ENUM_LINE_STYLE style;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XCAPivotStyle()
|
||||||
|
{
|
||||||
|
Default();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Model ...
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
width = 1;
|
||||||
|
clr = CLR_NONE;
|
||||||
|
style = STYLE_SOLID;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default Props ...
|
||||||
|
void Default()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
width = 1;
|
||||||
|
clr = CLR_NONE;
|
||||||
|
style = STYLE_SOLID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementations ...
|
||||||
|
class XCXCAEAPOIDrawer : public XCBase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool ignoreUpdateOSCTos;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Drawers ...
|
||||||
|
bool drawPeakPivots;
|
||||||
|
bool drawValePivots;
|
||||||
|
bool drawFVGBullishPivots;
|
||||||
|
bool drawFVGBearishPivots;
|
||||||
|
bool drawTrendBullishPivots;
|
||||||
|
bool drawTrendBearishPivots;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Styling ...
|
||||||
|
|
||||||
|
//
|
||||||
|
XCAPivotStyle defaultBullishStyle;
|
||||||
|
XCAPivotStyle defaultBearishStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCAPivotStyle peakPivotStyle;
|
||||||
|
XCAPivotStyle valePivotStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCAPivotStyle fvgBullishPivotStyle;
|
||||||
|
XCAPivotStyle fvgBearishPivotStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCAPivotStyle trendBullishPivotStyle;
|
||||||
|
XCAPivotStyle trendBearishPivotStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructors ...
|
||||||
|
XCXCAEAPOIDrawer(
|
||||||
|
XCXCAEAPOIDetector *_detector //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
detector = _detector;
|
||||||
|
drawer = new XCPOIDrawer();
|
||||||
|
|
||||||
|
//
|
||||||
|
Default();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// De Constructors ...
|
||||||
|
~XCXCAEAPOIDrawer()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(drawer);
|
||||||
|
ZeroMemory(detector);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Properties ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
//
|
||||||
|
virtual void Default()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Drawing ...
|
||||||
|
drawPeakPivots = false;
|
||||||
|
drawValePivots = false;
|
||||||
|
drawFVGBullishPivots = false;
|
||||||
|
drawFVGBearishPivots = false;
|
||||||
|
drawTrendBullishPivots = false;
|
||||||
|
drawTrendBearishPivots = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Styling ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish ...
|
||||||
|
defaultBullishStyle.width = 1;
|
||||||
|
defaultBullishStyle.clr = clrLime;
|
||||||
|
defaultBullishStyle.style = STYLE_SOLID;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish ...
|
||||||
|
defaultBearishStyle.width = 1;
|
||||||
|
defaultBearishStyle.clr = clrRed;
|
||||||
|
defaultBearishStyle.style = STYLE_SOLID;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pivots ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// PV ...
|
||||||
|
peakPivotStyle = defaultBearishStyle;
|
||||||
|
valePivotStyle = defaultBullishStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FVG ...
|
||||||
|
fvgBullishPivotStyle = defaultBullishStyle;
|
||||||
|
fvgBearishPivotStyle = defaultBearishStyle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TREND ...
|
||||||
|
trendBullishPivotStyle = defaultBullishStyle;
|
||||||
|
trendBearishPivotStyle = defaultBearishStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void Draw(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// PV ...
|
||||||
|
DrawPeakPivots(to);
|
||||||
|
DrawValePivots(to);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FVG ...
|
||||||
|
DrawFVGBullishPivots(to);
|
||||||
|
DrawFVGBearishPivots(to);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TREND ...
|
||||||
|
DrawTrendBullishPivots(to);
|
||||||
|
DrawTrendBearishPivots(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawBox(
|
||||||
|
XBoxZone &box,
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = box.IsValid();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Detect Pivot Type ...
|
||||||
|
ENUM_XCA_PIVOTS iType = GetPivotType(box);
|
||||||
|
has = IsValid(iType);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
switch (iType)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
case XCA_PEAK:
|
||||||
|
//
|
||||||
|
DrawPeakPivot(
|
||||||
|
box,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case XCA_VALE:
|
||||||
|
//
|
||||||
|
DrawValePivot(
|
||||||
|
box,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case XCA_FVG_BULL:
|
||||||
|
//
|
||||||
|
DrawFVGBullishPivot(
|
||||||
|
box,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case XCA_FVG_BEAR:
|
||||||
|
//
|
||||||
|
DrawFVGBearishPivot(
|
||||||
|
box,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case XCA_TREND_BULL:
|
||||||
|
//
|
||||||
|
DrawTrendBullishPivot(
|
||||||
|
box,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
case XCA_TREND_BEAR:
|
||||||
|
//
|
||||||
|
DrawTrendBearishPivot(
|
||||||
|
box,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawBoxes(
|
||||||
|
XBoxZone &boxes[],
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = HasChild(boxes);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(boxes);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = boxes[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Pivot Type ...
|
||||||
|
DrawBox(
|
||||||
|
iBox,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Cleanup Models ...
|
||||||
|
defaultBullishStyle.Clean();
|
||||||
|
defaultBearishStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Styles ...
|
||||||
|
peakPivotStyle.Clean();
|
||||||
|
valePivotStyle.Clean();
|
||||||
|
fvgBullishPivotStyle.Clean();
|
||||||
|
fvgBearishPivotStyle.Clean();
|
||||||
|
trendBullishPivotStyle.Clean();
|
||||||
|
trendBearishPivotStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Pivot Objects Holder ...
|
||||||
|
mPeakPivotObjects.Clear();
|
||||||
|
mValePivotObjects.Clear();
|
||||||
|
mFVGBullishPivotObjects.Clear();
|
||||||
|
mFVGBearishPivotObjects.Clear();
|
||||||
|
mTrendBullishPivotObjects.Clear();
|
||||||
|
mTrendBearishPivotObjects.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Collection Drawers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawPeakPivots(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawPeakPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = detector.HasPeakPivots();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = detector.CountPeakPivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = detector.peakPivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
DrawPeakPivot(
|
||||||
|
iBox,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawValePivots(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawValePivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = detector.HasValePivots();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = detector.CountValePivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = detector.valePivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
DrawValePivot(
|
||||||
|
iBox,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawFVGBullishPivots(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawFVGBullishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = detector.HasFVGBullishPivots();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = detector.CountFVGBullishPivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = detector.fvgBullishPivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
DrawFVGBullishPivot(
|
||||||
|
iBox,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawFVGBearishPivots(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawFVGBearishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = detector.HasFVGBearishPivots();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = detector.CountFVGBearishPivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = detector.fvgBearishPivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
DrawFVGBearishPivot(
|
||||||
|
iBox,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawTrendBullishPivots(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawTrendBullishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = detector.HasTrendBullishPivots();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = detector.CountTrendBullishPivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = detector.trendBullishPivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
DrawTrendBullishPivot(
|
||||||
|
iBox,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawTrendBearishPivots(datetime to = NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawTrendBearishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = detector.HasTrendBearishPivots();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = detector.CountTrendBearishPivots();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = detector.trendBearishPivots[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
DrawTrendBearishPivot(
|
||||||
|
iBox,
|
||||||
|
to //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// One Item Drawers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawPeakPivot(
|
||||||
|
XBoxZone &item,
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawPeakPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = item.IsValid() &&
|
||||||
|
item.type == GetBoxType(XCA_PEAK) &&
|
||||||
|
item.dir == GetDirection(XCA_PEAK);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canUpdateTo = IsValid(to);
|
||||||
|
if (canUpdateTo)
|
||||||
|
{
|
||||||
|
item.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
has = drawer.DrawBox(
|
||||||
|
item,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Style Object ...
|
||||||
|
ApplyPivotStyle(
|
||||||
|
iObj,
|
||||||
|
peakPivotStyle //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store Object ...
|
||||||
|
mPeakPivotObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawValePivot(
|
||||||
|
XBoxZone &item,
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawValePivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = item.IsValid() &&
|
||||||
|
item.type == GetBoxType(XCA_VALE) &&
|
||||||
|
item.dir == GetDirection(XCA_VALE);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canUpdateTo = IsValid(to);
|
||||||
|
if (canUpdateTo)
|
||||||
|
{
|
||||||
|
item.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
has = drawer.DrawBox(
|
||||||
|
item,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Style Object ...
|
||||||
|
ApplyPivotStyle(
|
||||||
|
iObj,
|
||||||
|
valePivotStyle //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store Object ...
|
||||||
|
mValePivotObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawFVGBullishPivot(
|
||||||
|
XBoxZone &item,
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawFVGBullishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = item.IsValid() &&
|
||||||
|
item.type == GetBoxType(XCA_FVG_BULL) &&
|
||||||
|
item.dir == GetDirection(XCA_FVG_BULL);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canUpdateTo = IsValid(to);
|
||||||
|
if (canUpdateTo)
|
||||||
|
{
|
||||||
|
item.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
has = drawer.DrawBox(
|
||||||
|
item,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Style Object ...
|
||||||
|
ApplyPivotStyle(
|
||||||
|
iObj,
|
||||||
|
fvgBullishPivotStyle //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store Object ...
|
||||||
|
mFVGBullishPivotObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawFVGBearishPivot(
|
||||||
|
XBoxZone &item,
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawFVGBearishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = item.IsValid() &&
|
||||||
|
item.type == GetBoxType(XCA_FVG_BEAR) &&
|
||||||
|
item.dir == GetDirection(XCA_FVG_BEAR);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canUpdateTo = IsValid(to);
|
||||||
|
if (canUpdateTo)
|
||||||
|
{
|
||||||
|
item.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
has = drawer.DrawBox(
|
||||||
|
item,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Style Object ...
|
||||||
|
ApplyPivotStyle(
|
||||||
|
iObj,
|
||||||
|
fvgBearishPivotStyle //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store Object ...
|
||||||
|
mFVGBearishPivotObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawTrendBullishPivot(
|
||||||
|
XBoxZone &item,
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawTrendBullishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = item.IsValid() &&
|
||||||
|
item.type == GetBoxType(XCA_TREND_BULL) &&
|
||||||
|
item.dir == GetDirection(XCA_TREND_BULL);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canUpdateTo = IsValid(to);
|
||||||
|
if (canUpdateTo)
|
||||||
|
{
|
||||||
|
item.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
has = drawer.DrawBox(
|
||||||
|
item,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Style Object ...
|
||||||
|
ApplyPivotStyle(
|
||||||
|
iObj,
|
||||||
|
trendBullishPivotStyle //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store Object ...
|
||||||
|
mTrendBullishPivotObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void DrawTrendBearishPivot(
|
||||||
|
XBoxZone &item,
|
||||||
|
datetime to = NULL //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = drawTrendBearishPivots;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = item.IsValid() &&
|
||||||
|
item.type == GetBoxType(XCA_TREND_BEAR) &&
|
||||||
|
item.dir == GetDirection(XCA_TREND_BEAR);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canUpdateTo = IsValid(to);
|
||||||
|
if (canUpdateTo)
|
||||||
|
{
|
||||||
|
item.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
has = drawer.DrawBox(
|
||||||
|
item,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Style Object ...
|
||||||
|
ApplyPivotStyle(
|
||||||
|
iObj,
|
||||||
|
trendBearishPivotStyle //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store Object ...
|
||||||
|
mTrendBearishPivotObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
void ApplyPivotStyle(
|
||||||
|
XCBoxObject *&object,
|
||||||
|
XCAPivotStyle &style //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (object == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
object.BoxColor(style.clr);
|
||||||
|
object.BoxWidth(style.width);
|
||||||
|
object.BoxStyle(style.style);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prrivate ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
XCPOIDrawer *drawer;
|
||||||
|
XCXCAEAPOIDetector *detector;
|
||||||
|
|
||||||
|
//
|
||||||
|
CArrayObj mPeakPivotObjects;
|
||||||
|
CArrayObj mValePivotObjects;
|
||||||
|
|
||||||
|
//
|
||||||
|
CArrayObj mFVGBullishPivotObjects;
|
||||||
|
CArrayObj mFVGBearishPivotObjects;
|
||||||
|
|
||||||
|
//
|
||||||
|
CArrayObj mTrendBullishPivotObjects;
|
||||||
|
CArrayObj mTrendBearishPivotObjects;
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,900 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XCXCAEASignaller ...
|
||||||
|
// Description: Class for XCAEA Signaller ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XCAEA Signaller"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../../Classes/x-saherelm.base.class.mq5"
|
||||||
|
#include "../../Classes/x-saherelm.x-cobject.class.mq5"
|
||||||
|
#include "../Classes/xcaea.x-poi.detector.class.mq5"
|
||||||
|
#include "../Classes/xcaea.x-poi.drawer.class.mq5"
|
||||||
|
#include "../Helpers/xcaea.helper.mq5"
|
||||||
|
#include "../Libraries/xcaea.signaller.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
class XCXCAEASignaller : XCBase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
bool useGuards;
|
||||||
|
bool useTargets;
|
||||||
|
int poiLoopback;
|
||||||
|
XCAEAInputs inputs;
|
||||||
|
XBarTracker barTraker;
|
||||||
|
XCXCAEAHelper *helper;
|
||||||
|
XCXCAEAPOIDrawer *drawer;
|
||||||
|
bool continuesRFTillTarget;
|
||||||
|
XBoxZone unAvailableBoxes[];
|
||||||
|
XCXCAEAPOIDetector *detector;
|
||||||
|
XCAEAStrategyConditions mConditions;
|
||||||
|
XCAEAStrategyConditions mConditionsCollection[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
XCXCAEASignaller(
|
||||||
|
string _symbol,
|
||||||
|
ENUM_TIMEFRAMES _period //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
symbol = _symbol;
|
||||||
|
period = _period;
|
||||||
|
|
||||||
|
//
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCXCAEASignaller()
|
||||||
|
{
|
||||||
|
DeInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Properties ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize ...
|
||||||
|
*/
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
useGuards = false;
|
||||||
|
useTargets = true;
|
||||||
|
continuesRFTillTarget = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
barTraker.Init(
|
||||||
|
symbol,
|
||||||
|
period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.Default();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Indicators ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCC ...
|
||||||
|
inputs.ccInputs.showCandles = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCT ...
|
||||||
|
inputs.ctInputs.showCandleTime = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCA ...
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.caInputs.supResSmoothingLength = 7;
|
||||||
|
inputs.caInputs.supResSmoothingMode = X_MA_MODE_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.x3maInputs.applyColor = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.x3maInputs.fastLength = 5;
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.x3maInputs.showFast = false;
|
||||||
|
inputs.x3maInputs.showSlow = false;
|
||||||
|
inputs.x3maInputs.showMedium = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.caInputs.showMAH = false;
|
||||||
|
inputs.caInputs.showMAL = false;
|
||||||
|
inputs.caInputs.showMAC = false;
|
||||||
|
inputs.caInputs.showSar = false;
|
||||||
|
inputs.caInputs.showSwings = true;
|
||||||
|
inputs.caInputs.showFiboLevel1 = false;
|
||||||
|
inputs.caInputs.showFiboLevel2 = false;
|
||||||
|
inputs.caInputs.showFiboLevel3 = false;
|
||||||
|
inputs.caInputs.showFiboLevel4 = false;
|
||||||
|
inputs.caInputs.showFiboLevel5 = false;
|
||||||
|
inputs.caInputs.showPeaksAndVales = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
inputs.caInputs.showKI = false;
|
||||||
|
inputs.caInputs.showTKI = false;
|
||||||
|
inputs.caInputs.showVidya = false;
|
||||||
|
inputs.caInputs.showTrend = false;
|
||||||
|
inputs.caInputs.showPeakAndValeGolden = false;
|
||||||
|
inputs.caInputs.showSupportAndResistance = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XOSCS ...
|
||||||
|
// inputs.oscsInputs.rsiLength = 5;
|
||||||
|
// inputs.oscsInputs.rsiOBLevel = 90;
|
||||||
|
// inputs.oscsInputs.rsiOSLevel = 10;
|
||||||
|
// inputs.oscsInputs.cciLength = 7;
|
||||||
|
// inputs.oscsInputs.cciOBLevel = 130;
|
||||||
|
// inputs.oscsInputs.cciOSLevel = -130;
|
||||||
|
// inputs.oscsInputs.mfiLength = 5;
|
||||||
|
// inputs.oscsInputs.rviLength = 5;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Oscillators Views ...
|
||||||
|
inputs.showRSI = false;
|
||||||
|
inputs.showCCI = false;
|
||||||
|
inputs.showMFI = false;
|
||||||
|
inputs.showRVI = false;
|
||||||
|
inputs.showADX = false;
|
||||||
|
inputs.showMACD = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCAEA Helper ...
|
||||||
|
helper = new XCXCAEAHelper();
|
||||||
|
helper.Init(
|
||||||
|
symbol,
|
||||||
|
period,
|
||||||
|
inputs //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize and Configure Detector ...
|
||||||
|
detector = new XCXCAEAPOIDetector(helper);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common Configurations ...
|
||||||
|
detector.maxAllowedPivots = 0;
|
||||||
|
detector.pivotVerifications = 5;
|
||||||
|
detector.ticksDividerInPoints = 15;
|
||||||
|
detector.pivotDetectionLoopbac = 1000;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Detector ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// PV ...
|
||||||
|
|
||||||
|
//
|
||||||
|
detector.maxAllowedPVLifetime = 0;
|
||||||
|
detector.applySwingsOnPVPivots = true;
|
||||||
|
detector.selectRejectedPVPivots = true;
|
||||||
|
detector.selectEngulfedPVPivots = true;
|
||||||
|
detector.applySupportAndResistanceOnPVPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// PEAK ...
|
||||||
|
detector.detectPeakPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// VALE ...
|
||||||
|
detector.detectValePivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FVG ...
|
||||||
|
|
||||||
|
//
|
||||||
|
detector.selectSameBarFVGs = false;
|
||||||
|
detector.maxAllowedFVGLifetime = 0;
|
||||||
|
detector.validateFVGUsingPV = false;
|
||||||
|
detector.applyPVToFVGBoundary = false;
|
||||||
|
detector.selectRejectedFVGPivots = false;
|
||||||
|
detector.selectEngulfedFVGPivots = false;
|
||||||
|
detector.validateFVGUsingManalyser = true;
|
||||||
|
detector.applyLastBarToFVGBoundary = false;
|
||||||
|
detector.selectOnlyFVGWhichHasIndirectionalLastBar = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish ...
|
||||||
|
detector.detectFVGBullishPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish ...
|
||||||
|
detector.detectFVGBearishPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TREND ...
|
||||||
|
|
||||||
|
//
|
||||||
|
detector.maxAllowedTrendLifetime = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish ...
|
||||||
|
detector.detectTrendBullishPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish ...
|
||||||
|
detector.detectTrendBearishPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// DRAWER ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize and Configure Drawer ...
|
||||||
|
drawer = new XCXCAEAPOIDrawer(detector);
|
||||||
|
|
||||||
|
//
|
||||||
|
drawer.ignoreUpdateOSCTos = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Drawer ...
|
||||||
|
drawer.drawPeakPivots = true;
|
||||||
|
drawer.drawValePivots = true;
|
||||||
|
drawer.drawFVGBullishPivots = true;
|
||||||
|
drawer.drawFVGBearishPivots = true;
|
||||||
|
drawer.drawTrendBullishPivots = true;
|
||||||
|
drawer.drawTrendBearishPivots = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Styles ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// PV ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// PEAK ...
|
||||||
|
XCAPivotStyle peakStyle;
|
||||||
|
peakStyle.width = 2;
|
||||||
|
peakStyle.clr = clrMagenta;
|
||||||
|
peakStyle.style = STYLE_SOLID;
|
||||||
|
drawer.peakPivotStyle = peakStyle;
|
||||||
|
peakStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// VALE ...
|
||||||
|
XCAPivotStyle valeStyle;
|
||||||
|
valeStyle.width = 2;
|
||||||
|
valeStyle.clr = clrAqua;
|
||||||
|
valeStyle.style = STYLE_SOLID;
|
||||||
|
drawer.valePivotStyle = valeStyle;
|
||||||
|
valeStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// FVG ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish ...
|
||||||
|
XCAPivotStyle fvgBullishStyle;
|
||||||
|
fvgBullishStyle.width = 2;
|
||||||
|
fvgBullishStyle.clr = clrLime;
|
||||||
|
fvgBullishStyle.style = STYLE_DASH;
|
||||||
|
drawer.fvgBullishPivotStyle = fvgBullishStyle;
|
||||||
|
fvgBullishStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish ...
|
||||||
|
XCAPivotStyle fvgBearishStyle;
|
||||||
|
fvgBearishStyle.width = 2;
|
||||||
|
fvgBearishStyle.clr = clrRed;
|
||||||
|
fvgBearishStyle.style = STYLE_DASH;
|
||||||
|
drawer.fvgBearishPivotStyle = fvgBearishStyle;
|
||||||
|
fvgBearishStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// TREND ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish ...
|
||||||
|
XCAPivotStyle trendBullishStyle;
|
||||||
|
trendBullishStyle.width = 2;
|
||||||
|
trendBullishStyle.clr = clrLime;
|
||||||
|
trendBullishStyle.style = STYLE_DOT;
|
||||||
|
drawer.trendBullishPivotStyle = trendBullishStyle;
|
||||||
|
trendBullishStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish ...
|
||||||
|
XCAPivotStyle trendBearishStyle;
|
||||||
|
trendBearishStyle.width = 2;
|
||||||
|
trendBearishStyle.clr = clrRed;
|
||||||
|
trendBearishStyle.style = STYLE_DOT;
|
||||||
|
drawer.trendBearishPivotStyle = trendBearishStyle;
|
||||||
|
trendBearishStyle.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DeInitialize ...
|
||||||
|
*/
|
||||||
|
void DeInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
inputs.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleaning Draws ...
|
||||||
|
drawer.Clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(drawer);
|
||||||
|
ZeroMemory(helper);
|
||||||
|
ZeroMemory(detector);
|
||||||
|
|
||||||
|
//
|
||||||
|
mConditions.Clean();
|
||||||
|
Clean(mConditionsCollection);
|
||||||
|
|
||||||
|
//
|
||||||
|
mObjects.Clear();
|
||||||
|
mBarObjects.Clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
barTraker.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
string GetSymbol()
|
||||||
|
{
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_TIMEFRAMES GetPeriod()
|
||||||
|
{
|
||||||
|
return period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signaller Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Setup Conditions based on Signalling ...
|
||||||
|
*
|
||||||
|
* @param maxAllowedSLDistanceInPoint: int, Max Allowed SL Distance in Points (if Bigger thn Zero Provided) ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectSignalSetup(
|
||||||
|
double tpReward = 3,
|
||||||
|
double maxAllowedSLDistanceInPoint = 100 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bar Processing ...
|
||||||
|
if (!barTraker.CanProcessBar())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = false;
|
||||||
|
bool isBearish = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIndex = 0;
|
||||||
|
int cIndex = zIndex + 1;
|
||||||
|
int pIndex = cIndex + 1;
|
||||||
|
int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
int loopback = 10;
|
||||||
|
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
double ask = GetAsk(symbol);
|
||||||
|
double bid = GetBid(symbol);
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
XOHCL cBar;
|
||||||
|
XOHCL pBar;
|
||||||
|
XOHCL pPBar;
|
||||||
|
result = zBar.Init(
|
||||||
|
symbol,
|
||||||
|
period,
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
zBar.GetPreviousBar(cBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
cBar.GetPreviousBar(pBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
pBar.GetPreviousBar(pPBar);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
pPBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup Conditions ...
|
||||||
|
XBoxZone decisionZone;
|
||||||
|
bool hasDecisionZone = false;
|
||||||
|
XCAEAConditions conditions;
|
||||||
|
ENUM_X_DIRECTION decisionZoneDir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Signal's Decision Zone ...
|
||||||
|
hasDecisionZone = DetectDecisionZone(
|
||||||
|
helper,
|
||||||
|
drawer,
|
||||||
|
decisionZone,
|
||||||
|
decisionZoneDir,
|
||||||
|
conditions,
|
||||||
|
zIndex,
|
||||||
|
loopback //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make Signal Box UnAvailable ...
|
||||||
|
if (hasDecisionZone)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
decisionZone,
|
||||||
|
unAvailableBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
isBullish = hasDecisionZone &&
|
||||||
|
IsBullish(decisionZoneDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
isBearish = hasDecisionZone &&
|
||||||
|
IsBearish(decisionZoneDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Do What we Want ...
|
||||||
|
barTraker.Waits();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Conditions ...
|
||||||
|
mConditions.symbol = symbol;
|
||||||
|
mConditions.period = period;
|
||||||
|
mConditions.time = zBar.time;
|
||||||
|
mConditions.reward = tpReward;
|
||||||
|
mConditions.provider = "XCAEA";
|
||||||
|
mConditions.setupTime = zBar.time;
|
||||||
|
mConditions.dir = decisionZoneDir;
|
||||||
|
mConditions.conditions = conditions;
|
||||||
|
mConditions.decisionZone = decisionZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resource ...
|
||||||
|
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
pPBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
conditions.Clean();
|
||||||
|
decisionZone.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Trigger Conditions for Specified Signal ...
|
||||||
|
*
|
||||||
|
* @param conditions: XCAEAStrategyConditions instance Reference, Specified Signal Conditions ...
|
||||||
|
* @param maxAllowedSetupAge: specified Setup Age for Expiration (if bigger than Zero) ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectSignalTrigger(
|
||||||
|
XCAEAStrategyConditions &conditions,
|
||||||
|
int barIndex = 0,
|
||||||
|
int maxAllowedSetupAge = 200 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
barIndex = NormalizeInt(barIndex, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = conditions.IsSetuped();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
datetime setupTime = conditions.setupTime;
|
||||||
|
ENUM_X_DIRECTION setupDir = conditions.dir;
|
||||||
|
|
||||||
|
//
|
||||||
|
helper.GetConditions(
|
||||||
|
conditions.conditions,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = IsBullish(setupDir);
|
||||||
|
bool isBearish = IsBearish(setupDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIndex = 0;
|
||||||
|
int cIndex = zIndex + 1;
|
||||||
|
int pIndex = cIndex + 1;
|
||||||
|
int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
int loopback = 10;
|
||||||
|
|
||||||
|
//
|
||||||
|
double ask = GetAsk(symbol);
|
||||||
|
double bid = GetBid(symbol);
|
||||||
|
datetime cTime = TimeCurrent();
|
||||||
|
double points = GetPoints(symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Signal Validation ...
|
||||||
|
// IMPORTANT: since all Validations done in SetUp Process ...
|
||||||
|
// here we only Execute Signal ...
|
||||||
|
|
||||||
|
//
|
||||||
|
result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Trigger Conditions ...
|
||||||
|
double sl = 0;
|
||||||
|
double tp = 0;
|
||||||
|
ENUM_X_DIRECTION triggerDir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Trigger Cond 0 ...
|
||||||
|
bool canTriggerCond0 = CanTriggerCond0(
|
||||||
|
helper,
|
||||||
|
conditions.decisionZone,
|
||||||
|
triggerDir,
|
||||||
|
sl,
|
||||||
|
tp,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Trigger Cond 1 ...
|
||||||
|
bool canTriggerCond1 = false;
|
||||||
|
// CanTriggerCond1(
|
||||||
|
// helper,
|
||||||
|
// conditions.decisionZone,
|
||||||
|
// triggerDir,
|
||||||
|
// sl,
|
||||||
|
// tp,
|
||||||
|
// barIndex //
|
||||||
|
// );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Trigger Cond 2 ...
|
||||||
|
bool canTriggerCond2 = false;
|
||||||
|
// CanTriggerCond2(
|
||||||
|
// helper,
|
||||||
|
// conditions.decisionZone,
|
||||||
|
// triggerDir,
|
||||||
|
// sl,
|
||||||
|
// tp,
|
||||||
|
// barIndex //
|
||||||
|
// );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update Signal Box To ...
|
||||||
|
conditions.decisionZone.to = cTime;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
bool has = helper.poiDrawer.DrawBox(
|
||||||
|
conditions.decisionZone,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
mObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
ZeroMemory(iObj);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Summarizing Result ...
|
||||||
|
result =
|
||||||
|
canTriggerCond0 ||
|
||||||
|
canTriggerCond1 ||
|
||||||
|
canTriggerCond2;
|
||||||
|
|
||||||
|
//
|
||||||
|
isBullish = result &&
|
||||||
|
IsBullish(triggerDir);
|
||||||
|
isBearish = result &&
|
||||||
|
IsBearish(triggerDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Conditions for Preparing Signal ...
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Reconfigure Position TP/SL Entry and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double entry = GetEntry(
|
||||||
|
conditions.symbol,
|
||||||
|
triggerDir //
|
||||||
|
);
|
||||||
|
conditions.entry = entry;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (tp > 0.0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
tp,
|
||||||
|
conditions.targets //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double spred = GetSpread(conditions.symbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
double risk = MathAbs(entry - sl) + spred;
|
||||||
|
double reward = (risk * conditions.reward);
|
||||||
|
tp =
|
||||||
|
isBullish
|
||||||
|
? entry + reward
|
||||||
|
: entry - reward;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handling RF ...
|
||||||
|
double rfReward = risk * 1.85;
|
||||||
|
double rfPrice =
|
||||||
|
isBullish
|
||||||
|
? entry + rfReward
|
||||||
|
: entry - rfReward;
|
||||||
|
Add(
|
||||||
|
rfPrice,
|
||||||
|
conditions.targets //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
rfReward = risk * 2.85;
|
||||||
|
rfPrice =
|
||||||
|
isBullish
|
||||||
|
? entry + rfReward
|
||||||
|
: entry - rfReward;
|
||||||
|
Add(
|
||||||
|
rfPrice,
|
||||||
|
conditions.targets //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handling Partial Close ...
|
||||||
|
// conditions.partialCloseOnTPLevel = 1;
|
||||||
|
// conditions.partialCloseMultiplier = 0.5;
|
||||||
|
|
||||||
|
//
|
||||||
|
conditions.sl = sl;
|
||||||
|
conditions.tp = tp;
|
||||||
|
conditions.dir = triggerDir;
|
||||||
|
conditions.triggerTime = cTime;
|
||||||
|
conditions.type = isBullish
|
||||||
|
? X_POSITION_TYPE_LONG
|
||||||
|
: X_POSITION_TYPE_SHORT;
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validating Conditions if not Triggered ...
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Check Box Age ...
|
||||||
|
int age = conditions.GetSetupAge();
|
||||||
|
bool has = age <= maxAllowedSetupAge;
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
conditions.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Box Price ...
|
||||||
|
has = IsBoxBreaked(
|
||||||
|
helper,
|
||||||
|
conditions.decisionZone,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
conditions.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Guards bsed on Signalling Class ...
|
||||||
|
*
|
||||||
|
* @param guards: XCAEAGuard instance Collection, Holds Provided Guards ...
|
||||||
|
* @param positions: XPosition instance Collection, Provides Signalling Based Positions for Apply Guards on them ...
|
||||||
|
* @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectGuards(
|
||||||
|
XCAEAGuard &guards[],
|
||||||
|
const XPosition &positions[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Conditions to Conditions Collection if not Exists ...
|
||||||
|
*
|
||||||
|
* @param maxAllowed: int, Specified Max Allowed Holding Conditions ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int AddConditionsIfNotExists(
|
||||||
|
int maxAllowed = 10 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isSetuped = IsValid(mConditions.setupTime) &&
|
||||||
|
HasDirection(mConditions.dir);
|
||||||
|
if (!isSetuped)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(mConditionsCollection);
|
||||||
|
if (IsValidSize(count))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Copy Original Items ...
|
||||||
|
XCAEAStrategyConditions tmpItems[];
|
||||||
|
Copy(
|
||||||
|
mConditionsCollection,
|
||||||
|
tmpItems //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prese Item Data ...
|
||||||
|
bool isBullish = IsBullish(mConditions.dir);
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCAEAStrategyConditions iItem = tmpItems[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canRemove = mConditions.dir == iItem.dir &&
|
||||||
|
mConditions.pivot == iItem.pivot;
|
||||||
|
if (canRemove)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArrayRemove(
|
||||||
|
mConditionsCollection,
|
||||||
|
i,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(tmpItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
mConditions,
|
||||||
|
mConditionsCollection //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove Olds ...
|
||||||
|
CleanupArray(
|
||||||
|
mConditionsCollection,
|
||||||
|
maxAllowed //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(mConditionsCollection);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
string symbol;
|
||||||
|
ENUM_TIMEFRAMES period;
|
||||||
|
CArrayObj mObjects;
|
||||||
|
CArrayObj mBarObjects;
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,647 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center XCond2 MQL5 Script
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: XCAEA
|
||||||
|
// Description: an Exper Advisor which used Panels
|
||||||
|
//
|
||||||
|
// Maintainer:
|
||||||
|
// ------------
|
||||||
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Global Properties ...
|
||||||
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
||||||
|
#property link "https://saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "SaherElm XCAEA Cond2 Script"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Classes ...
|
||||||
|
#include "../../Classes/x-saherelm.x-poi.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Libraries ...
|
||||||
|
#include "../../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helpers ...
|
||||||
|
#include "../Helpers/xcaea.helper.mq5";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Holds Drawn Objects ...
|
||||||
|
CArrayObj mObjects;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Required Objects ...
|
||||||
|
int mLoopback = 10;
|
||||||
|
XCAEAInputs mInputs;
|
||||||
|
XBarTracker mBarTracker;
|
||||||
|
XCAEAConditions mConditions;
|
||||||
|
XCXCAEAHelper *helper = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Script ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Initialize Helper ...
|
||||||
|
bool isInited = InitHelper();
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De Initialize Script ...
|
||||||
|
*
|
||||||
|
* @param reason: Argument 1
|
||||||
|
*/
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mInputs.Clean();
|
||||||
|
mConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Tick Event ...
|
||||||
|
*/
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Run on New Bar ...
|
||||||
|
bool isNewBar = mBarTracker.IsNewBar();
|
||||||
|
if (!isNewBar)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setting Bar Index ...
|
||||||
|
int barIndex = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Conditions ...
|
||||||
|
has = helper.GetConditions(
|
||||||
|
mConditions,
|
||||||
|
barIndex,
|
||||||
|
mLoopback //
|
||||||
|
);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handling Logic ...
|
||||||
|
HandleLogic();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Helper ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool InitHelper()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
mInputs.Default();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Oscilators ...
|
||||||
|
mInputs.showAC = false;
|
||||||
|
mInputs.showAD = false;
|
||||||
|
mInputs.showADX = false;
|
||||||
|
mInputs.showATR = false;
|
||||||
|
mInputs.showCCI = false;
|
||||||
|
mInputs.showRSI = false;
|
||||||
|
mInputs.showMFI = false;
|
||||||
|
mInputs.showRVI = false;
|
||||||
|
mInputs.showMACD = false;
|
||||||
|
mInputs.showMomentum = false;
|
||||||
|
mInputs.showStochastic = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCT ...
|
||||||
|
mInputs.ctInputs.showCandleTime = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCC ...
|
||||||
|
mInputs.ccInputs.showCandles = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// X3MA ...
|
||||||
|
mInputs.x3maInputs.showFast = false;
|
||||||
|
mInputs.x3maInputs.showSlow = false;
|
||||||
|
mInputs.x3maInputs.showMedium = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XOSC ...
|
||||||
|
// mInputs.oscsInputs;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XCA ...
|
||||||
|
mInputs.caInputs.showKI = false;
|
||||||
|
mInputs.caInputs.showSar = false;
|
||||||
|
mInputs.caInputs.showTKI = false;
|
||||||
|
mInputs.caInputs.showMAH = true;
|
||||||
|
mInputs.caInputs.showMAL = true;
|
||||||
|
mInputs.caInputs.showMAC = true;
|
||||||
|
mInputs.caInputs.showVidya = false;
|
||||||
|
mInputs.caInputs.showTrend = false;
|
||||||
|
mInputs.caInputs.showSwings = false;
|
||||||
|
mInputs.caInputs.showLongCycle = false;
|
||||||
|
mInputs.caInputs.showHindCycle = false;
|
||||||
|
mInputs.caInputs.showShortCycle = false;
|
||||||
|
mInputs.caInputs.showFiboLevel1 = true;
|
||||||
|
mInputs.caInputs.showFiboLevel2 = false;
|
||||||
|
mInputs.caInputs.showFiboLevel3 = true;
|
||||||
|
mInputs.caInputs.showMediumCycle = false;
|
||||||
|
mInputs.caInputs.showPeaksAndVales = false;
|
||||||
|
mInputs.caInputs.showPeakAndValeGolden = false;
|
||||||
|
mInputs.caInputs.showSupportAndResistance = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Helper ...
|
||||||
|
helper = new XCXCAEAHelper();
|
||||||
|
result = helper.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
mInputs //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Bar Tracker ...
|
||||||
|
result = mBarTracker.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Logic of Script ...
|
||||||
|
*/
|
||||||
|
void HandleLogic()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Defining Requirements ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIDX = 0;
|
||||||
|
int cIDX = zIDX + 1;
|
||||||
|
int pIDX = cIDX + 1;
|
||||||
|
int p2IDX = pIDX + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reading Required Values ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// PEAK ...
|
||||||
|
double zPeak = mConditions.peakBuffer[zIDX];
|
||||||
|
double cPeak = mConditions.peakBuffer[cIDX];
|
||||||
|
double pPeak = mConditions.peakBuffer[pIDX];
|
||||||
|
double p2Peak = mConditions.peakBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// VALE ...
|
||||||
|
double zVale = mConditions.valeBuffer[zIDX];
|
||||||
|
double cVale = mConditions.valeBuffer[cIDX];
|
||||||
|
double pVale = mConditions.valeBuffer[pIDX];
|
||||||
|
double p2Vale = mConditions.valeBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// SAR ...
|
||||||
|
double zSar = mConditions.sarBuffer[zIDX];
|
||||||
|
double cSar = mConditions.sarBuffer[cIDX];
|
||||||
|
double pSar = mConditions.sarBuffer[pIDX];
|
||||||
|
double p2Sar = mConditions.sarBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// KI ...
|
||||||
|
double zKI = mConditions.kiBuffer[zIDX];
|
||||||
|
double cKI = mConditions.kiBuffer[cIDX];
|
||||||
|
double pKI = mConditions.kiBuffer[pIDX];
|
||||||
|
double p2KI = mConditions.kiBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// KI State ...
|
||||||
|
double zKIState = mConditions.kiStateBuffer[zIDX];
|
||||||
|
double cKIState = mConditions.kiStateBuffer[cIDX];
|
||||||
|
double pKIState = mConditions.kiStateBuffer[pIDX];
|
||||||
|
double p2KIState = mConditions.kiStateBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// TKI ...
|
||||||
|
double zTKI = mConditions.tkiBuffer[zIDX];
|
||||||
|
double cTKI = mConditions.tkiBuffer[cIDX];
|
||||||
|
double pTKI = mConditions.tkiBuffer[pIDX];
|
||||||
|
double p2TKI = mConditions.tkiBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// TKI State ...
|
||||||
|
double zTKIState = mConditions.tkiStateBuffer[zIDX];
|
||||||
|
double cTKIState = mConditions.tkiStateBuffer[cIDX];
|
||||||
|
double pTKIState = mConditions.tkiStateBuffer[pIDX];
|
||||||
|
double p2TKIState = mConditions.tkiStateBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAH ...
|
||||||
|
double zMAH = mConditions.mahBuffer[zIDX];
|
||||||
|
double cMAH = mConditions.mahBuffer[cIDX];
|
||||||
|
double pMAH = mConditions.mahBuffer[pIDX];
|
||||||
|
double p2MAH = mConditions.mahBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAL ...
|
||||||
|
double zMAL = mConditions.malBuffer[zIDX];
|
||||||
|
double cMAL = mConditions.malBuffer[cIDX];
|
||||||
|
double pMAL = mConditions.malBuffer[pIDX];
|
||||||
|
double p2MAL = mConditions.malBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// MAC ...
|
||||||
|
double zMAC = mConditions.macBuffer[zIDX];
|
||||||
|
double cMAC = mConditions.macBuffer[cIDX];
|
||||||
|
double pMAC = mConditions.macBuffer[pIDX];
|
||||||
|
double p2MAC = mConditions.macBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// TREND ...
|
||||||
|
double zTrend = mConditions.trendBuffer[zIDX];
|
||||||
|
double cTrend = mConditions.trendBuffer[cIDX];
|
||||||
|
double pTrend = mConditions.trendBuffer[pIDX];
|
||||||
|
double p2Trend = mConditions.trendBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// TREND State ...
|
||||||
|
double zTrendState = mConditions.trendStateBuffer[zIDX];
|
||||||
|
double cTrendState = mConditions.trendStateBuffer[cIDX];
|
||||||
|
double pTrendState = mConditions.trendStateBuffer[pIDX];
|
||||||
|
double p2TrendState = mConditions.trendStateBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// RESISTANCE ...
|
||||||
|
double zResistance = mConditions.resistanceBuffer[zIDX];
|
||||||
|
double cResistance = mConditions.resistanceBuffer[cIDX];
|
||||||
|
double pResistance = mConditions.resistanceBuffer[pIDX];
|
||||||
|
double p2Resistance = mConditions.resistanceBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// SUPPORT ...
|
||||||
|
double zSupport = mConditions.supportBuffer[zIDX];
|
||||||
|
double cSupport = mConditions.supportBuffer[cIDX];
|
||||||
|
double pSupport = mConditions.supportBuffer[pIDX];
|
||||||
|
double p2Support = mConditions.supportBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// VIDYA ...
|
||||||
|
double zVIDYA = mConditions.vidyaBuffer[zIDX];
|
||||||
|
double cVIDYA = mConditions.vidyaBuffer[cIDX];
|
||||||
|
double pVIDYA = mConditions.vidyaBuffer[pIDX];
|
||||||
|
double p2VIDYA = mConditions.vidyaBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// VIDYA State ...
|
||||||
|
double zVIDYAState = mConditions.vidyaStateBuffer[zIDX];
|
||||||
|
double cVIDYAState = mConditions.vidyaStateBuffer[cIDX];
|
||||||
|
double pVIDYAState = mConditions.vidyaStateBuffer[pIDX];
|
||||||
|
double p2VIDYAState = mConditions.vidyaStateBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWING Low ...
|
||||||
|
double zSwingLow = mConditions.swingLowBuffer[zIDX];
|
||||||
|
double cSwingLow = mConditions.swingLowBuffer[cIDX];
|
||||||
|
double pSwingLow = mConditions.swingLowBuffer[pIDX];
|
||||||
|
double p2SwingLow = mConditions.swingLowBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// SWING High ...
|
||||||
|
double zSwingHigh = mConditions.swingHighBuffer[zIDX];
|
||||||
|
double cSwingHigh = mConditions.swingHighBuffer[cIDX];
|
||||||
|
double pSwingHigh = mConditions.swingHighBuffer[pIDX];
|
||||||
|
double p2SwingHigh = mConditions.swingHighBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIBO Level 1 ...
|
||||||
|
double zFiboLevel1 = mConditions.fiboLevel1Buffer[zIDX];
|
||||||
|
double cFiboLevel1 = mConditions.fiboLevel1Buffer[cIDX];
|
||||||
|
double pFiboLevel1 = mConditions.fiboLevel1Buffer[pIDX];
|
||||||
|
double p2FiboLevel1 = mConditions.fiboLevel1Buffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIBO Level 2 ...
|
||||||
|
double zFiboLevel2 = mConditions.fiboLevel2Buffer[zIDX];
|
||||||
|
double cFiboLevel2 = mConditions.fiboLevel2Buffer[cIDX];
|
||||||
|
double pFiboLevel2 = mConditions.fiboLevel2Buffer[pIDX];
|
||||||
|
double p2FiboLevel2 = mConditions.fiboLevel2Buffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIBO Level 3 ...
|
||||||
|
double zFiboLevel3 = mConditions.fiboLevel3Buffer[zIDX];
|
||||||
|
double cFiboLevel3 = mConditions.fiboLevel3Buffer[cIDX];
|
||||||
|
double pFiboLevel3 = mConditions.fiboLevel3Buffer[pIDX];
|
||||||
|
double p2FiboLevel3 = mConditions.fiboLevel3Buffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// X3MA ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double z3MAFast = mConditions.fastBuffer[zIDX];
|
||||||
|
double c3MAFast = mConditions.fastBuffer[cIDX];
|
||||||
|
double p3MAFast = mConditions.fastBuffer[pIDX];
|
||||||
|
double p23MAFast = mConditions.fastBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
double z3MAFastState = mConditions.fastStateBuffer[zIDX];
|
||||||
|
double c3MAFastState = mConditions.fastStateBuffer[cIDX];
|
||||||
|
double p3MAFastState = mConditions.fastStateBuffer[pIDX];
|
||||||
|
double p23MAFastState = mConditions.fastStateBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEDIUM ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double z3MAMedium = mConditions.mediumBuffer[zIDX];
|
||||||
|
double c3MAMedium = mConditions.mediumBuffer[cIDX];
|
||||||
|
double p3MAMedium = mConditions.mediumBuffer[pIDX];
|
||||||
|
double p23MAMedium = mConditions.mediumBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
double z3MAMediumState = mConditions.mediumStateBuffer[zIDX];
|
||||||
|
double c3MAMediumState = mConditions.mediumStateBuffer[cIDX];
|
||||||
|
double p3MAMediumState = mConditions.mediumStateBuffer[pIDX];
|
||||||
|
double p23MAMediumState = mConditions.mediumStateBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double z3MASlow = mConditions.slowBuffer[zIDX];
|
||||||
|
double c3MASlow = mConditions.slowBuffer[cIDX];
|
||||||
|
double p3MASlow = mConditions.slowBuffer[pIDX];
|
||||||
|
double p23MASlow = mConditions.slowBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
double z3MASlowState = mConditions.slowStateBuffer[zIDX];
|
||||||
|
double c3MASlowState = mConditions.slowStateBuffer[cIDX];
|
||||||
|
double p3MASlowState = mConditions.slowStateBuffer[pIDX];
|
||||||
|
double p23MASlowState = mConditions.slowStateBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
double zRSI = mConditions.rsiBuffer[zIDX];
|
||||||
|
double cRSI = mConditions.rsiBuffer[cIDX];
|
||||||
|
double pRSI = mConditions.rsiBuffer[pIDX];
|
||||||
|
double p2RSI = mConditions.rsiBuffer[p2IDX];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reading Bars ...
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
XOHCL cBar;
|
||||||
|
XOHCL pBar;
|
||||||
|
XOHCL p2Bar;
|
||||||
|
XOHCL p3Bar;
|
||||||
|
XOHCL p4Bar;
|
||||||
|
has = zBar.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
zIDX //
|
||||||
|
);
|
||||||
|
has =
|
||||||
|
has &&
|
||||||
|
zBar.GetPreviousBar(cBar);
|
||||||
|
has =
|
||||||
|
has &&
|
||||||
|
cBar.GetPreviousBar(pBar);
|
||||||
|
has =
|
||||||
|
has &&
|
||||||
|
pBar.GetPreviousBar(p2Bar);
|
||||||
|
has =
|
||||||
|
has &&
|
||||||
|
p2Bar.GetPreviousBar(p3Bar);
|
||||||
|
has =
|
||||||
|
has &&
|
||||||
|
p3Bar.GetPreviousBar(p4Bar);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
p2Bar.Clean();
|
||||||
|
p3Bar.Clean();
|
||||||
|
p4Bar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reading Bars Related Data ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Score ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double bullishScore = 0;
|
||||||
|
double bearishScore = 0;
|
||||||
|
mConditions.GenerateScore(
|
||||||
|
bullishScore,
|
||||||
|
bearishScore //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isScoreBullish =
|
||||||
|
bullishScore > bearishScore;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isScoreBearish =
|
||||||
|
bearishScore > bullishScore;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generating Conditions Summary ...
|
||||||
|
string summary =
|
||||||
|
mConditions
|
||||||
|
.GenerateSummary();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculating Range Volumes ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double bullishVolume = 0;
|
||||||
|
double bearishVolume = 0;
|
||||||
|
int volumeRangeLoopback = 5;
|
||||||
|
helper.barAnalyser.CalculateRangeVolume(
|
||||||
|
cBar,
|
||||||
|
bullishVolume,
|
||||||
|
bearishVolume,
|
||||||
|
volumeRangeLoopback //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double rangeVolume = bullishVolume = bearishVolume;
|
||||||
|
double rangeVolumeAvg = rangeVolume / volumeRangeLoopback;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Preparing Complex Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isRSIBullish =
|
||||||
|
cRSI > pRSI &&
|
||||||
|
!mConditions.isRSIOB;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isRSIBearish =
|
||||||
|
cRSI < pRSI &&
|
||||||
|
!mConditions.isRSIOS;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isVolumeBullish = bullishVolume > bearishVolume;
|
||||||
|
bool isVolumeBearish = bullishVolume < bearishVolume;
|
||||||
|
bool isVolumeOverLast = cBar.volume > pBar.volume;
|
||||||
|
bool isVolumeOverAvg = cBar.volume > rangeVolumeAvg;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cond2 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCond2Bullish =
|
||||||
|
//
|
||||||
|
mConditions.isUnderMal &&
|
||||||
|
mConditions.isValeIsPivot &&
|
||||||
|
// mConditions.swingLowBuffer[cIDX] > mConditions.valeBuffer[cIDX] &&
|
||||||
|
mConditions.swingLowBuffer[cIDX] < mConditions.fiboLevel3Buffer[cIDX]
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCond2Bearish =
|
||||||
|
//
|
||||||
|
false // &&
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isCond2 = isCond2Bullish ||
|
||||||
|
isCond2Bearish;
|
||||||
|
if (isCond2)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Print("Cond2");
|
||||||
|
// isCond2Bullish = false;
|
||||||
|
// isCond2Bearish = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Results ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = isCond2Bullish;
|
||||||
|
bool isBearish = isCond2Bearish;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool result = isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime time = zBar.time;
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION iDir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle Works ...
|
||||||
|
if (isCond2)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string name = "Cond2_" + ToString(iDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
color clr = isBullish
|
||||||
|
? clrAqua
|
||||||
|
: clrMagenta;
|
||||||
|
|
||||||
|
//
|
||||||
|
CChartObjectHLine *iObj;
|
||||||
|
iObj = new CChartObjectHLine();
|
||||||
|
has = iObj.Create(
|
||||||
|
0,
|
||||||
|
name,
|
||||||
|
0,
|
||||||
|
time //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Style Object ...
|
||||||
|
iObj.Width(1);
|
||||||
|
iObj.Color(clr);
|
||||||
|
iObj.Style(STYLE_DOT);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Store Object ...
|
||||||
|
mObjects.Add(iObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
Reference in New Issue
Block a user