add backup 14040103
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,245 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Valid_Break_Detector |
|
||||||
|
//| Copyright 2023, MetaQuotes Software Corp. |
|
||||||
|
//| https://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2023, MetaQuotes Software Corp."
|
||||||
|
#property link "https://www.mql5.com"
|
||||||
|
#property version "1.00"
|
||||||
|
#property description "Detects Valid Breakouts of Zones with Rejection Confirmation"
|
||||||
|
|
||||||
|
// Input Parameters
|
||||||
|
input double LotSize = 0.1; // Lot size for trades
|
||||||
|
input int StopLoss = 50; // Stop Loss in points
|
||||||
|
input int TakeProfit = 100; // Take Profit in points
|
||||||
|
input bool RequireVolumeSpike = true; // Enable volume spike filter
|
||||||
|
input double VolumeThreshold = 1.5; // Minimum volume increase factor
|
||||||
|
input bool RequireCloseBeyond = true; // Require candle close beyond the zone
|
||||||
|
input int RejectionConfirmationCandles = 2; // Number of candles to confirm rejection
|
||||||
|
|
||||||
|
// Global Variables
|
||||||
|
int MagicNumber = 789101;
|
||||||
|
|
||||||
|
//
|
||||||
|
double _Ask = 0;
|
||||||
|
double _Bid = 0;
|
||||||
|
|
||||||
|
// Zone Boundaries
|
||||||
|
double ZoneHigh = 0;
|
||||||
|
double ZoneLow = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
double maBuffer[];
|
||||||
|
int maHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
// Breakout Status
|
||||||
|
bool BullishBreakoutDetected = false;
|
||||||
|
bool BearishBreakoutDetected = false;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(maBuffer, true);
|
||||||
|
maHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
14,
|
||||||
|
0,
|
||||||
|
MODE_SMA,
|
||||||
|
VOLUME_TICK //
|
||||||
|
);
|
||||||
|
if (maHandler == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
return (INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Print("Valid Break Detector EA Initialized");
|
||||||
|
return (INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
IndicatorRelease(maHandler);
|
||||||
|
Print("Valid Break Detector EA Deinitialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
_Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||||||
|
_Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||||||
|
CopyBuffer(maHandler, MAIN_LINE, 0, 14, maBuffer);
|
||||||
|
|
||||||
|
// Define the zone dynamically (e.g., based on recent highs/lows)
|
||||||
|
DefineZone();
|
||||||
|
|
||||||
|
// Check for valid break of the zone
|
||||||
|
CheckValidBreak();
|
||||||
|
|
||||||
|
// Confirm rejection after breakout
|
||||||
|
if (BullishBreakoutDetected || BearishBreakoutDetected)
|
||||||
|
ConfirmRejection();
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Function to define the zone dynamically |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void DefineZone()
|
||||||
|
{
|
||||||
|
// Example: Define zone based on recent highs and lows
|
||||||
|
ZoneHigh = iHigh(_Symbol, _Period, 1); // Recent high
|
||||||
|
ZoneLow = iLow(_Symbol, _Period, 2); // Recent low
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Function to check for a valid break of the zone |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CheckValidBreak()
|
||||||
|
{
|
||||||
|
double currentPrice = _Bid;
|
||||||
|
|
||||||
|
// Check if price breaks above the zone
|
||||||
|
if (!BullishBreakoutDetected && currentPrice > ZoneHigh)
|
||||||
|
{
|
||||||
|
if (IsValidBreak(ZoneHigh, true))
|
||||||
|
{
|
||||||
|
Print("Potential Bullish Break Above Zone Detected at ", TimeToString(TimeCurrent(), TIME_DATE));
|
||||||
|
BullishBreakoutDetected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if price breaks below the zone
|
||||||
|
if (!BearishBreakoutDetected && currentPrice < ZoneLow)
|
||||||
|
{
|
||||||
|
if (IsValidBreak(ZoneLow, false))
|
||||||
|
{
|
||||||
|
Print("Potential Bearish Break Below Zone Detected at ", TimeToString(TimeCurrent(), TIME_DATE));
|
||||||
|
BearishBreakoutDetected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Function to validate the breakout |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool IsValidBreak(double zoneLevel, bool isAbove)
|
||||||
|
{
|
||||||
|
// Check if the candle closed beyond the zone
|
||||||
|
if (RequireCloseBeyond)
|
||||||
|
{
|
||||||
|
double closePrice = iClose(_Symbol, _Period, 1);
|
||||||
|
if ((isAbove && closePrice <= zoneLevel) || (!isAbove && closePrice >= zoneLevel))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for a volume spike
|
||||||
|
if (RequireVolumeSpike)
|
||||||
|
{
|
||||||
|
double currentVolume = (double) iVolume(_Symbol, _Period, 1);
|
||||||
|
double averageVolume = maBuffer[1];
|
||||||
|
if (currentVolume < VolumeThreshold * averageVolume)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All conditions met, valid breakout
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Function to confirm rejection |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void ConfirmRejection()
|
||||||
|
{
|
||||||
|
double currentPrice = _Bid;
|
||||||
|
|
||||||
|
if (BullishBreakoutDetected)
|
||||||
|
{
|
||||||
|
// Check if price rejects lower levels and confirms bullish breakout
|
||||||
|
bool confirmed = true;
|
||||||
|
for (int i = 1; i <= RejectionConfirmationCandles; i++)
|
||||||
|
{
|
||||||
|
double closePrice = iClose(_Symbol, _Period, i);
|
||||||
|
if (closePrice < ZoneHigh)
|
||||||
|
{
|
||||||
|
confirmed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirmed)
|
||||||
|
{
|
||||||
|
Print("Bullish Breakout Confirmed at ", TimeToString(TimeCurrent(), TIME_DATE));
|
||||||
|
PlaceTrade(ORDER_TYPE_BUY, "Confirmed Bullish Breakout Buy");
|
||||||
|
BullishBreakoutDetected = false; // Reset breakout status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BearishBreakoutDetected)
|
||||||
|
{
|
||||||
|
// Check if price rejects higher levels and confirms bearish breakout
|
||||||
|
bool confirmed = true;
|
||||||
|
for (int i = 1; i <= RejectionConfirmationCandles; i++)
|
||||||
|
{
|
||||||
|
double closePrice = iClose(_Symbol, _Period, i);
|
||||||
|
if (closePrice > ZoneLow)
|
||||||
|
{
|
||||||
|
confirmed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirmed)
|
||||||
|
{
|
||||||
|
Print("Bearish Breakout Confirmed at ", TimeToString(TimeCurrent(), TIME_DATE));
|
||||||
|
PlaceTrade(ORDER_TYPE_SELL, "Confirmed Bearish Breakout Sell");
|
||||||
|
BearishBreakoutDetected = false; // Reset breakout status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Function to place a trade |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void PlaceTrade(int orderType, string comment)
|
||||||
|
{
|
||||||
|
double price = (orderType == ORDER_TYPE_BUY) ? _Ask : _Bid;
|
||||||
|
double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * Point() : price + StopLoss * Point();
|
||||||
|
double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * Point() : price - TakeProfit * Point();
|
||||||
|
|
||||||
|
MqlTradeRequest request;
|
||||||
|
MqlTradeResult result;
|
||||||
|
|
||||||
|
ZeroMemory(request);
|
||||||
|
ZeroMemory(result);
|
||||||
|
|
||||||
|
request.action = TRADE_ACTION_DEAL;
|
||||||
|
request.symbol = _Symbol;
|
||||||
|
request.volume = LotSize;
|
||||||
|
request.type = orderType;
|
||||||
|
request.price = price;
|
||||||
|
request.sl = sl;
|
||||||
|
request.tp = tp;
|
||||||
|
request.deviation = 10;
|
||||||
|
request.magic = MagicNumber;
|
||||||
|
request.comment = comment;
|
||||||
|
|
||||||
|
if (!OrderSend(request, result))
|
||||||
|
{
|
||||||
|
Print("Error placing order: ", result.retcode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Print(comment, " Order placed successfully.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,830 @@
|
|||||||
|
//
|
||||||
|
bool HasSenario1Conditions(
|
||||||
|
ENUM_X_CYCLES cycle,
|
||||||
|
XBoxZone &box,
|
||||||
|
XBoxZone &holderBox,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
XBoxZone &waitingBoxes[],
|
||||||
|
X121SMCStrategySignalProviderData &provider,
|
||||||
|
ENUM_X_CYCLES holderCycle = X_CYCLE_NONE,
|
||||||
|
int barIndex = 0 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
Parse(cXConditions);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fil Selected Data ...
|
||||||
|
XPOIState chState;
|
||||||
|
X121Conditions chXConditions;
|
||||||
|
XPOIStateEvents chStateEvents;
|
||||||
|
XC121SMCCycleHelper *chHelper;
|
||||||
|
X121SMCCycleConditions chConditions;
|
||||||
|
if (holderCycle != X_CYCLE_NONE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = provider.SelectCycle(
|
||||||
|
holderCycle,
|
||||||
|
chState,
|
||||||
|
chStateEvents,
|
||||||
|
chXConditions,
|
||||||
|
chHelper,
|
||||||
|
chConditions //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
chState.Clean();
|
||||||
|
ZeroMemory(chHelper);
|
||||||
|
chConditions.Clean();
|
||||||
|
chXConditions.Clean();
|
||||||
|
chStateEvents.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Parse(chXConditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Waiting Baoxes Exists ...
|
||||||
|
result = HasChild(waitingBoxes);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCPOIDrawer *drawer = provider
|
||||||
|
.visionCycleHelper
|
||||||
|
.mPOIDrawer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Args ...
|
||||||
|
|
||||||
|
//
|
||||||
|
box.Clean();
|
||||||
|
holderBox.Clean();
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial Bars ...
|
||||||
|
result = zBar.Init(
|
||||||
|
cState.symbol,
|
||||||
|
cState.period,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
zBar.GetPreviousBar(cBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
cBar.GetPreviousBar(pBar);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
cState.Clean();
|
||||||
|
chState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
ZeroMemory(chHelper);
|
||||||
|
chConditions.Clean();
|
||||||
|
chXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Inside Box ...
|
||||||
|
XBoxZone insideBox;
|
||||||
|
count = ArraySize(waitingBoxes);
|
||||||
|
has = IsValidSize(count);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iBox = waitingBoxes[i];
|
||||||
|
bool isBullish = iBox.IsBullish();
|
||||||
|
double iMid = iBox.lower + ((iBox.upper - iBox.lower) / 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
has =
|
||||||
|
//
|
||||||
|
isBullish
|
||||||
|
? cBar.low < iMid &&
|
||||||
|
cBar.low > iBox.lower
|
||||||
|
: cBar.high > iMid &&
|
||||||
|
cBar.high < iBox.upper
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
insideBox = iBox;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
has = insideBox.IsValid();
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION iBarPosDir;
|
||||||
|
bool isBarValidForDir = cHelper
|
||||||
|
.mBarAnalyser
|
||||||
|
.IsValidForPosition(
|
||||||
|
cBar,
|
||||||
|
iBarPosDir //
|
||||||
|
);
|
||||||
|
bool isBarValidForBullish =
|
||||||
|
isBarValidForDir &&
|
||||||
|
IsBullish(iBarPosDir);
|
||||||
|
bool isBarValidForBearish =
|
||||||
|
isBarValidForDir &&
|
||||||
|
IsBearish(iBarPosDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
has = drawer.DrawBox(
|
||||||
|
insideBox,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Print("Dec Scores:");
|
||||||
|
Print("-------------");
|
||||||
|
Print("Bull: ", provider.decisionBullishScore);
|
||||||
|
Print("Bear: ", provider.decisionBearishScore);
|
||||||
|
Print("-------------");
|
||||||
|
Print("Anal Scores:");
|
||||||
|
Print("-------------");
|
||||||
|
Print("Bull: ", provider.analyseBullishScore);
|
||||||
|
Print("Bear: ", provider.analyseBearishScore);
|
||||||
|
Print("-------------");
|
||||||
|
Print("Bar Valid For: " + ToString(iBarPosDir));
|
||||||
|
Print("-------------");
|
||||||
|
Print(ToString(insideBox.dir), " Inside ...");
|
||||||
|
Print("-------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = has;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
cState.Clean();
|
||||||
|
chState.Clean();
|
||||||
|
insideBox.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
ZeroMemory(chHelper);
|
||||||
|
chConditions.Clean();
|
||||||
|
chXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detecting Signal Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish Conditions ...
|
||||||
|
isBullish =
|
||||||
|
//
|
||||||
|
// Base Condition ...
|
||||||
|
(
|
||||||
|
//
|
||||||
|
insideBox.IsBullish() &&
|
||||||
|
isBarValidForBullish
|
||||||
|
//
|
||||||
|
)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish Conditions ...
|
||||||
|
isBearish =
|
||||||
|
//
|
||||||
|
// Base Condition ...
|
||||||
|
(
|
||||||
|
//
|
||||||
|
insideBox.IsBearish() &&
|
||||||
|
isBarValidForBearish
|
||||||
|
//
|
||||||
|
)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filling Requirements ...
|
||||||
|
result =
|
||||||
|
isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.dir = dir;
|
||||||
|
box.to = TimeCurrent();
|
||||||
|
box.from = insideBox.from;
|
||||||
|
box.upper = insideBox.upper;
|
||||||
|
box.lower = insideBox.lower;
|
||||||
|
box.symbol = cXConditions.symbol;
|
||||||
|
box.period = cXConditions.period;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check All Conditions ...
|
||||||
|
result =
|
||||||
|
box.IsValid() &&
|
||||||
|
HasDirection(dir) &&
|
||||||
|
(isBullish ||
|
||||||
|
isBearish);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
cState.Clean();
|
||||||
|
chState.Clean();
|
||||||
|
insideBox.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cStateEvents.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
ZeroMemory(chHelper);
|
||||||
|
chConditions.Clean();
|
||||||
|
chStateEvents.Clean();
|
||||||
|
chXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checking a Box Exists in Collections or not ...
|
||||||
|
*
|
||||||
|
* @param box: XBoxZone instance reference ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsExists(XBoxZone &box)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Validation ...
|
||||||
|
result = box.IsValid() &&
|
||||||
|
(HasWaitingBoxes() ||
|
||||||
|
HasBreakedBoxes() ||
|
||||||
|
HasUnavailableBoxes());
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Index in Waiting Boxes ...
|
||||||
|
has = HasWaitingBoxes();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = FindIndex(
|
||||||
|
box,
|
||||||
|
waitingBoxes //
|
||||||
|
);
|
||||||
|
result = IsValidIndex(idx);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Index in Breaked Boxes ...
|
||||||
|
has = HasBreakedBoxes();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = FindIndex(
|
||||||
|
box,
|
||||||
|
breakedBoxes //
|
||||||
|
);
|
||||||
|
result = IsValidIndex(idx);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Index in Unavailable Boxes ...
|
||||||
|
has = HasUnavailableBoxes();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = FindIndex(
|
||||||
|
box,
|
||||||
|
unavailableBoxes //
|
||||||
|
);
|
||||||
|
result = IsValidIndex(idx);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Signal Boxes ...
|
||||||
|
*
|
||||||
|
* @param cycle: ENUM_X_CYCLES member ...
|
||||||
|
* @param provider: X121SMCStrategySignalProviderData instance reference ...
|
||||||
|
* @param barIndex: int ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool DetectSignalBoxes(
|
||||||
|
ENUM_X_CYCLES cycle,
|
||||||
|
X121SMCStrategySignalProviderData &provider,
|
||||||
|
int barIndex = 0 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
int idx = -1;
|
||||||
|
int count = 0;
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (barIndex < 0)
|
||||||
|
{
|
||||||
|
barIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Cycle ...
|
||||||
|
XPOIState cState;
|
||||||
|
XPOIStateEvents cStateEvents;
|
||||||
|
X121Conditions cXConditions;
|
||||||
|
XC121SMCCycleHelper *cHelper;
|
||||||
|
X121SMCCycleConditions cConditions;
|
||||||
|
result = provider.SelectCycle(
|
||||||
|
cycle,
|
||||||
|
cState,
|
||||||
|
cStateEvents,
|
||||||
|
cXConditions,
|
||||||
|
cHelper,
|
||||||
|
cConditions //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cStateEvents.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Rejection Boxes ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Select Validate Rejection Boxes ...
|
||||||
|
// XBoxZone rejections[];
|
||||||
|
// int count = cHelper
|
||||||
|
// .DetectRejections(
|
||||||
|
// rejections,
|
||||||
|
// barIndex //
|
||||||
|
// );
|
||||||
|
|
||||||
|
// //
|
||||||
|
// result = IsValidSize(count);
|
||||||
|
// if (result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// for (int i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// has = IsExists(rejections[i]);
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// rejections[i],
|
||||||
|
// waitingBoxes //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Select Order Blocks ...
|
||||||
|
// if (cStateEvents.hasNewOrderBlock)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// idx = GetYoungest(cState.orderBlocks);
|
||||||
|
// has = IsValidIndex(idx);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XCOrderBlock *iOB = cState.orderBlocks[idx];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XBoxZone iBox;
|
||||||
|
// has = ToBox(
|
||||||
|
// iBox,
|
||||||
|
// iOB //
|
||||||
|
// );
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// has = IsExists(iBox);
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iBox,
|
||||||
|
// waitingBoxes //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Fair Value Gaps ...
|
||||||
|
// if (cStateEvents.hasNewFairValueGap)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// idx = GetYoungest(cState.fairValueGaps);
|
||||||
|
// has = IsValidIndex(idx);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XCFVG *iOB = cState.fairValueGaps[idx];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XBoxZone iBox;
|
||||||
|
// has = ToBox(
|
||||||
|
// iBox,
|
||||||
|
// iOB //
|
||||||
|
// );
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// has = IsExists(iBox);
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iBox,
|
||||||
|
// waitingBoxes //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Supply/Demand Zones ...
|
||||||
|
// if (cStateEvents.hasNewSupplyZone)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// idx = GetYoungest(cState.supplyZones);
|
||||||
|
// has = IsValidIndex(idx);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XCSupplyZone *iSupply = cState.supplyZones[idx];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XBoxZone iBox;
|
||||||
|
// has = ToBox(
|
||||||
|
// iBox,
|
||||||
|
// iSupply //
|
||||||
|
// );
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// has = IsExists(iBox);
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iBox,
|
||||||
|
// waitingBoxes //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (cStateEvents.hasNewDemandZone)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// idx = GetYoungest(cState.demandZones);
|
||||||
|
// has = IsValidIndex(idx);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XCDemandZone *iDemand = cState.demandZones[idx];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XBoxZone iBox;
|
||||||
|
// has = ToBox(
|
||||||
|
// iBox,
|
||||||
|
// iDemand //
|
||||||
|
// );
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// has = IsExists(iBox);
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iBox,
|
||||||
|
// waitingBoxes //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Support/Resistance Zones ...
|
||||||
|
// if (cStateEvents.hasNewSupportZone)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// idx = GetYoungest(cState.supportZones);
|
||||||
|
// has = IsValidIndex(idx);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XCSupportZone *iSupport = cState.supportZones[idx];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XBoxZone iBox;
|
||||||
|
// has = ToBox(
|
||||||
|
// iBox,
|
||||||
|
// iSupport //
|
||||||
|
// );
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// has = IsExists(iBox);
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iBox,
|
||||||
|
// waitingBoxes //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (cStateEvents.hasNewResistanceZone)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// idx = GetYoungest(cState.resistanceZones);
|
||||||
|
// has = IsValidIndex(idx);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XCResistanceZone *iResistance = cState.resistanceZones[idx];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XBoxZone iBox;
|
||||||
|
// has = ToBox(
|
||||||
|
// iBox,
|
||||||
|
// iResistance //
|
||||||
|
// );
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// has = IsExists(iBox);
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iBox,
|
||||||
|
// waitingBoxes //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
count = CountWaitingBoxes();
|
||||||
|
result = IsValidSize(count);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
|
||||||
|
//
|
||||||
|
cState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
cStateEvents.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validating Waiting Boxes and Detect Breaked Boxes ...
|
||||||
|
*
|
||||||
|
* @param barIndex: int ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ValidateWaitingBoxes(
|
||||||
|
int barIndex = 0 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool has = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (barIndex < 0)
|
||||||
|
{
|
||||||
|
barIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (barIndex == 0)
|
||||||
|
{
|
||||||
|
barIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = HasWaitingBoxes();
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int removeIDX[];
|
||||||
|
result = CountWaitingBoxes();
|
||||||
|
for (int i = 0; i < result; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XOHCL iBar;
|
||||||
|
XBoxZone iBox = waitingBoxes[i];
|
||||||
|
bool isInite = iBar
|
||||||
|
.Init(
|
||||||
|
iBox.symbol,
|
||||||
|
iBox.period,
|
||||||
|
iBox.from //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
has = isInite &&
|
||||||
|
IsBoxBreaked(
|
||||||
|
iBox,
|
||||||
|
iBar.Index() - 1,
|
||||||
|
barIndex,
|
||||||
|
period //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
i,
|
||||||
|
removeIDX //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iBox,
|
||||||
|
breakedBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
iBar.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = HasChild(removeIDX);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CleanupArray(
|
||||||
|
removeIDX,
|
||||||
|
waitingBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Clean(removeIDX);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = CountWaitingBoxes();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Support and Resistance.mq5 |
|
||||||
|
//| https://t.me/ForexEaPremium |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "https://t.me/ForexEaPremium"
|
||||||
|
#property version "2.02"
|
||||||
|
|
||||||
|
#property description "Blue and red support and resistance levels displayed directly on the chart."
|
||||||
|
#property description "Alerts for close above resistance and close below support."
|
||||||
|
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 2
|
||||||
|
#property indicator_plots 2
|
||||||
|
#property indicator_color1 clrRed
|
||||||
|
#property indicator_type1 DRAW_ARROW
|
||||||
|
#property indicator_width1 2
|
||||||
|
#property indicator_label1 "Resistance"
|
||||||
|
#property indicator_color2 clrBlue
|
||||||
|
#property indicator_type2 DRAW_ARROW
|
||||||
|
#property indicator_width2 2
|
||||||
|
#property indicator_label2 "Support"
|
||||||
|
|
||||||
|
enum enum_candle_to_check
|
||||||
|
{
|
||||||
|
Current,
|
||||||
|
Previous
|
||||||
|
};
|
||||||
|
|
||||||
|
input bool EnableNativeAlerts = false;
|
||||||
|
input bool EnableEmailAlerts = false;
|
||||||
|
input bool EnablePushAlerts = false;
|
||||||
|
input enum_candle_to_check TriggerCandle = Previous;
|
||||||
|
|
||||||
|
double Resistance[];
|
||||||
|
double Support[];
|
||||||
|
|
||||||
|
int myFractal;
|
||||||
|
|
||||||
|
datetime LastAlertTime = D'01.01.1970';
|
||||||
|
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
PlotIndexSetInteger(0, PLOT_ARROW, 119);
|
||||||
|
PlotIndexSetInteger(1, PLOT_ARROW, 119);
|
||||||
|
|
||||||
|
SetIndexBuffer(0, Resistance);
|
||||||
|
SetIndexBuffer(1, Support);
|
||||||
|
|
||||||
|
ArraySetAsSeries(Resistance, true);
|
||||||
|
ArraySetAsSeries(Support, true);
|
||||||
|
|
||||||
|
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 5);
|
||||||
|
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, 5);
|
||||||
|
|
||||||
|
myFractal = iFractals(NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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[])
|
||||||
|
{
|
||||||
|
ArraySetAsSeries(High, true);
|
||||||
|
ArraySetAsSeries(Low, true);
|
||||||
|
ArraySetAsSeries(Close, true);
|
||||||
|
ArraySetAsSeries(Time, true);
|
||||||
|
|
||||||
|
//Get the values of the Fractals indicator before entering the cycle.
|
||||||
|
double FractalUpperBuffer[];
|
||||||
|
double FractalLowerBuffer[];
|
||||||
|
|
||||||
|
CopyBuffer(myFractal, 0, 0, rates_total, FractalUpperBuffer);
|
||||||
|
CopyBuffer(myFractal, 1, 0, rates_total, FractalLowerBuffer);
|
||||||
|
|
||||||
|
ArraySetAsSeries(FractalUpperBuffer, true);
|
||||||
|
ArraySetAsSeries(FractalLowerBuffer, true);
|
||||||
|
|
||||||
|
for (int i = rates_total - 2; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (FractalUpperBuffer[i] != EMPTY_VALUE) Resistance[i] = High[i];
|
||||||
|
else Resistance[i] = Resistance[i + 1];
|
||||||
|
|
||||||
|
if (FractalLowerBuffer[i] != EMPTY_VALUE) Support[i] = Low[i];
|
||||||
|
else Support[i] = Support[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alerts
|
||||||
|
if (((TriggerCandle > 0) && (Time[0] > LastAlertTime)) || (TriggerCandle == 0))
|
||||||
|
{
|
||||||
|
string Text, TextNative;
|
||||||
|
// Resistance.
|
||||||
|
if ((Close[TriggerCandle] > Resistance[TriggerCandle]) && (Close[TriggerCandle + 1] <= Resistance[TriggerCandle]))
|
||||||
|
{
|
||||||
|
Text = "S&R: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Closed above Resistance: " + DoubleToString(Resistance[TriggerCandle], _Digits) + ".";
|
||||||
|
TextNative = "S&R: Closed above Resistance: " + DoubleToString(Resistance[TriggerCandle], _Digits) + ".";
|
||||||
|
if (EnableNativeAlerts) Alert(TextNative);
|
||||||
|
if (EnableEmailAlerts) SendMail("S&R Alert", Text);
|
||||||
|
if (EnablePushAlerts) SendNotification(Text);
|
||||||
|
LastAlertTime = Time[0];
|
||||||
|
}
|
||||||
|
// Support.
|
||||||
|
if ((Close[TriggerCandle] < Support[TriggerCandle]) && (Close[TriggerCandle + 1] >= Support[TriggerCandle]))
|
||||||
|
{
|
||||||
|
Text = "S&R: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Closed below Support: " + DoubleToString(Support[TriggerCandle], _Digits) + ".";
|
||||||
|
TextNative = "S&R: Closed below Support: " + DoubleToString(Support[TriggerCandle], _Digits) + ".";
|
||||||
|
if (EnableNativeAlerts) Alert(TextNative);
|
||||||
|
if (EnableEmailAlerts) SendMail("S&R Alert", Text);
|
||||||
|
if (EnablePushAlerts) SendNotification(Text);
|
||||||
|
LastAlertTime = Time[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -0,0 +1,584 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// Configurations ...
|
||||||
|
bool useSharpChange = false;
|
||||||
|
bool useOrderBlockFVG = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Order Blocks ...
|
||||||
|
if (useOrderBlockFVG)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (obStateEvents.hasNewOrderBlock)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = GetYoungest(obState.orderBlocks);
|
||||||
|
has = IsValidIndex(idx);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCFVG *iFVG = NULL;
|
||||||
|
XCOrderBlock *iOB = obState.orderBlocks[idx];
|
||||||
|
bool isBullish = iOB.IsBullish();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detecting Inside FVG ...
|
||||||
|
has = fvgState.HasFairValueGaps();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCFVG *tmpFVGs[];
|
||||||
|
count = fvgState.CountFairValueGaps();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCFVG *jFVG = fvgState.fairValueGaps[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isDirPassed = jFVG.GetDirection() == iOB.GetDirection();
|
||||||
|
bool isFromPassed = jFVG.From() >= iOB.From();
|
||||||
|
bool isPlacePassed = IsInsideOrDiff(
|
||||||
|
jFVG,
|
||||||
|
iOB,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
has = isDirPassed &&
|
||||||
|
isFromPassed &&
|
||||||
|
isPlacePassed;
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
jFVG,
|
||||||
|
tmpFVGs //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(jFVG);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selecting iFVG Based on Direction of OB ...
|
||||||
|
has = HasChild(tmpFVGs);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx =
|
||||||
|
isBullish
|
||||||
|
? GetLowest(tmpFVGs)
|
||||||
|
: GetHighest(tmpFVGs);
|
||||||
|
has = IsValidIndex(idx);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
iFVG = tmpFVGs[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(tmpFVGs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XBoxZone iOBBox;
|
||||||
|
XBoxZone iFVGBox;
|
||||||
|
if (iFVG != NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
has = ToBox(
|
||||||
|
iFVGBox,
|
||||||
|
iFVG //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = ToBox(
|
||||||
|
iOBBox,
|
||||||
|
iOB //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
has = iOBBox.IsValid() &&
|
||||||
|
iFVGBox.IsValid();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XSignalBox iSignalBox;
|
||||||
|
|
||||||
|
//
|
||||||
|
iSignalBox.ob = iOBBox;
|
||||||
|
iSignalBox.fvg = iFVGBox;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Here We Check Waiting Box Contains Other Zones ...
|
||||||
|
// Like Support/Resistances ...
|
||||||
|
bool forceVerification = false;
|
||||||
|
if (forceVerification)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone iVerificationBox;
|
||||||
|
XBoxZone tmpBoxes[];
|
||||||
|
if (isBullish)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ToBox(
|
||||||
|
provider.decisionState.supportZones,
|
||||||
|
tmpBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ToBox(
|
||||||
|
provider.decisionState.resistanceZones,
|
||||||
|
tmpBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
has = HasChild(tmpBoxes);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
while (HasChild(tmpBoxes))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = GetYoungest(tmpBoxes);
|
||||||
|
has = IsValidIndex(idx);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Box ...
|
||||||
|
XBoxZone iBox = tmpBoxes[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpBoxes,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Box ...
|
||||||
|
bool isValidPassed = !IsBoxValid(
|
||||||
|
iBox,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
bool isDirPassed = iBox.dir == iOBBox.dir;
|
||||||
|
bool isPlacePassed =
|
||||||
|
IsBoxInside(
|
||||||
|
iBox,
|
||||||
|
iOBBox //
|
||||||
|
)
|
||||||
|
//
|
||||||
|
&&
|
||||||
|
//
|
||||||
|
(!iFVGBox.IsValid()
|
||||||
|
? true
|
||||||
|
: IsBoxInsideOr(
|
||||||
|
iBox,
|
||||||
|
iFVGBox //
|
||||||
|
));
|
||||||
|
|
||||||
|
//
|
||||||
|
has =
|
||||||
|
isDirPassed &&
|
||||||
|
isValidPassed &&
|
||||||
|
isPlacePassed;
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iVerificationBox = iBox;
|
||||||
|
iBox.Clean();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
has = iVerificationBox.IsValid();
|
||||||
|
Clean(tmpBoxes);
|
||||||
|
iVerificationBox.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iSignalBox,
|
||||||
|
waitingBoxes //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
iSignalBox.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
iOBBox.Clean();
|
||||||
|
iFVGBox.Clean();
|
||||||
|
ZeroMemory(iOB);
|
||||||
|
ZeroMemory(iFVG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Checking Other Senario for Waiting Boxes ...
|
||||||
|
if (useSharpChange)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (obStateEvents.hasNewSharp)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XBoxZone currSharp;
|
||||||
|
XBoxZone prevSharp;
|
||||||
|
XBoxZone sharpConsolidation;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Current Sharp ...
|
||||||
|
XCPOIDrawer *drawer = provider.visionCycleHelper.mPOIDrawer;
|
||||||
|
XBoxZone tmpBoxes[];
|
||||||
|
Copy(
|
||||||
|
obState.sharps,
|
||||||
|
tmpBoxes //
|
||||||
|
);
|
||||||
|
idx = GetYoungest(tmpBoxes);
|
||||||
|
has = IsValidIndex(idx);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
currSharp = tmpBoxes[idx];
|
||||||
|
bool isBullish = currSharp.IsBullish();
|
||||||
|
|
||||||
|
//
|
||||||
|
ArrayRemove(
|
||||||
|
tmpBoxes,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
while (HasChild(tmpBoxes))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = GetYoungest(tmpBoxes);
|
||||||
|
has = IsValidIndex(idx);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XBoxZone iBox = tmpBoxes[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpBoxes,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (iBox.dir == currSharp.dir)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
prevSharp = iBox;
|
||||||
|
iBox.Clean();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(tmpBoxes);
|
||||||
|
}
|
||||||
|
Clean(tmpBoxes);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Preparing Sharp Consolidation Box ...
|
||||||
|
has = currSharp.IsValid() &&
|
||||||
|
prevSharp.IsValid() &&
|
||||||
|
prevSharp.lower < currSharp.upper;
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
sharpConsolidation.type = "XSHCNZ";
|
||||||
|
sharpConsolidation.dir = currSharp.dir;
|
||||||
|
sharpConsolidation.symbol = currSharp.symbol;
|
||||||
|
sharpConsolidation.period = currSharp.period;
|
||||||
|
|
||||||
|
//
|
||||||
|
sharpConsolidation.from = prevSharp.to;
|
||||||
|
sharpConsolidation.to = currSharp.from;
|
||||||
|
|
||||||
|
//
|
||||||
|
int toIDX = GetBarIndex(
|
||||||
|
currSharp.symbol,
|
||||||
|
currSharp.period,
|
||||||
|
sharpConsolidation.to //
|
||||||
|
);
|
||||||
|
int fromIDX = GetBarIndex(
|
||||||
|
currSharp.symbol,
|
||||||
|
currSharp.period,
|
||||||
|
sharpConsolidation.from //
|
||||||
|
);
|
||||||
|
int length = fromIDX - toIDX;
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL toBar;
|
||||||
|
has = toBar.Init(
|
||||||
|
sharpConsolidation.symbol,
|
||||||
|
sharpConsolidation.period,
|
||||||
|
toIDX //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double upper = toBar.FindHighest(
|
||||||
|
length,
|
||||||
|
MODE_HIGH //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double lower = toBar.FindLowest(
|
||||||
|
length,
|
||||||
|
MODE_LOW //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
sharpConsolidation.upper = upper;
|
||||||
|
sharpConsolidation.lower = lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = sharpConsolidation.IsValid();
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XSignalBox iBox;
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.ob = sharpConsolidation;
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
iBox,
|
||||||
|
waitingBoxes //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XCBoxObject *iCBoxObj;
|
||||||
|
// XCBoxObject *iPBoxObj;
|
||||||
|
// provider.visionCycleHelper.mPOIDrawer.DrawBox(
|
||||||
|
// currSharp,
|
||||||
|
// iCBoxObj //
|
||||||
|
// );
|
||||||
|
// provider.visionCycleHelper.mPOIDrawer.DrawBox(
|
||||||
|
// prevSharp,
|
||||||
|
// iPBoxObj //
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
currSharp.Clean();
|
||||||
|
prevSharp.Clean();
|
||||||
|
sharpConsolidation.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update Exists Box ...
|
||||||
|
// XBoxZone fvgs[];
|
||||||
|
// count = ArraySize(waitingBoxes);
|
||||||
|
// has = IsValidSize(count);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// for (int i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// bool isSharpBox = waitingBoxes[i].ob.type == "XSHCNZ";
|
||||||
|
// if (!isSharpBox)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// bool isBullish = waitingBoxes[i].ob.IsBullish();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Extract Inside FVGS ...
|
||||||
|
// if (isBullish)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// ToBox(
|
||||||
|
// fvgState.bullishFairValueGaps,
|
||||||
|
// fvgs //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// ToBox(
|
||||||
|
// fvgState.bearishFairValueGaps,
|
||||||
|
// fvgs //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// has = HasChild(fvgs);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// int removeds[];
|
||||||
|
// int iFVGsCount = ArraySize(fvgs);
|
||||||
|
// for (int j = 0; j < iFVGsCount; j++)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XBoxZone iFVGBox = fvgs[j];
|
||||||
|
// bool isFromPassed = iFVGBox.from >= waitingBoxes[i].ob.from;
|
||||||
|
// bool isBoundaryPassed =
|
||||||
|
// isBullish
|
||||||
|
// ? iFVGBox.lower < waitingBoxes[i].ob.upper
|
||||||
|
// : iFVGBox.upper > waitingBoxes[i].ob.lower;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// has = isFromPassed &&
|
||||||
|
// isBoundaryPassed;
|
||||||
|
// if (!has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// Add(
|
||||||
|
// j,
|
||||||
|
// removeds //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// CleanupArray(
|
||||||
|
// removeds,
|
||||||
|
// fvgs //
|
||||||
|
// );
|
||||||
|
// Clean(removeds);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Select FVG ...
|
||||||
|
// has = HasChild(fvgs);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// idx = isBullish
|
||||||
|
// ? GetLowest(fvgs)
|
||||||
|
// : GetHighest(fvgs);
|
||||||
|
// has = IsValidIndex(idx);
|
||||||
|
// if (has)
|
||||||
|
// {
|
||||||
|
// waitingBoxes[i].fvg = fvgs[idx];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// waitingBoxes[i].fvg.Clean();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean(fvgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (signalProvider == X121SMC_XWZ_PROVIDER_XHKMA)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iAtr = provider.decisionXConditions.atrBuffer[1];
|
||||||
|
iAtr *= 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Box fro SL ...
|
||||||
|
iSL = pivot;
|
||||||
|
Add(
|
||||||
|
iSL,
|
||||||
|
sls //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix rf Reward ...
|
||||||
|
rfRewar = 2;
|
||||||
|
}
|
||||||
|
else if (signalProvider == X121SMC_XWZ_PROVIDER_XREJECTED_BOX)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iAtr = provider.decisionXConditions.atrBuffer[1];
|
||||||
|
iAtr *= 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(sls);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Box fro SL ...
|
||||||
|
iSL = signalBox.lower + ((signalBox.upper - signalBox.lower) / 2);
|
||||||
|
Add(
|
||||||
|
iSL,
|
||||||
|
sls //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix rf Reward ...
|
||||||
|
rfRewar = 2;
|
||||||
|
}
|
||||||
|
else if (signalProvider == X121SMC_XWZ_PROVIDER_XACTIVATED_BOX)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iAtr = provider.decisionXConditions.atrBuffer[1];
|
||||||
|
iAtr *= 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(sls);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Box fro SL ...
|
||||||
|
iSL = pivot;
|
||||||
|
Add(
|
||||||
|
iSL,
|
||||||
|
sls //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix rf Reward ...
|
||||||
|
rfRewar = 2;
|
||||||
|
}
|
||||||
|
else if (signalProvider == X121SMC_XWZ_PROVIDER_XBREAKED_BOX)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iAtr = provider.decisionXConditions.atrBuffer[1];
|
||||||
|
iAtr *= 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(sls);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepare Box fro SL ...
|
||||||
|
iSL = pivot;
|
||||||
|
Add(
|
||||||
|
iSL,
|
||||||
|
sls //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix rf Reward ...
|
||||||
|
rfRewar = 2;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,520 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
int DrawOrderBlock(
|
||||||
|
XCOrderBlock *zone,
|
||||||
|
XCBaseObject *&objects[],
|
||||||
|
//
|
||||||
|
bool drawStartedBar = true,
|
||||||
|
bool drawActivatedBar = true,
|
||||||
|
bool drawBreakedBar = true,
|
||||||
|
bool drawWorkedBar = true,
|
||||||
|
//
|
||||||
|
int widthStartedBar = 1,
|
||||||
|
color clrStartedBar = clrYellow,
|
||||||
|
ENUM_LINE_STYLE styleStartedBar = STYLE_SOLID,
|
||||||
|
//
|
||||||
|
int widthActivatedBar = 1,
|
||||||
|
color clrActivatedBar = clrLime,
|
||||||
|
ENUM_LINE_STYLE styleActivatedBar = STYLE_SOLID,
|
||||||
|
//
|
||||||
|
int widthBreakedBar = 1,
|
||||||
|
color clrBreakedBar = clrRed,
|
||||||
|
ENUM_LINE_STYLE styleBreakedBar = STYLE_SOLID,
|
||||||
|
//
|
||||||
|
int widthWorkedBar = 1,
|
||||||
|
color clrWorkedBar = clrAqua,
|
||||||
|
ENUM_LINE_STYLE styleWorkedBar = STYLE_SOLID
|
||||||
|
//
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(objects);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (zone == NULL ||
|
||||||
|
!zone.IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION zoneDir = zone.GetDirection();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Started Bar ...
|
||||||
|
XOHCL startedBar;
|
||||||
|
bool isBodyOut = false;
|
||||||
|
bool isStarted = zone
|
||||||
|
.IsStarted(
|
||||||
|
zoneDir,
|
||||||
|
startedBar,
|
||||||
|
isBodyOut //
|
||||||
|
);
|
||||||
|
if (isStarted)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = startedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
startedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthStartedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthStartedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthStartedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleStartedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleStartedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleStartedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrStartedBar);
|
||||||
|
iBarObj.LowShadowColor(clrStartedBar);
|
||||||
|
iBarObj.HighShadowColor(clrStartedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Activated Bar ...
|
||||||
|
XOHCL activatedBar;
|
||||||
|
bool isBodyIn = false;
|
||||||
|
bool isActivated = zone
|
||||||
|
.IsActivated(
|
||||||
|
zoneDir,
|
||||||
|
activatedBar,
|
||||||
|
isBodyIn,
|
||||||
|
false // Force Body Out Started ...
|
||||||
|
);
|
||||||
|
if (isActivated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = activatedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
activatedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthActivatedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthActivatedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthActivatedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleActivatedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleActivatedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleActivatedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrActivatedBar);
|
||||||
|
iBarObj.LowShadowColor(clrActivatedBar);
|
||||||
|
iBarObj.HighShadowColor(clrActivatedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Breaked Bar ...
|
||||||
|
XOHCL breakedBar;
|
||||||
|
isBodyOut = false;
|
||||||
|
bool isBreaked = zone
|
||||||
|
.IsBreaked(
|
||||||
|
zoneDir,
|
||||||
|
breakedBar,
|
||||||
|
isBodyOut,
|
||||||
|
false, // Ignore Start ...
|
||||||
|
false // Force Body Out Started ...
|
||||||
|
);
|
||||||
|
if (isBreaked)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = breakedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
breakedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthBreakedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthBreakedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthBreakedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleBreakedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleBreakedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleBreakedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrBreakedBar);
|
||||||
|
iBarObj.LowShadowColor(clrBreakedBar);
|
||||||
|
iBarObj.HighShadowColor(clrBreakedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Worked Bar ...
|
||||||
|
XOHCL workedBar;
|
||||||
|
isBodyOut = false;
|
||||||
|
bool isWorked = zone
|
||||||
|
.IsWorked(
|
||||||
|
zoneDir,
|
||||||
|
workedBar,
|
||||||
|
isBodyOut,
|
||||||
|
false, // Ignore Activation ...
|
||||||
|
false, // Force Body Out Started ...
|
||||||
|
false // Force Body In Activated ...
|
||||||
|
);
|
||||||
|
if (isWorked)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = workedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
workedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthWorkedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthWorkedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthWorkedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleWorkedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleWorkedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleWorkedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrWorkedBar);
|
||||||
|
iBarObj.LowShadowColor(clrWorkedBar);
|
||||||
|
iBarObj.HighShadowColor(clrWorkedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBaseObject *iObj;
|
||||||
|
bool isCreated = CreateOrderBlock(
|
||||||
|
zone,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(objects);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int DrawFairValueGap(
|
||||||
|
XCFVG *zone,
|
||||||
|
XCBaseObject *&objects[],
|
||||||
|
//
|
||||||
|
bool drawStartedBar = true,
|
||||||
|
bool drawActivatedBar = true,
|
||||||
|
bool drawBreakedBar = true,
|
||||||
|
bool drawWorkedBar = true,
|
||||||
|
//
|
||||||
|
int widthStartedBar = 1,
|
||||||
|
color clrStartedBar = clrYellow,
|
||||||
|
ENUM_LINE_STYLE styleStartedBar = STYLE_SOLID,
|
||||||
|
//
|
||||||
|
int widthActivatedBar = 1,
|
||||||
|
color clrActivatedBar = clrLime,
|
||||||
|
ENUM_LINE_STYLE styleActivatedBar = STYLE_SOLID,
|
||||||
|
//
|
||||||
|
int widthBreakedBar = 1,
|
||||||
|
color clrBreakedBar = clrRed,
|
||||||
|
ENUM_LINE_STYLE styleBreakedBar = STYLE_SOLID,
|
||||||
|
//
|
||||||
|
int widthWorkedBar = 1,
|
||||||
|
color clrWorkedBar = clrAqua,
|
||||||
|
ENUM_LINE_STYLE styleWorkedBar = STYLE_SOLID
|
||||||
|
//
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(objects);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (zone == NULL ||
|
||||||
|
!zone.IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_X_DIRECTION zoneDir = zone.GetDirection();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Started Bar ...
|
||||||
|
XOHCL startedBar;
|
||||||
|
bool isBodyOut = false;
|
||||||
|
bool isStarted = zone
|
||||||
|
.IsStarted(
|
||||||
|
zoneDir,
|
||||||
|
startedBar,
|
||||||
|
isBodyOut //
|
||||||
|
);
|
||||||
|
if (isStarted)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = startedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
startedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthStartedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthStartedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthStartedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleStartedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleStartedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleStartedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrStartedBar);
|
||||||
|
iBarObj.LowShadowColor(clrStartedBar);
|
||||||
|
iBarObj.HighShadowColor(clrStartedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Activated Bar ...
|
||||||
|
XOHCL activatedBar;
|
||||||
|
bool isBodyIn = false;
|
||||||
|
bool isActivated = zone
|
||||||
|
.IsActivated(
|
||||||
|
zoneDir,
|
||||||
|
activatedBar,
|
||||||
|
isBodyIn,
|
||||||
|
false // Force Body Out Started ...
|
||||||
|
);
|
||||||
|
if (isActivated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = activatedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
activatedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthActivatedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthActivatedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthActivatedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleActivatedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleActivatedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleActivatedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrActivatedBar);
|
||||||
|
iBarObj.LowShadowColor(clrActivatedBar);
|
||||||
|
iBarObj.HighShadowColor(clrActivatedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Breaked Bar ...
|
||||||
|
XOHCL breakedBar;
|
||||||
|
isBodyOut = false;
|
||||||
|
bool isBreaked = zone
|
||||||
|
.IsBreaked(
|
||||||
|
zoneDir,
|
||||||
|
breakedBar,
|
||||||
|
isBodyOut,
|
||||||
|
false, // Ignore Start ...
|
||||||
|
false // Force Body Out Started ...
|
||||||
|
);
|
||||||
|
if (isBreaked)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = breakedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
breakedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthBreakedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthBreakedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthBreakedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleBreakedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleBreakedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleBreakedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrBreakedBar);
|
||||||
|
iBarObj.LowShadowColor(clrBreakedBar);
|
||||||
|
iBarObj.HighShadowColor(clrBreakedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Worked Bar ...
|
||||||
|
XOHCL workedBar;
|
||||||
|
isBodyOut = false;
|
||||||
|
bool isWorked = zone
|
||||||
|
.IsWorked(
|
||||||
|
zoneDir,
|
||||||
|
workedBar,
|
||||||
|
isBodyOut,
|
||||||
|
false, // Ignore Activation ...
|
||||||
|
false, // Force Body Out Started ...
|
||||||
|
false // Force Body In Activated ...
|
||||||
|
);
|
||||||
|
if (isWorked)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
datetime iBarTo = workedBar.NextAt();
|
||||||
|
|
||||||
|
//
|
||||||
|
XCOHCLObject *iBarObj;
|
||||||
|
bool isCreated = CreateBar(
|
||||||
|
workedBar,
|
||||||
|
iBarObj,
|
||||||
|
iBarTo //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iBarObj.BodyWidth(widthWorkedBar);
|
||||||
|
iBarObj.LowShadowWidth(widthWorkedBar);
|
||||||
|
iBarObj.HighShadowWidth(widthWorkedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyStyle(styleWorkedBar);
|
||||||
|
iBarObj.LowShadowStyle(styleWorkedBar);
|
||||||
|
iBarObj.HighShadowStyle(styleWorkedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
iBarObj.BodyColor(clrWorkedBar);
|
||||||
|
iBarObj.LowShadowColor(clrWorkedBar);
|
||||||
|
iBarObj.HighShadowColor(clrWorkedBar);
|
||||||
|
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iBarObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBaseObject *iObj;
|
||||||
|
bool isCreated = CreateFairValueGap(
|
||||||
|
zone,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
(XCBaseObject *)iObj,
|
||||||
|
objects //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(objects);
|
||||||
|
|
||||||
|
//
|
||||||
|
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
@@ -0,0 +1,543 @@
|
|||||||
|
//
|
||||||
|
bool HasSenario1Conditions(
|
||||||
|
ENUM_X_CYCLES cycle,
|
||||||
|
XBoxZone &box,
|
||||||
|
XBoxZone &holderBox,
|
||||||
|
ENUM_X_DIRECTION &dir,
|
||||||
|
X121SMCStrategySignalProviderData &provider,
|
||||||
|
ENUM_X_CYCLES holderCycle = X_CYCLE_NONE,
|
||||||
|
int barIndex = 0 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fil Selected Data ...
|
||||||
|
XPOIState cState;
|
||||||
|
X121Conditions cXConditions;
|
||||||
|
XC121SMCCycleHelper *cHelper;
|
||||||
|
X121SMCCycleConditions cConditions;
|
||||||
|
result = provider.SelectCycle(
|
||||||
|
cycle,
|
||||||
|
cState,
|
||||||
|
cXConditions,
|
||||||
|
cHelper,
|
||||||
|
cConditions //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
cState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Parse(cXConditions);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fil Selected Data ...
|
||||||
|
XPOIState chState;
|
||||||
|
X121Conditions chXConditions;
|
||||||
|
XC121SMCCycleHelper *chHelper;
|
||||||
|
X121SMCCycleConditions chConditions;
|
||||||
|
if (holderCycle != X_CYCLE_NONE)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = provider.SelectCycle(
|
||||||
|
holderCycle,
|
||||||
|
chState,
|
||||||
|
chXConditions,
|
||||||
|
chHelper,
|
||||||
|
chConditions //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
chState.Clean();
|
||||||
|
ZeroMemory(chHelper);
|
||||||
|
chConditions.Clean();
|
||||||
|
chXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Parse(chXConditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normalize Args ...
|
||||||
|
|
||||||
|
//
|
||||||
|
box.Clean();
|
||||||
|
holderBox.Clean();
|
||||||
|
dir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = false;
|
||||||
|
bool isBearish = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
XOHCL cBar;
|
||||||
|
XOHCL pBar;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initial Bars ...
|
||||||
|
result = zBar.Init(
|
||||||
|
cState.symbol,
|
||||||
|
cState.period,
|
||||||
|
barIndex //
|
||||||
|
);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
zBar.GetPreviousBar(cBar);
|
||||||
|
result =
|
||||||
|
result &&
|
||||||
|
cBar.GetPreviousBar(pBar);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
cState.Clean();
|
||||||
|
chState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
ZeroMemory(chHelper);
|
||||||
|
chConditions.Clean();
|
||||||
|
chXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detecting Signal Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isX3MAFastRejectUp =
|
||||||
|
//
|
||||||
|
cBar.low < cXConditions.x3maFastBuffer[cIDX] &&
|
||||||
|
cBar.GetDown() > cXConditions.x3maFastBuffer[cIDX]
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isX3MAFastRejectDown =
|
||||||
|
//
|
||||||
|
cBar.high > cXConditions.x3maFastBuffer[cIDX] &&
|
||||||
|
cBar.GetUp() < cXConditions.x3maFastBuffer[cIDX]
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find Breaker Bar ...
|
||||||
|
datetime nearCloseOverX3MAFast = cHelper.GetNearestCloseOverX3MAFast(cBar);
|
||||||
|
datetime nearCloseUnderX3MAFast = cHelper.GetNearestCloseUnderX3MAFast(cBar);
|
||||||
|
bool hasNearestCloseOverX3MAFast =
|
||||||
|
IsValid(nearCloseOverX3MAFast) &&
|
||||||
|
IsValid(nearCloseUnderX3MAFast)
|
||||||
|
? nearCloseOverX3MAFast > nearCloseUnderX3MAFast
|
||||||
|
: IsValid(nearCloseOverX3MAFast)
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
bool hasNearestCloseUnderX3MAFast =
|
||||||
|
IsValid(nearCloseOverX3MAFast) &&
|
||||||
|
IsValid(nearCloseUnderX3MAFast)
|
||||||
|
? nearCloseUnderX3MAFast > nearCloseOverX3MAFast
|
||||||
|
: IsValid(nearCloseUnderX3MAFast)
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish Conditions ...
|
||||||
|
isBullish =
|
||||||
|
//
|
||||||
|
// Base Condition ...
|
||||||
|
(
|
||||||
|
//
|
||||||
|
cBar.IsBullish() &&
|
||||||
|
isX3MAFastRejectUp &&
|
||||||
|
cXConditions.isSMHKBullish &&
|
||||||
|
hasNearestCloseOverX3MAFast &&
|
||||||
|
cXConditions.xhkSMOpenBuffer[cIDX] < cXConditions.x3maMidBuffer[cIDX]
|
||||||
|
//
|
||||||
|
)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish Conditions ...
|
||||||
|
isBearish =
|
||||||
|
//
|
||||||
|
// Base Condition ...
|
||||||
|
(
|
||||||
|
//
|
||||||
|
cBar.IsBearish() &&
|
||||||
|
isX3MAFastRejectDown &&
|
||||||
|
cXConditions.isSMHKBearish &&
|
||||||
|
hasNearestCloseUnderX3MAFast &&
|
||||||
|
cXConditions.xhkSMOpenBuffer[cIDX] > cXConditions.x3maMidBuffer[cIDX]
|
||||||
|
//
|
||||||
|
)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Filling Requirements ...
|
||||||
|
result =
|
||||||
|
isBullish ||
|
||||||
|
isBearish;
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
dir =
|
||||||
|
isBullish
|
||||||
|
? X_DIRECTION_BULLISH
|
||||||
|
: X_DIRECTION_BEARISH;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.dir = dir;
|
||||||
|
box.to = TimeCurrent();
|
||||||
|
box.symbol = cXConditions.symbol;
|
||||||
|
box.period = cXConditions.period;
|
||||||
|
|
||||||
|
//
|
||||||
|
int fromIDX = -1;
|
||||||
|
if (isBullish)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX = GetBarIndex(
|
||||||
|
cBar.symbol,
|
||||||
|
cBar.period,
|
||||||
|
nearCloseOverX3MAFast //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
fromIDX = GetBarIndex(
|
||||||
|
cBar.symbol,
|
||||||
|
cBar.period,
|
||||||
|
nearCloseUnderX3MAFast //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (IsValidIndex(fromIDX))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
box.from = iTime(
|
||||||
|
zBar.symbol,
|
||||||
|
zBar.period,
|
||||||
|
fromIDX //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
box.from = pBar.time;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detect Holder Box ...
|
||||||
|
XBoxZone tmpBoxes[];
|
||||||
|
if (chState.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (isBullish)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Demand Zones ...
|
||||||
|
XBoxZone tmp[];
|
||||||
|
ToBox(
|
||||||
|
chState.demandZones,
|
||||||
|
tmp //
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
tmp,
|
||||||
|
tmpBoxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
Clean(tmp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish Order Blocks ...
|
||||||
|
ToBox(
|
||||||
|
chState.bullishOrderBlocks,
|
||||||
|
tmp //
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
tmp,
|
||||||
|
tmpBoxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
Clean(tmp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish Fair Value Gaps ...
|
||||||
|
ToBox(
|
||||||
|
chState.bullishFairValueGaps,
|
||||||
|
tmp //
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
tmp,
|
||||||
|
tmpBoxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
Clean(tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Supply Zones ...
|
||||||
|
XBoxZone tmp[];
|
||||||
|
ToBox(
|
||||||
|
chState.supplyZones,
|
||||||
|
tmp //
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
tmp,
|
||||||
|
tmpBoxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
Clean(tmp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish Order Blocks ...
|
||||||
|
ToBox(
|
||||||
|
chState.bearishOrderBlocks,
|
||||||
|
tmp //
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
tmp,
|
||||||
|
tmpBoxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
Clean(tmp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish Fair Value Gaps ...
|
||||||
|
ToBox(
|
||||||
|
chState.bearishFairValueGaps,
|
||||||
|
tmp //
|
||||||
|
);
|
||||||
|
Copy(
|
||||||
|
tmp,
|
||||||
|
tmpBoxes,
|
||||||
|
false //
|
||||||
|
);
|
||||||
|
Clean(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
has = HasChild(tmpBoxes);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
while (HasChild(tmpBoxes))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
idx = GetOldest(tmpBoxes);
|
||||||
|
has = IsValidIndex(idx);
|
||||||
|
if (!has)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XBoxZone iBox = tmpBoxes[idx];
|
||||||
|
ArrayRemove(
|
||||||
|
tmpBoxes,
|
||||||
|
idx,
|
||||||
|
1 //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
has = IsBoxInside(
|
||||||
|
box,
|
||||||
|
iBox //
|
||||||
|
);
|
||||||
|
if (has)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
holderBox = iBox;
|
||||||
|
holderBox.to = TimeCurrent();
|
||||||
|
iBox.Clean();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
iBox.Clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(tmpBoxes);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fix Box Upper and Lower based on Strategy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double points = GetPoints(box.symbol);
|
||||||
|
double minPointsDiff = points * 20;
|
||||||
|
|
||||||
|
//
|
||||||
|
double prefferSL = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Other SL Conditions ...
|
||||||
|
if (prefferSL <= 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
prefferSL = cHelper
|
||||||
|
.mX121Helper
|
||||||
|
.xhkHelper
|
||||||
|
.GetSMHKOpen(fromIDX);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (prefferSL > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
box.upper =
|
||||||
|
isBullish
|
||||||
|
? zBar.open
|
||||||
|
: prefferSL;
|
||||||
|
|
||||||
|
//
|
||||||
|
box.lower =
|
||||||
|
isBullish
|
||||||
|
? prefferSL
|
||||||
|
: zBar.open;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (box.IsValid())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
XCBoxObject *iObj;
|
||||||
|
bool isCreated = cHelper.mPOIDrawer.DrawBox(
|
||||||
|
box,
|
||||||
|
iObj //
|
||||||
|
);
|
||||||
|
if (isCreated)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
iObj.BoxWidth(2);
|
||||||
|
iObj.BoxFill(true);
|
||||||
|
iObj.BoxStyle(STYLE_DOT);
|
||||||
|
|
||||||
|
//
|
||||||
|
Print("Signal ...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Conditions to Force Has Holder Box ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// result =
|
||||||
|
// result &&
|
||||||
|
// holderBox.IsValid() &&
|
||||||
|
// dir == holderBox.dir;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// isBullish = false;
|
||||||
|
// isBearish = false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check All Conditions ...
|
||||||
|
result =
|
||||||
|
box.IsValid() &&
|
||||||
|
HasDirection(dir) &&
|
||||||
|
(isBullish ||
|
||||||
|
isBearish);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
cState.Clean();
|
||||||
|
chState.Clean();
|
||||||
|
ZeroMemory(cHelper);
|
||||||
|
cConditions.Clean();
|
||||||
|
cXConditions.Clean();
|
||||||
|
ZeroMemory(chHelper);
|
||||||
|
chConditions.Clean();
|
||||||
|
chXConditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//
|
||||||
|
// Detecting Signal Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bullish Conditions ...
|
||||||
|
isBullish =
|
||||||
|
//
|
||||||
|
// Base Condition ...
|
||||||
|
(
|
||||||
|
//
|
||||||
|
provider.visionXConditions.isSMHKBullish &&
|
||||||
|
provider.decisionXConditions.isSarBullish &&
|
||||||
|
provider.decisionXConditions.isVWapFastBullish &&
|
||||||
|
provider.decisionXConditions.isX3MaFastBullish &&
|
||||||
|
provider.consolidationXConditions.isSMHKBullish &&
|
||||||
|
provider.decisionXConditions.isSMHKSwitchedToBullish
|
||||||
|
//
|
||||||
|
)
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Bearish Conditions ...
|
||||||
|
isBearish =
|
||||||
|
//
|
||||||
|
// Base Condition ...
|
||||||
|
(
|
||||||
|
//
|
||||||
|
provider.visionXConditions.isSMHKBearish &&
|
||||||
|
provider.decisionXConditions.isSarBearish &&
|
||||||
|
provider.decisionXConditions.isVWapFastBearish &&
|
||||||
|
provider.decisionXConditions.isX3MaFastBearish &&
|
||||||
|
provider.consolidationXConditions.isSMHKBearish &&
|
||||||
|
provider.decisionXConditions.isSMHKSwitchedToBearish
|
||||||
|
//
|
||||||
|
)
|
||||||
|
//
|
||||||
|
;
|
||||||
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,197 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Forex Sessions and Day Range Indicator |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Your Name"
|
||||||
|
#property link "https://www.example.com"
|
||||||
|
#property version "1.00"
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
#include <Arrays\ArrayObj.mqh>
|
||||||
|
|
||||||
|
struct SessionInfo {
|
||||||
|
string name;
|
||||||
|
int startHour; // Standard start hour (GMT)
|
||||||
|
int startMinute;
|
||||||
|
int endHour; // Standard end hour (GMT)
|
||||||
|
int endMinute;
|
||||||
|
bool *isDST(datetime); // DST check function
|
||||||
|
int dstAdjustment; // Hours to add during DST
|
||||||
|
};
|
||||||
|
|
||||||
|
SessionInfo sessions[] = {
|
||||||
|
{"Sydney", 21, 0, 5, 0, IsSydneyDST, 1},
|
||||||
|
{"Tokyo", 23, 0, 8, 0, IsTokyoDST, 0},
|
||||||
|
{"London", 7, 0, 15, 0, IsLondonDST, 1},
|
||||||
|
{"New York", 12, 0, 17, 0, IsNewYorkDST, 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool sessionActive[];
|
||||||
|
double sessionHigh[];
|
||||||
|
double sessionLow[];
|
||||||
|
datetime sessionStartTime[];
|
||||||
|
datetime sessionEndTime[];
|
||||||
|
|
||||||
|
double dayHigh = 0;
|
||||||
|
double dayLow = 0;
|
||||||
|
datetime dayStartTime;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit() {
|
||||||
|
ArrayResize(sessionActive, ArraySize(sessions));
|
||||||
|
ArrayResize(sessionHigh, ArraySize(sessions));
|
||||||
|
ArrayResize(sessionLow, ArraySize(sessions));
|
||||||
|
ArrayResize(sessionStartTime, ArraySize(sessions));
|
||||||
|
ArrayResize(sessionEndTime, ArraySize(sessions));
|
||||||
|
|
||||||
|
for(int i=0; i<ArraySize(sessions); i++) {
|
||||||
|
sessionActive[i] = false;
|
||||||
|
sessionHigh[i] = 0;
|
||||||
|
sessionLow[i] = 0;
|
||||||
|
sessionStartTime[i] = 0;
|
||||||
|
sessionEndTime[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dayHigh = 0;
|
||||||
|
dayLow = 0;
|
||||||
|
dayStartTime = 0;
|
||||||
|
|
||||||
|
return(INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator iteration function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
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[]) {
|
||||||
|
datetime currentTime = TimeCurrent();
|
||||||
|
|
||||||
|
// Check each session
|
||||||
|
for(int i=0; i<ArraySize(sessions); i++) {
|
||||||
|
SessionInfo session = sessions[i];
|
||||||
|
bool dstActive = session.isDST(currentTime);
|
||||||
|
int adjStartHour = session.startHour + (dstActive ? session.dstAdjustment : 0);
|
||||||
|
int adjEndHour = session.endHour + (dstActive ? session.dstAdjustment : 0);
|
||||||
|
|
||||||
|
datetime todayStart = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
|
||||||
|
IntegerToString(adjStartHour) + ":" +
|
||||||
|
IntegerToString(session.startMinute));
|
||||||
|
datetime todayEnd = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
|
||||||
|
IntegerToString(adjEndHour) + ":" +
|
||||||
|
IntegerToString(session.endMinute));
|
||||||
|
|
||||||
|
// Handle sessions spanning midnight
|
||||||
|
if(adjEndHour < adjStartHour) {
|
||||||
|
todayEnd += 24 * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentTime >= todayStart && currentTime < todayEnd) {
|
||||||
|
if(!sessionActive[i]) {
|
||||||
|
sessionActive[i] = true;
|
||||||
|
sessionStartTime[i] = todayStart;
|
||||||
|
sessionEndTime[i] = todayEnd;
|
||||||
|
sessionHigh[i] = Bid;
|
||||||
|
sessionLow[i] = Ask;
|
||||||
|
} else {
|
||||||
|
if(Bid > sessionHigh[i]) sessionHigh[i] = Bid;
|
||||||
|
if(Ask < sessionLow[i]) sessionLow[i] = Ask;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sessionActive[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check day range
|
||||||
|
bool dstActiveNY = IsNewYorkDST(currentTime);
|
||||||
|
int dayStartHour = dstActiveNY ? 21 : 22;
|
||||||
|
datetime todayDayStart = StringToTime(TimeToString(currentTime, TIME_DATE) + " " +
|
||||||
|
IntegerToString(dayStartHour) + ":00");
|
||||||
|
|
||||||
|
if(currentTime < todayDayStart) {
|
||||||
|
todayDayStart -= 24 * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dayStartTime != todayDayStart) {
|
||||||
|
dayStartTime = todayDayStart;
|
||||||
|
dayHigh = Bid;
|
||||||
|
dayLow = Ask;
|
||||||
|
} else {
|
||||||
|
if(Bid > dayHigh) dayHigh = Bid;
|
||||||
|
if(Ask < dayLow) dayLow = Ask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display information on chart
|
||||||
|
string comment = "Active Forex Sessions:\n";
|
||||||
|
for(int i=0; i<ArraySize(sessions); i++) {
|
||||||
|
if(sessionActive[i]) {
|
||||||
|
comment += sessions[i].name + " Session\n" +
|
||||||
|
"High: " + DoubleToString(sessionHigh[i], _Digits) + "\n" +
|
||||||
|
"Low: " + DoubleToString(sessionLow[i], _Digits) + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
comment += "\nDay Range:\n" +
|
||||||
|
"High: " + DoubleToString(dayHigh, _Digits) + "\n" +
|
||||||
|
"Low: " + DoubleToString(dayLow, _Digits);
|
||||||
|
Comment(comment);
|
||||||
|
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| DST Check Functions |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool IsLondonDST(datetime time) {
|
||||||
|
int year = TimeYear(time);
|
||||||
|
datetime march31 = StringToTime(year + ".03.31 00:00");
|
||||||
|
int lastSundayMarch = TimeDay(march31) - (TimeDayOfWeek(march31) % 7);
|
||||||
|
datetime dstStart = StringToTime(year + ".03." + IntegerToString(lastSundayMarch) + " 01:00");
|
||||||
|
|
||||||
|
datetime oct31 = StringToTime(year + ".10.31 00:00");
|
||||||
|
int lastSundayOct = TimeDay(oct31) - (TimeDayOfWeek(oct31) % 7);
|
||||||
|
datetime dstEnd = StringToTime(year + ".10." + IntegerToString(lastSundayOct) + " 01:00");
|
||||||
|
|
||||||
|
return time >= dstStart && time < dstEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsNewYorkDST(datetime time) {
|
||||||
|
int year = TimeYear(time);
|
||||||
|
datetime march1 = StringToTime(year + ".03.01 00:00");
|
||||||
|
int dayOfWeekMarch1 = TimeDayOfWeek(march1);
|
||||||
|
int secondSundayMarch = 1 + (7 - dayOfWeekMarch1) % 7 + 7;
|
||||||
|
datetime dstStart = StringToTime(year + ".03." + IntegerToString(secondSundayMarch) + " 07:00");
|
||||||
|
|
||||||
|
datetime nov1 = StringToTime(year + ".11.01 00:00");
|
||||||
|
int dayOfWeekNov1 = TimeDayOfWeek(nov1);
|
||||||
|
int firstSundayNov = 1 + (7 - dayOfWeekNov1) % 7;
|
||||||
|
datetime dstEnd = StringToTime(year + ".11." + IntegerToString(firstSundayNov) + " 06:00");
|
||||||
|
|
||||||
|
return time >= dstStart && time < dstEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSydneyDST(datetime time) {
|
||||||
|
int year = TimeYear(time);
|
||||||
|
datetime oct1 = StringToTime(year + ".10.01 00:00");
|
||||||
|
int dayOfWeekOct1 = TimeDayOfWeek(oct1);
|
||||||
|
int firstSundayOct = 1 + (7 - dayOfWeekOct1) % 7;
|
||||||
|
datetime dstStart = StringToTime(year + ".10." + IntegerToString(firstSundayOct) + " 13:00");
|
||||||
|
|
||||||
|
datetime apr1 = StringToTime(year + ".04.01 00:00");
|
||||||
|
int dayOfWeekApr1 = TimeDayOfWeek(apr1);
|
||||||
|
int firstSundayApr = 1 + (7 - dayOfWeekApr1) % 7;
|
||||||
|
datetime dstEnd = StringToTime(year + ".04." + IntegerToString(firstSundayApr) + " 15:00");
|
||||||
|
|
||||||
|
return time >= dstStart && time < dstEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsTokyoDST(datetime time) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,377 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| x-saherelm.xpoi.test.ea.mq5 |
|
||||||
|
//| SaherElm IT Center |
|
||||||
|
//| https://www.saherelm.ir |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "SaherElm IT Center"
|
||||||
|
#property link "https://www.saherelm.ir"
|
||||||
|
#property version "1.00"
|
||||||
|
|
||||||
|
//
|
||||||
|
#include "../Classes/x-saherelm.x-poi.class.mq5"
|
||||||
|
#include "../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
||||||
|
#include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
|
||||||
|
#include "../Libraries/x-saherelm.x-poi.state.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
#include "../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Global Variables ...
|
||||||
|
|
||||||
|
//
|
||||||
|
XCPOIDrawer *mPOIDrawer;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCPOIDetector *mPOIDetector;
|
||||||
|
XBarTracker mBarTracker;
|
||||||
|
XCBarAnalyser *mBarAnalyser;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool useDetector = true;
|
||||||
|
bool useBarAnalyser = false;
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mPOIDetector = new XCPOIDetector(
|
||||||
|
_Symbol,
|
||||||
|
_Period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
mPOIDrawer = new XCPOIDrawer();
|
||||||
|
|
||||||
|
//
|
||||||
|
mBarAnalyser = new XCBarAnalyser();
|
||||||
|
|
||||||
|
//
|
||||||
|
mBarTracker.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
return (INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// ZeroMemory(mPOIDrawer);
|
||||||
|
// ZeroMemory(mPOIDetector);
|
||||||
|
ZeroMemory(mBarAnalyser);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
DetectBarAnalyser();
|
||||||
|
|
||||||
|
//
|
||||||
|
DetectPOIState();
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom Functions |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect POI(s) Using Bar Analyser Class ...
|
||||||
|
*/
|
||||||
|
void DetectBarAnalyser()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!useBarAnalyser)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!mBarTracker.IsNewBar())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
bool isInited = zBar.Init(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL cBar;
|
||||||
|
isInited = zBar.GetPreviousBar(cBar);
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int rootIDX = -1;
|
||||||
|
XOHCL selectedBar;
|
||||||
|
ENUM_X_DIRECTION dir;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Big Change in Price ...
|
||||||
|
bool isBigChange = mBarAnalyser.IsSharp(
|
||||||
|
zBar, // Bar ...
|
||||||
|
dir, // Change Direction ...
|
||||||
|
rootIDX, // Change Root IDX ...
|
||||||
|
X_PRICE_CLOSE, // Price Change Type ...
|
||||||
|
true, // Force Use Body for Range Calculation ...
|
||||||
|
1.0 // Range Extend Multiplier ...
|
||||||
|
);
|
||||||
|
if (isBigChange)
|
||||||
|
{
|
||||||
|
Print("Big Price Change Detected: ", ToString(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Big Change in Price ...
|
||||||
|
bool isSpike = mBarAnalyser.IsSpike(
|
||||||
|
zBar, // Bar ...
|
||||||
|
dir, // Change Direction ...
|
||||||
|
rootIDX, // Root Index ...
|
||||||
|
X_PRICE_CLOSE, // Price Change Type ...
|
||||||
|
true, // Force Use Body for Range Calculation ...
|
||||||
|
1.0, // Range Extend Multiplier ...
|
||||||
|
3 // Same Bars ...
|
||||||
|
);
|
||||||
|
if (isSpike)
|
||||||
|
{
|
||||||
|
Print("Spike Detected: ", ToString(dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Doji Pattern ...
|
||||||
|
bool isDoji = mBarAnalyser.IsDoji(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isDoji)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Doji Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Hammer Pattern ...
|
||||||
|
bool isHammer = mBarAnalyser.IsHammer(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isHammer)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Hammer Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Engulf Pattern ...
|
||||||
|
bool isEngulfed = mBarAnalyser.IsEngulfed(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isEngulfed)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Engulfed Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Momentum Pattern ...
|
||||||
|
bool isMomentum = mBarAnalyser.IsMomentum(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isMomentum)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Momentum Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Pullback Pattern ...
|
||||||
|
bool isPullback = mBarAnalyser.IsPullback(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isMomentum)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Pullback Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Swing Pattern ...
|
||||||
|
bool isSwing = mBarAnalyser.IsSwing(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isSwing)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Swing Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Swing Pattern ...
|
||||||
|
bool isRejected = mBarAnalyser.IsRejected(
|
||||||
|
cBar,
|
||||||
|
dir //
|
||||||
|
);
|
||||||
|
if (isRejected)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Rejected Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Support ...
|
||||||
|
bool isSupport = mBarAnalyser.HasSupport(
|
||||||
|
cBar,
|
||||||
|
selectedBar //
|
||||||
|
);
|
||||||
|
if (isSupport)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Support Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Resistance ...
|
||||||
|
bool isResistance = mBarAnalyser.HasResistance(
|
||||||
|
cBar,
|
||||||
|
selectedBar //
|
||||||
|
);
|
||||||
|
if (isResistance)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " Resistance Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Fair Value Gap ...
|
||||||
|
XOHCL toBar;
|
||||||
|
XOHCL fromBar;
|
||||||
|
bool hasFVG = mBarAnalyser.HasFairValueGap(
|
||||||
|
zBar,
|
||||||
|
fromBar,
|
||||||
|
toBar,
|
||||||
|
dir,
|
||||||
|
3 //
|
||||||
|
);
|
||||||
|
if (hasFVG)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " FairValueGap Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Order Block ...
|
||||||
|
bool hasOB = mBarAnalyser.HasOrderBlock(
|
||||||
|
zBar,
|
||||||
|
selectedBar,
|
||||||
|
dir,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true //
|
||||||
|
);
|
||||||
|
if (hasOB)
|
||||||
|
{
|
||||||
|
Print(ToString(dir), " OrderBlock Detected ...");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup Resources ...
|
||||||
|
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect POI(s) Using POIDetector Class ...
|
||||||
|
*/
|
||||||
|
void DetectPOIState()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!useDetector)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!mBarTracker.IsNewBar())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_XPOI_EVENTS poiEvents[];
|
||||||
|
XPOIStateEvents poiEventNotifier;
|
||||||
|
mPOIDetector.Update(
|
||||||
|
poiEvents,
|
||||||
|
0 //
|
||||||
|
);
|
||||||
|
poiEventNotifier.Init(poiEvents);
|
||||||
|
|
||||||
|
//
|
||||||
|
XPOIState state;
|
||||||
|
mPOIDetector.GetState(state);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool showBullishPOIs = true;
|
||||||
|
bool showBearishPOIs = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
XCBaseObject *stateObjects[];
|
||||||
|
mPOIDrawer.DrawState(
|
||||||
|
state,
|
||||||
|
stateObjects,
|
||||||
|
//
|
||||||
|
// Bullish ...
|
||||||
|
showBullishPOIs && false, // SwingLows
|
||||||
|
showBullishPOIs && false, // DemandZones
|
||||||
|
showBullishPOIs && false, // SupportZones
|
||||||
|
showBullishPOIs && false, // BullishSharps
|
||||||
|
showBullishPOIs && false, // BullishSpikes
|
||||||
|
showBullishPOIs && false, // BullishPullbacks
|
||||||
|
showBullishPOIs && false, // BullishMomentums
|
||||||
|
showBullishPOIs && false, // BullishRejections
|
||||||
|
showBullishPOIs && false, // BullishOrderBlocks
|
||||||
|
showBullishPOIs && false, // BullishFairValueGaps
|
||||||
|
showBullishPOIs && false, // BullishConsolidationZones
|
||||||
|
//
|
||||||
|
// Bearish ...
|
||||||
|
showBearishPOIs && false, // SwingHighs
|
||||||
|
showBearishPOIs && false, // SupplyZones
|
||||||
|
showBearishPOIs && false, // ResistanceZones
|
||||||
|
showBearishPOIs && false, // BearishSharps
|
||||||
|
showBearishPOIs && false, // BearishSpikes
|
||||||
|
showBearishPOIs && false, // BearishPullbacks
|
||||||
|
showBearishPOIs && false, // BearishMomentums
|
||||||
|
showBearishPOIs && false, // BearishRejections
|
||||||
|
showBearishPOIs && false, // BearishOrderBlocks
|
||||||
|
showBearishPOIs && false, // BearishFairValueGaps
|
||||||
|
showBearishPOIs && false // BearishConsolidationZones
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(poiEvents);
|
||||||
|
poiEventNotifier.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
@@ -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,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,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,462 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center XTest MQL5 Expert Advisor
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121SMCEA
|
||||||
|
// 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 X121SMCEA"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121SMCEA"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../X121SMCEA/Experts/x-121.smc.expert.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
input group "Common";
|
||||||
|
input long eaMagicNumber = 78692110; // Magic Number
|
||||||
|
input int eaSlippage = 10; // Slippgae
|
||||||
|
input string eaLogSuffix = ""; // Log Suffix
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbols ...
|
||||||
|
input group "Symbols";
|
||||||
|
input bool eaMultiSymbol = false; // Use Multi Symbol
|
||||||
|
input string eaSymbols = "EURUSDb,GBPUSDb,USDCHFb,USDJPYb"; // Trading Symbols
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signalling ...
|
||||||
|
input group "Signalling";
|
||||||
|
input bool eaAllowLong = true; // Allow Long Signals
|
||||||
|
input bool eaAllowShort = true; // Allow Short Signals
|
||||||
|
input int eaMaxAllowedLongs = 5; // Max Allowed Long Signals
|
||||||
|
input int eaMaxAllowedShorts = 5; // Max Allowed Short Signals
|
||||||
|
input bool eaUseMaxAllowedSignalsPerSymbol = true; // Use Max Allowed Signal Types Per Symbol
|
||||||
|
input double eaLastPositionProfitForAcceptNextInPoint = 0; // Last Position Profit In Points for Accept new Signal
|
||||||
|
input int eaDelaysBetweenTwoSignalsInBar = 0; // Delay between two Signals in Bars
|
||||||
|
input double eaMaxAllowedSpread = 0; // Max Allowed Spread for Signalling
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trade ...
|
||||||
|
input group "Trade";
|
||||||
|
input bool eaAllowTrade = true; // Allow Open Trade On Signals
|
||||||
|
input string eaStartTradeAt = ""; // Enable Trade on Signals on Time
|
||||||
|
input string eaStopTradeAt = ""; // Enable Trade on Signals on Time
|
||||||
|
input string eaCloseAllTradesAt = ""; // Enable Close All Trades on Signals on Time
|
||||||
|
|
||||||
|
//
|
||||||
|
// Risk Management ...
|
||||||
|
input group "Risk Management";
|
||||||
|
input double eaR2R = 6; // Signallers Risk to Reward Ratio
|
||||||
|
input double eaVolume = 0; // Static Volume
|
||||||
|
input double eaStaticBalance = 1000; // Static Balance
|
||||||
|
input double eaBalancePerTrade = 5; // Balance Used in Each Trade
|
||||||
|
input double eaRiskPercentPerBalance = 0; // Risk Percent Per Balance in Each Trade
|
||||||
|
input bool eaDynamicRiskManagement = false; // Dynamic Risk Management
|
||||||
|
input bool eaUseDynamicVolume = false; // Use Dynamic Volume
|
||||||
|
input double eaDynamicVolumeStep = 0.01; // Increase Volume Step
|
||||||
|
input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume
|
||||||
|
input double eaMaxAllowedDrawdownToOpenTrades = 3; // Max Allowed Drawdown for Open Trades
|
||||||
|
input int eaMaxAllowedSLToPauseSignallingPerSymbol = 0; // Max Allowed SL for Pause Signalling Per Symbol
|
||||||
|
input int eaPauseSignallingAfterReachesMaxAllowedSLInSecconds = 0; // Pause Signalling Per Symbol afte Max Allowed SL Reached In Seconds
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protection ...
|
||||||
|
input group "Protection";
|
||||||
|
input bool eaAllowHedging = false; // Allow Hedge Positions
|
||||||
|
input int eaMinOpenTradesFroHedging = 4; // Minimum Open Positions for Hedging
|
||||||
|
input double eaHedgingMinVolumeStep = 0.01; // Minimum Volume Step for Hedging
|
||||||
|
input double eaHedgeingMinRequiredProfitPerVolumeStep = 1.0; // Minimum Required Profit Per Volume Step for Hedging
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
//
|
||||||
|
// Define Local Variables ...
|
||||||
|
|
||||||
|
XC121SMCExpert *eaExpert;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure EA Expert Class ...
|
||||||
|
eaExpert = new XC121SMCExpert();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
eaExpert.OnSignalEventListener = OnSignalRecieved;
|
||||||
|
eaExpert.OnDealsChangedEventListener = OnDealsChanged;
|
||||||
|
eaExpert.OnOrdersChangedEventListener = OnOrdersChanged;
|
||||||
|
eaExpert.OnPositionSLEventListener = OnStopLossTriggered;
|
||||||
|
eaExpert.OnPositionTPEventListener = OnTakeProfitTriggered;
|
||||||
|
eaExpert.OnPositionsChangedEventListener = OnPositionsChanged;
|
||||||
|
eaExpert.OnPositionForceCloseEventListener = OnPositionForceClosed;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
eaExpert.MagicNumber(eaMagicNumber);
|
||||||
|
eaExpert.Slippage(eaSlippage);
|
||||||
|
eaExpert.TagPrefix(eaLogSuffix);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Symbol ...
|
||||||
|
eaExpert.SetSymbol(_Symbol);
|
||||||
|
eaExpert.SetPeriod(_Period);
|
||||||
|
eaExpert.Symbols(eaSymbols);
|
||||||
|
eaExpert.MultiSymbol(eaMultiSymbol);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Signalling ...
|
||||||
|
eaExpert.AllowLong(eaAllowLong);
|
||||||
|
eaExpert.AllowShort(eaAllowShort);
|
||||||
|
eaExpert.MaxAllowedLongs(eaMaxAllowedLongs);
|
||||||
|
eaExpert.MaxAllowedShorts(eaMaxAllowedShorts);
|
||||||
|
eaExpert.UseMaxAllowedSignalsPerSymbol(eaUseMaxAllowedSignalsPerSymbol);
|
||||||
|
eaExpert.LastPositionProfitForAcceptNextInPoint(eaLastPositionProfitForAcceptNextInPoint);
|
||||||
|
eaExpert.DelaysBetweenTwoSignalsInBar(eaDelaysBetweenTwoSignalsInBar);
|
||||||
|
eaExpert.MaxAllowedSpread(eaMaxAllowedSpread);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trade ...
|
||||||
|
eaExpert.AllowTrade(eaAllowTrade);
|
||||||
|
eaExpert.StartTradeAt(eaStartTradeAt);
|
||||||
|
eaExpert.StopTradeAt(eaStopTradeAt);
|
||||||
|
eaExpert.CloseAllTradesAt(eaCloseAllTradesAt);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Risk Management ...
|
||||||
|
eaExpert.R2R(eaR2R);
|
||||||
|
eaExpert.Volume(eaVolume);
|
||||||
|
eaExpert.StaticBalance(eaStaticBalance);
|
||||||
|
eaExpert.BalancePerTrade(eaBalancePerTrade);
|
||||||
|
eaExpert.RiskPercentPerBalance(eaRiskPercentPerBalance);
|
||||||
|
eaExpert.DynamicRiskManagement(eaDynamicRiskManagement);
|
||||||
|
eaExpert.UseDynamicVolume(eaUseDynamicVolume);
|
||||||
|
eaExpert.DynamicVolumeStep(eaDynamicVolumeStep);
|
||||||
|
eaExpert.DynamicVolumeBalanceFactor(eaDynamicVolumeBalanceFactor);
|
||||||
|
eaExpert.MaxAllowedDrawdownToOpenTrades(eaMaxAllowedDrawdownToOpenTrades);
|
||||||
|
eaExpert.MaxAllowedSLToPauseSignallingPerSymbol(eaMaxAllowedSLToPauseSignallingPerSymbol);
|
||||||
|
eaExpert.PauseSignallingAfterReachesMaxAllowedSLInSecconds(eaPauseSignallingAfterReachesMaxAllowedSLInSecconds);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protection ...
|
||||||
|
eaExpert.AllowHedging(eaAllowHedging);
|
||||||
|
eaExpert.MinOpenTradesFroHedging(eaMinOpenTradesFroHedging);
|
||||||
|
eaExpert.HedgingMinVolumeStep(eaHedgingMinVolumeStep);
|
||||||
|
eaExpert.HedgeingMinRequiredProfitPerVolumeStep(eaHedgeingMinRequiredProfitPerVolumeStep);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alert ...
|
||||||
|
eaExpert.SetAlertEnableAlerts(eaEnableAlerts);
|
||||||
|
eaExpert.SetAlertLogAlerts(eaLogAlerts);
|
||||||
|
eaExpert.SetAlertMailAlerts(eaMailAlerts);
|
||||||
|
eaExpert.SetAlertPushAlerts(eaPushAlerts);
|
||||||
|
eaExpert.SetAlertTerminalAlerts(eaTerminalAlerts);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reports ...
|
||||||
|
eaExpert.ReportNewMonths(eaReportNewMonths);
|
||||||
|
eaExpert.ReportNewWeeks(eaReportNewWeeks);
|
||||||
|
eaExpert.ReportNewDays(eaReportNewDays);
|
||||||
|
eaExpert.ReportNewHours(eaReportNewHours);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isInited = eaExpert.HandleOnInit();
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy Timer ...
|
||||||
|
eaExpert.HandleOnDeInit();
|
||||||
|
|
||||||
|
//
|
||||||
|
delete eaExpert;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(eaExpert);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Tick Handler ...
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handle On Trade Event ...
|
||||||
|
void OnTrade()
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnTrade();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On Timer ...
|
||||||
|
void OnTimer()
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chart Event Handler ...
|
||||||
|
void OnChartEvent(
|
||||||
|
const int id,
|
||||||
|
const long &lparam,
|
||||||
|
const double &dparam,
|
||||||
|
const string &sparam //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnChartEvent(id, lparam, dparam, sparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Listeners ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do What we Want by Specific Signal ...
|
||||||
|
*
|
||||||
|
* @param signal: XSignal instance ...
|
||||||
|
* @param conditions: XStrategyConditions instance ...
|
||||||
|
*/
|
||||||
|
void OnSignalRecieved(
|
||||||
|
XSignal &signal,
|
||||||
|
X121SMCStrategyConditions &conditions //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaExpert.HandleOnSignalRecieved(
|
||||||
|
signal,
|
||||||
|
conditions //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle StopLoss Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal instance ...
|
||||||
|
*/
|
||||||
|
void OnStopLossTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnStopLossTriggered(deal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Take Profit Triggered Positions ...
|
||||||
|
*
|
||||||
|
* @param deal: XDeal instance ...
|
||||||
|
*/
|
||||||
|
void OnTakeProfitTriggered(const XDeal &deal)
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnTakeProfitTriggered(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 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
eaExpert.HandleOnPositionForceClosed(
|
||||||
|
ticket,
|
||||||
|
position,
|
||||||
|
comment //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Deals Changes ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
void OnDealsChanged(int count)
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnDealsChanged(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Orders Changes ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
void OnOrdersChanged(int count)
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnOrdersChanged(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Positions Changes ...
|
||||||
|
*
|
||||||
|
* @param count: Integer, Number of Changes ...
|
||||||
|
*/
|
||||||
|
void OnPositionsChanged(int count)
|
||||||
|
{
|
||||||
|
eaExpert.HandleOnPositionsChanged(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
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,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 ...
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,788 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Helper Class Library
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Name: XCX121XMASHelper
|
||||||
|
// 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 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
enum ENUM_X121_XMAS_BUFFERS
|
||||||
|
{
|
||||||
|
//
|
||||||
|
X121_XMAS_UPPER_LINE = 0,
|
||||||
|
X121_XMAS_MID_LINE = 1,
|
||||||
|
X121_XMAS_LOWER_LINE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Input Models ...
|
||||||
|
struct X121XMASInputs
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
int length; // MA Length
|
||||||
|
ENUM_MA_METHOD method; // MA Method
|
||||||
|
ENUM_APPLIED_PRICE upperAppliedTo; // Upper Applied To
|
||||||
|
ENUM_APPLIED_PRICE midAppliedTo; // Mid Applied To
|
||||||
|
ENUM_APPLIED_PRICE lowerAppliedTo; // Lower Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
int startCalculationForLastBars; // Calculate Last n Bars
|
||||||
|
bool showUpper; // Show Upper
|
||||||
|
bool showMid; // Show Mid
|
||||||
|
bool showLower; // Show Lower
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor(s) ...
|
||||||
|
X121XMASInputs()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clean ...
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
length = 0; // MA Length
|
||||||
|
method = MODE_EMA; // MA Method
|
||||||
|
upperAppliedTo = PRICE_HIGH; // Upper Applied To
|
||||||
|
midAppliedTo = PRICE_MEDIAN; // Mid Applied To
|
||||||
|
lowerAppliedTo = PRICE_LOW; // Lower Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
startCalculationForLastBars = 0; // Calculate Last n Bars
|
||||||
|
showUpper = false; // Show Upper
|
||||||
|
showMid = false; // Show Mid
|
||||||
|
showLower = false; // Show Lower
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default ...
|
||||||
|
void Default()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
length = 14; // MA Length
|
||||||
|
method = MODE_EMA; // MA Method
|
||||||
|
upperAppliedTo = PRICE_HIGH; // Upper Applied To
|
||||||
|
midAppliedTo = PRICE_MEDIAN; // Mid Applied To
|
||||||
|
lowerAppliedTo = PRICE_LOW; // Lower Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
showUpper = true; // Show Upper
|
||||||
|
showMid = true; // Show Mid
|
||||||
|
showLower = true; // Show Lower
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate ...
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
length > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve MAx Length ...
|
||||||
|
int Max()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(result, length);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conditions ...
|
||||||
|
struct X121XMASConditions
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Common ...
|
||||||
|
string symbol;
|
||||||
|
ENUM_TIMEFRAMES period;
|
||||||
|
datetime time;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
double upperBuffer[];
|
||||||
|
double midBuffer[];
|
||||||
|
double lowerBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
X121XMASConditions()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleaning Up ...
|
||||||
|
*/
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Commons ...
|
||||||
|
symbol = NULL;
|
||||||
|
period = NULL;
|
||||||
|
time = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(upperBuffer);
|
||||||
|
Clean(midBuffer);
|
||||||
|
Clean(lowerBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(upperBuffer, true);
|
||||||
|
ArraySetAsSeries(midBuffer, true);
|
||||||
|
ArraySetAsSeries(lowerBuffer, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Conditions Scores ...
|
||||||
|
*
|
||||||
|
* @param bullishScore: Double, Directional Scores Reference ...
|
||||||
|
* @param bearishScore: Double, Directional Scores Reference ...
|
||||||
|
*/
|
||||||
|
void GenerateScore(
|
||||||
|
double &bullishScore,
|
||||||
|
double &bearishScore //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bullishScore = 0;
|
||||||
|
bearishScore = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implement if Required ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Summary String for Represent Conditions State ...
|
||||||
|
*
|
||||||
|
* @param onlyCommons: Boolean, Just Generate Only Commons Conditions ...
|
||||||
|
* @param onlyConditions: Boolean, Just Generate Only Conditions ...
|
||||||
|
* @param includeScores: Boolean, Attach Scores Representations on Result ...
|
||||||
|
* @param ignoreFalseConditions: Boolean, Ignore False Conditions on Result ...
|
||||||
|
* @param separator: String, Separate Lines ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GenerateSummary(
|
||||||
|
bool onlyCommons = false,
|
||||||
|
bool onlyConditions = false,
|
||||||
|
bool includeScores = true,
|
||||||
|
bool ignoreFalseConditions = true,
|
||||||
|
string separator = "\n" //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
double bullishScore = 0;
|
||||||
|
double bearishScore = 0;
|
||||||
|
GenerateScore(
|
||||||
|
bullishScore,
|
||||||
|
bearishScore //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
string scoresStr =
|
||||||
|
//
|
||||||
|
"Scores: " + separator +
|
||||||
|
"---------------" + separator +
|
||||||
|
"Bullish: " + ToString(bullishScore) + separator +
|
||||||
|
"Bearish: " + ToString(bearishScore) + separator +
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
string commonStr = GenerateSpecifiedCommonSummary(
|
||||||
|
this,
|
||||||
|
separator,
|
||||||
|
includeScores //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
string conditionsStr =
|
||||||
|
//
|
||||||
|
//
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
"[" + GetTag() + "]" + separator +
|
||||||
|
(onlyConditions
|
||||||
|
? ""
|
||||||
|
: commonStr) +
|
||||||
|
(!includeScores
|
||||||
|
? ""
|
||||||
|
: scoresStr) +
|
||||||
|
" " + separator +
|
||||||
|
(onlyCommons
|
||||||
|
? ""
|
||||||
|
: conditionsStr) +
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve nique Tag Identifier ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GetTag()
|
||||||
|
{
|
||||||
|
return GetTypeName(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class ...
|
||||||
|
class XCX121XMASHelper : public XCBaseHelper
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructors ...
|
||||||
|
XCX121XMASHelper()
|
||||||
|
: XCBaseHelper(_Symbol, _Period)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCX121XMASHelper()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mInputs.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(upperBuffer);
|
||||||
|
Clean(midBuffer);
|
||||||
|
Clean(lowerBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
bool Init(
|
||||||
|
string symbol, // Trading Symbol
|
||||||
|
ENUM_TIMEFRAMES period, // Trading Period
|
||||||
|
X121XMASInputs &inputs // Inputs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
mSymbol = symbol;
|
||||||
|
mPeriod = period;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = inputs.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(upperBuffer, true);
|
||||||
|
ArraySetAsSeries(midBuffer, true);
|
||||||
|
ArraySetAsSeries(lowerBuffer, true);
|
||||||
|
|
||||||
|
//
|
||||||
|
mInputs = inputs;
|
||||||
|
|
||||||
|
//
|
||||||
|
mHandler = iCustom(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
"x-saherelm.x121.xmas",
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
"",
|
||||||
|
mInputs.length,
|
||||||
|
mInputs.method,
|
||||||
|
mInputs.upperAppliedTo,
|
||||||
|
mInputs.midAppliedTo,
|
||||||
|
mInputs.lowerAppliedTo,
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
"",
|
||||||
|
//
|
||||||
|
mInputs.startCalculationForLastBars,
|
||||||
|
//
|
||||||
|
mInputs.showUpper,
|
||||||
|
mInputs.showMid,
|
||||||
|
mInputs.showLower
|
||||||
|
//
|
||||||
|
);
|
||||||
|
result = mHandler != INVALID_HANDLE;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
X121XMASInputs GetInputs()
|
||||||
|
{
|
||||||
|
return mInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool SetInputs(
|
||||||
|
X121XMASInputs &inputs // Configs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
return Init(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
inputs
|
||||||
|
//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Readers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double GetUpper(
|
||||||
|
int barIndex // Bar Index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (barIndex < 0)
|
||||||
|
{
|
||||||
|
barIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(upperBuffer);
|
||||||
|
if (barIndex >= count)
|
||||||
|
{
|
||||||
|
barIndex = count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return upperBuffer[barIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int CopyUpper(
|
||||||
|
int start, // Start
|
||||||
|
int count, // Number of Items for read
|
||||||
|
double &buffer[], // Dest Buffer
|
||||||
|
bool forceClean = true // Force To Clean buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Update Calculations ...
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy Items ...
|
||||||
|
return Copy(
|
||||||
|
start,
|
||||||
|
count,
|
||||||
|
upperBuffer,
|
||||||
|
buffer,
|
||||||
|
forceClean
|
||||||
|
//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double GetUMid(
|
||||||
|
int barIndex // Bar Index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (barIndex < 0)
|
||||||
|
{
|
||||||
|
barIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(midBuffer);
|
||||||
|
if (barIndex >= count)
|
||||||
|
{
|
||||||
|
barIndex = count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return midBuffer[barIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int CopyMid(
|
||||||
|
int start, // Start
|
||||||
|
int count, // Number of Items for read
|
||||||
|
double &buffer[], // Dest Buffer
|
||||||
|
bool forceClean = true // Force To Clean buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Update Calculations ...
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy Items ...
|
||||||
|
return Copy(
|
||||||
|
start,
|
||||||
|
count,
|
||||||
|
midBuffer,
|
||||||
|
buffer,
|
||||||
|
forceClean
|
||||||
|
//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double GetULower(
|
||||||
|
int barIndex // Bar Index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (barIndex < 0)
|
||||||
|
{
|
||||||
|
barIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(lowerBuffer);
|
||||||
|
if (barIndex >= count)
|
||||||
|
{
|
||||||
|
barIndex = count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return lowerBuffer[barIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int CopyLower(
|
||||||
|
int start, // Start
|
||||||
|
int count, // Number of Items for read
|
||||||
|
double &buffer[], // Dest Buffer
|
||||||
|
bool forceClean = true // Force To Clean buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Update Calculations ...
|
||||||
|
Calculate();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy Items ...
|
||||||
|
return Copy(
|
||||||
|
start,
|
||||||
|
count,
|
||||||
|
lowerBuffer,
|
||||||
|
buffer,
|
||||||
|
forceClean
|
||||||
|
//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool GetConditions(
|
||||||
|
X121XMASConditions &conditions, //
|
||||||
|
int barIndex = 0, //
|
||||||
|
int loopback = 5 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (loopback < 5)
|
||||||
|
{
|
||||||
|
loopback = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
conditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
conditions.symbol = mSymbol;
|
||||||
|
conditions.period = mPeriod;
|
||||||
|
conditions.time = TimeCurrent();
|
||||||
|
|
||||||
|
//
|
||||||
|
int zIndex = barIndex;
|
||||||
|
int cIndex = zIndex + 1;
|
||||||
|
int pIndex = cIndex + 1;
|
||||||
|
int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL zBar;
|
||||||
|
result = zBar.Init(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
zIndex //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL cBar;
|
||||||
|
result = cBar.Init(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
cIndex //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
XOHCL pBar;
|
||||||
|
result = pBar.Init(
|
||||||
|
mSymbol,
|
||||||
|
mPeriod,
|
||||||
|
pIndex //
|
||||||
|
);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
CopyUpper(
|
||||||
|
zIndex,
|
||||||
|
loopback,
|
||||||
|
conditions.upperBuffer //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
CopyMid(
|
||||||
|
zIndex,
|
||||||
|
loopback,
|
||||||
|
conditions.midBuffer //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
CopyLower(
|
||||||
|
zIndex,
|
||||||
|
loopback,
|
||||||
|
conditions.lowerBuffer //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conditions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int cIDX = 1;
|
||||||
|
int pIDX = cIDX + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SAR ...
|
||||||
|
|
||||||
|
//
|
||||||
|
Cleanup();
|
||||||
|
|
||||||
|
//
|
||||||
|
zBar.Clean();
|
||||||
|
cBar.Clean();
|
||||||
|
pBar.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
X121XMASInputs mInputs; // Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
double upperBuffer[];
|
||||||
|
double midBuffer[];
|
||||||
|
double lowerBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
void Calculate(
|
||||||
|
int maxRequiredBars = 100 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
CopyBuffer(
|
||||||
|
mHandler,
|
||||||
|
X121_XMAS_UPPER_LINE,
|
||||||
|
0,
|
||||||
|
maxRequiredBars,
|
||||||
|
upperBuffer
|
||||||
|
//
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST STATE ...
|
||||||
|
CopyBuffer(
|
||||||
|
mHandler,
|
||||||
|
X121_XMAS_MID_LINE,
|
||||||
|
0,
|
||||||
|
maxRequiredBars,
|
||||||
|
midBuffer
|
||||||
|
//
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// MID ...
|
||||||
|
CopyBuffer(
|
||||||
|
mHandler,
|
||||||
|
X121_XMAS_LOWER_LINE,
|
||||||
|
0,
|
||||||
|
maxRequiredBars,
|
||||||
|
lowerBuffer
|
||||||
|
//
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void Cleanup(
|
||||||
|
int maxAllowed = 100 //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CleanupArray(
|
||||||
|
upperBuffer,
|
||||||
|
maxAllowed //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
CleanupArray(
|
||||||
|
midBuffer,
|
||||||
|
maxAllowed //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
CleanupArray(
|
||||||
|
lowerBuffer,
|
||||||
|
maxAllowed //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
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,659 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XWZ
|
||||||
|
// Description: XWZ ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XWZ Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121_X3MA"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
input int fastMALength = 20; // Fast MA Length
|
||||||
|
input int midMALength = 50; // Mid MA Length
|
||||||
|
input int slowMALength = 200; // Slow MA Length
|
||||||
|
input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method
|
||||||
|
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
input bool showMaFast = true; // Show Fast MA
|
||||||
|
input bool showMaMid = true; // Show Mid MA
|
||||||
|
input bool showMaSlow = true; // Show Slow MA
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 9
|
||||||
|
#property indicator_plots 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
#define maFastBufferIndex 0
|
||||||
|
double maFastBuffer[];
|
||||||
|
|
||||||
|
#define maFastColorBufferIndex 1
|
||||||
|
double maFastColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define maFastPlotBufferIndex 0
|
||||||
|
#property indicator_label1 "X121 MAF"
|
||||||
|
#property indicator_type1 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color1 CLR_NONE, clrAqua, clrMagenta, clrGray
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
#property indicator_width1 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// MID ...
|
||||||
|
#define maMidBufferIndex 2
|
||||||
|
double maMidBuffer[];
|
||||||
|
|
||||||
|
#define maMidColorBufferIndex 3
|
||||||
|
double maMidColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define maMidPlotBufferIndex 1
|
||||||
|
#property indicator_label2 "X121 MAM"
|
||||||
|
#property indicator_type2 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color2 CLR_NONE, clrGreen, clrRed, clrGray
|
||||||
|
#property indicator_style2 STYLE_SOLID
|
||||||
|
#property indicator_width2 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
#define maSlowBufferIndex 4
|
||||||
|
double maSlowBuffer[];
|
||||||
|
|
||||||
|
#define maSlowColorBufferIndex 5
|
||||||
|
double maSlowColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define maSlowPlotBufferIndex 2
|
||||||
|
#property indicator_label3 "X121 MAS"
|
||||||
|
#property indicator_type3 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color3 CLR_NONE, clrSteelBlue, clrDarkRed, clrGray
|
||||||
|
#property indicator_style3 STYLE_SOLID
|
||||||
|
#property indicator_width3 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int mLastBufferIndex = 5;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast State ...
|
||||||
|
#define maFastStateBufferIndex mLastBufferIndex + 1
|
||||||
|
double maFastStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid State ...
|
||||||
|
#define maMidStateBufferIndex mLastBufferIndex + 2
|
||||||
|
double maMidStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow State ...
|
||||||
|
#define maSlowStateBufferIndex mLastBufferIndex + 3
|
||||||
|
double maSlowStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maFastHandler = INVALID_HANDLE;
|
||||||
|
int maMidHandler = INVALID_HANDLE;
|
||||||
|
int maSlowHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast MA ...
|
||||||
|
maFastHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
fastMALength,
|
||||||
|
0,
|
||||||
|
maMethod,
|
||||||
|
maAppliedTo //
|
||||||
|
);
|
||||||
|
bool isInited = maFastHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid MA ...
|
||||||
|
maMidHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
midMALength,
|
||||||
|
0,
|
||||||
|
maMethod,
|
||||||
|
maAppliedTo //
|
||||||
|
);
|
||||||
|
isInited = maMidHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow MA ...
|
||||||
|
maSlowHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
slowMALength,
|
||||||
|
0,
|
||||||
|
maMethod,
|
||||||
|
maAppliedTo //
|
||||||
|
);
|
||||||
|
isInited = maSlowHandler != 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();
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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(maFastHandler);
|
||||||
|
IndicatorRelease(maMidHandler);
|
||||||
|
IndicatorRelease(maSlowHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 MA ...
|
||||||
|
int maFastCalculatedBars = BarsCalculated(maFastHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid MA ...
|
||||||
|
int maMidCalculatedBars = BarsCalculated(maMidHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow MA ...
|
||||||
|
int maSlowCalculatedBars = BarsCalculated(maSlowHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isPassedRequiredCalculatedBars =
|
||||||
|
//
|
||||||
|
// Fast MA ...
|
||||||
|
maFastCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// Slow MA ...
|
||||||
|
maMidCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// Slow MA ...
|
||||||
|
maSlowCalculatedBars >= maxLength
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCalculatedBars)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast MA ...
|
||||||
|
int copiedFastMas = CopyBuffer(maFastHandler, 0, 0, limit, maFastBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid MA ...
|
||||||
|
int copiedMidMas = CopyBuffer(maMidHandler, 0, 0, limit, maMidBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow MA ...
|
||||||
|
int copiedSlowMas = CopyBuffer(maSlowHandler, 0, 0, limit, maSlowBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Copied Items ...
|
||||||
|
bool isPassedRequiredCopiedItems =
|
||||||
|
//
|
||||||
|
// Fast MA ...
|
||||||
|
copiedFastMas > 0 &&
|
||||||
|
//
|
||||||
|
// Mid MA ...
|
||||||
|
copiedMidMas > 0 &&
|
||||||
|
//
|
||||||
|
// Slow MA ...
|
||||||
|
copiedSlowMas > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
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 = fastMALength > 0 &&
|
||||||
|
midMALength > 0 &&
|
||||||
|
slowMALength > 0 &&
|
||||||
|
midMALength > fastMALength &&
|
||||||
|
slowMALength > midMALength;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(fastMALength, midMALength);
|
||||||
|
result = MathMax(result, slowMALength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast ...
|
||||||
|
ArraySetAsSeries(maFastBuffer, true);
|
||||||
|
ArraySetAsSeries(maFastColorBuffer, true);
|
||||||
|
SetIndexBuffer(maFastBufferIndex, maFastBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(maFastColorBufferIndex, maFastColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
ArraySetAsSeries(maMidBuffer, true);
|
||||||
|
ArraySetAsSeries(maMidColorBuffer, true);
|
||||||
|
SetIndexBuffer(maMidBufferIndex, maMidBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(maMidColorBufferIndex, maMidColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow ...
|
||||||
|
ArraySetAsSeries(maSlowBuffer, true);
|
||||||
|
ArraySetAsSeries(maSlowColorBuffer, true);
|
||||||
|
SetIndexBuffer(maSlowBufferIndex, maSlowBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(maSlowColorBufferIndex, maSlowColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast State ...
|
||||||
|
ArraySetAsSeries(maFastStateBuffer, true);
|
||||||
|
SetIndexBuffer(maFastStateBufferIndex, maFastStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid State ...
|
||||||
|
ArraySetAsSeries(maMidStateBuffer, true);
|
||||||
|
SetIndexBuffer(maMidStateBufferIndex, maMidStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow State ...
|
||||||
|
ArraySetAsSeries(maSlowStateBuffer, true);
|
||||||
|
SetIndexBuffer(maSlowStateBufferIndex, maSlowStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
maMidBuffer[barIndex] = 0;
|
||||||
|
maFastBuffer[barIndex] = 0;
|
||||||
|
maSlowBuffer[barIndex] = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
maFastColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
maMidColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
maSlowColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
maFastStateBuffer[barIndex] = hideColorIDX;
|
||||||
|
maMidStateBuffer[barIndex] = hideColorIDX;
|
||||||
|
maSlowStateBuffer[barIndex] = hideColorIDX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Vales ...
|
||||||
|
*
|
||||||
|
* @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 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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Implement Colorify Mechanism ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate Applied Price ...
|
||||||
|
ENUM_X_PRICE mPType = ToXPrice(maAppliedTo);
|
||||||
|
double iPrice = GetAppliedPrice(
|
||||||
|
mPType,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close,
|
||||||
|
bar_index //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double iFast = maFastBuffer[bar_index];
|
||||||
|
double iMid = maMidBuffer[bar_index];
|
||||||
|
double iSlow = maSlowBuffer[bar_index];
|
||||||
|
|
||||||
|
//
|
||||||
|
double iFastState = iPrice > iFast
|
||||||
|
? bullishColorIDX
|
||||||
|
: iPrice < iFast
|
||||||
|
? bearishColorIDX
|
||||||
|
: neuturalColorIDX;
|
||||||
|
double iMidState = iPrice > iMid
|
||||||
|
? bullishColorIDX
|
||||||
|
: iPrice < iMid
|
||||||
|
? bearishColorIDX
|
||||||
|
: neuturalColorIDX;
|
||||||
|
double iSlowState = iPrice > iSlow
|
||||||
|
? bullishColorIDX
|
||||||
|
: iPrice < iSlow
|
||||||
|
? bearishColorIDX
|
||||||
|
: neuturalColorIDX;
|
||||||
|
|
||||||
|
//
|
||||||
|
maFastColorBuffer[bar_index] =
|
||||||
|
showMaFast
|
||||||
|
? iFastState
|
||||||
|
: hideColorIDX;
|
||||||
|
maFastStateBuffer[bar_index] = iFastState;
|
||||||
|
|
||||||
|
//
|
||||||
|
maMidColorBuffer[bar_index] =
|
||||||
|
showMaMid
|
||||||
|
? iMidState
|
||||||
|
: hideColorIDX;
|
||||||
|
maMidStateBuffer[bar_index] = iMidState;
|
||||||
|
|
||||||
|
//
|
||||||
|
maSlowColorBuffer[bar_index] =
|
||||||
|
showMaSlow
|
||||||
|
? iSlowState
|
||||||
|
: hideColorIDX;
|
||||||
|
maSlowStateBuffer[bar_index] = iSlowState;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,650 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XATR
|
||||||
|
// Description: XATR ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XATR Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XATR"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "RSI Detection";
|
||||||
|
input int rsiLength = 14; // Length
|
||||||
|
input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "ATR Detection";
|
||||||
|
input int atrLength = 14; // Length
|
||||||
|
input double atrMultiplier = 1; // Multiplier
|
||||||
|
input ENUM_APPLIED_PRICE atrUpperAppliedTo = PRICE_HIGH; // Upper Zone Applied To
|
||||||
|
input ENUM_APPLIED_PRICE atrLowerAppliedTo = PRICE_LOW; // Lower Zone Applied To
|
||||||
|
input ENUM_X_MA_METHOD atrSmoothingMode = X_MA_MODE_EMA; // Smoothing Method
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showAtrUpper = true; // Show Upper Zone
|
||||||
|
input bool showAtrLower = true; // Show Lower Zone
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 6
|
||||||
|
#property indicator_plots 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define atrUpperBufferIndex 0
|
||||||
|
double atrUpperBuffer[];
|
||||||
|
|
||||||
|
#property indicator_label1 "X121 ATRU"
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 clrYellow
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
#property indicator_width1 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define atrLowerBufferIndex 1
|
||||||
|
double atrLowerBuffer[];
|
||||||
|
|
||||||
|
#property indicator_label2 "X121 ATRL"
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color2 clrYellow
|
||||||
|
#property indicator_style2 STYLE_SOLID
|
||||||
|
#property indicator_width2 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int mLastBufferIndex = 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
|
||||||
|
#define atrBufferIndex mLastBufferIndex + 1
|
||||||
|
double atrBuffer[];
|
||||||
|
|
||||||
|
#define atrUpperRawBufferIndex mLastBufferIndex + 2
|
||||||
|
double atrUpperRawBuffer[];
|
||||||
|
|
||||||
|
#define atrLowerRawBufferIndex mLastBufferIndex + 3
|
||||||
|
double atrLowerRawBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
#define rsiBufferIndex mLastBufferIndex + 4
|
||||||
|
double rsiBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI Handler ...
|
||||||
|
int rsiHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR Handler ...
|
||||||
|
int atrHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isStrTrendChanged;
|
||||||
|
bool isStrStartBearishTrend;
|
||||||
|
bool isStrStartBullishTrend;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
rsiHandler = iRSI(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
rsiLength,
|
||||||
|
rsiAppliedTo //
|
||||||
|
);
|
||||||
|
bool isInited = rsiHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
atrHandler = iATR(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
atrLength //
|
||||||
|
);
|
||||||
|
isInited = atrHandler != 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(rsiHandler);
|
||||||
|
IndicatorRelease(atrHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill All Buffers by Zero ...
|
||||||
|
if (prev_calculated == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Calculated Bars ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
int rsiCalculatedBars = BarsCalculated(rsiHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
int atrCalculatedBars = BarsCalculated(atrHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isPassedRequiredCalculatedBars =
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
rsiCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
atrCalculatedBars >= maxLength
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCalculatedBars)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
int copiedRsis = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
int copiedAtrs = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Copied Items ...
|
||||||
|
bool isPassedRequiredCopiedItems =
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
copiedRsis > 0 &&
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
copiedAtrs > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
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 =
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
rsiLength > 0 &&
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
atrLength > 0 &&
|
||||||
|
atrMultiplier > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(rsiLength, atrLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// UPPER ...
|
||||||
|
bool canShowAtrUpper = showAtrUpper;
|
||||||
|
ENUM_DRAW_TYPE atrUpperDrawType = canShowAtrUpper ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(atrUpperBuffer, true);
|
||||||
|
SetIndexBuffer(atrUpperBufferIndex, atrUpperBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(atrUpperBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(atrUpperBufferIndex, PLOT_SHOW_DATA, canShowAtrUpper);
|
||||||
|
PlotIndexSetInteger(atrUpperBufferIndex, PLOT_DRAW_TYPE, atrUpperDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOWER ...
|
||||||
|
bool canShowAtrLower = showAtrLower;
|
||||||
|
ENUM_DRAW_TYPE atrLowerDrawType = canShowAtrLower ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(atrLowerBuffer, true);
|
||||||
|
SetIndexBuffer(atrLowerBufferIndex, atrLowerBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(atrLowerBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(atrLowerBufferIndex, PLOT_SHOW_DATA, canShowAtrLower);
|
||||||
|
PlotIndexSetInteger(atrLowerBufferIndex, PLOT_DRAW_TYPE, atrLowerDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(atrBuffer, true);
|
||||||
|
SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(atrUpperRawBuffer, true);
|
||||||
|
SetIndexBuffer(atrUpperRawBufferIndex, atrUpperRawBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(atrLowerRawBuffer, true);
|
||||||
|
SetIndexBuffer(atrLowerRawBufferIndex, atrLowerRawBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// RSI ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(rsiBuffer, true);
|
||||||
|
SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateAtrZones(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FillBuffersZero(bar_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer ...
|
||||||
|
*/
|
||||||
|
void FillBuffersZero(int barIndex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// RSIS ...
|
||||||
|
rsiBuffer[barIndex] = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATRS ...
|
||||||
|
atrBuffer[barIndex] = 0;
|
||||||
|
atrUpperBuffer[barIndex] = 0;
|
||||||
|
atrUpperRawBuffer[barIndex] = 0;
|
||||||
|
atrUpperBuffer[barIndex] = 0;
|
||||||
|
atrLowerRawBuffer[barIndex] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate ATR Zones ...
|
||||||
|
*
|
||||||
|
* @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 ...
|
||||||
|
*/
|
||||||
|
void CalculateAtrZones(
|
||||||
|
int bar_index, // Selected Bar Index
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal,
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &close[],
|
||||||
|
const double &low[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Select ATr Value ...
|
||||||
|
double atrValue = atrBuffer[bar_index];
|
||||||
|
double appliedAtrMultiplierValue = atrValue * atrMultiplier;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Upper Price ...
|
||||||
|
ENUM_X_PRICE mUpperType = ToXPrice(atrUpperAppliedTo);
|
||||||
|
double upperPrice = GetAppliedPrice(
|
||||||
|
mUpperType,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close,
|
||||||
|
bar_index //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Select Lower Price ...
|
||||||
|
ENUM_X_PRICE mLowerType = ToXPrice(atrLowerAppliedTo);
|
||||||
|
double lowerPrice = GetAppliedPrice(
|
||||||
|
mLowerType,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close,
|
||||||
|
bar_index //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate Raw Atrs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
double atrUpperRawValue = upperPrice + appliedAtrMultiplierValue;
|
||||||
|
atrUpperRawBuffer[bar_index] = atrUpperRawValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
double atrLowerRawValue = lowerPrice - appliedAtrMultiplierValue;
|
||||||
|
atrLowerRawBuffer[bar_index] = atrLowerRawValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool canSmooth = atrSmoothingMode != X_MA_MODE_NONE;
|
||||||
|
if (canSmooth)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
iMAOnBuffer(
|
||||||
|
ratesTotal,
|
||||||
|
prevCalculated,
|
||||||
|
bar_index,
|
||||||
|
atrLength,
|
||||||
|
atrUpperRawBuffer,
|
||||||
|
atrUpperBuffer,
|
||||||
|
atrSmoothingMode //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
iMAOnBuffer(
|
||||||
|
ratesTotal,
|
||||||
|
prevCalculated,
|
||||||
|
bar_index,
|
||||||
|
atrLength,
|
||||||
|
atrLowerRawBuffer,
|
||||||
|
atrLowerBuffer,
|
||||||
|
atrSmoothingMode //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Use Raw Values ...
|
||||||
|
atrUpperBuffer[bar_index] = atrUpperRawValue;
|
||||||
|
atrLowerBuffer[bar_index] = atrLowerRawValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -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,624 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XCHE
|
||||||
|
// Description: XCHE ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XCHE Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XCHE"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
input int cheLength = 35; // Length
|
||||||
|
input int cheLoopback = 26; // Loopback
|
||||||
|
input double cheMultiplier1 = 3.0; // 1st Multiplier
|
||||||
|
input double cheMultiplier2 = 3.5; // 2nd Multiplier
|
||||||
|
input ENUM_APPLIED_PRICE cheUpperAppliedTo = PRICE_HIGH; // Upper Zone Applied to
|
||||||
|
input ENUM_APPLIED_PRICE cheLowerAppliedTo = PRICE_LOW; // Lower Zone Applied to
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int cheArrowCode = 159; // CHE Arrow Code
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showLE1 = true; // Show 1st Long Exit
|
||||||
|
input bool showSE1 = true; // Show 1st Short Exit
|
||||||
|
input bool showLE2 = true; // Show 2st Long Exit
|
||||||
|
input bool showSE2 = true; // Show 2st Short Exit
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 8
|
||||||
|
#property indicator_plots 8
|
||||||
|
|
||||||
|
//
|
||||||
|
// Exit 1 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// LONG ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define le1BufferIndex 0
|
||||||
|
double le1Buffer[];
|
||||||
|
|
||||||
|
#property indicator_label1 "X121 LE1"
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 clrAqua
|
||||||
|
#property indicator_style1 STYLE_DOT
|
||||||
|
#property indicator_width1 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// SHORT ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define se1BufferIndex 1
|
||||||
|
double se1Buffer[];
|
||||||
|
|
||||||
|
#property indicator_label2 "X121 SE1"
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color2 clrMagenta
|
||||||
|
#property indicator_style2 STYLE_DOT
|
||||||
|
#property indicator_width2 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Exit 2 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// LONG ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define le2BufferIndex 2
|
||||||
|
double le2Buffer[];
|
||||||
|
|
||||||
|
#property indicator_label3 "X121 LE2"
|
||||||
|
#property indicator_type3 DRAW_LINE
|
||||||
|
#property indicator_color3 clrAqua
|
||||||
|
#property indicator_style3 STYLE_SOLID
|
||||||
|
#property indicator_width3 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// SHORT ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define se2BufferIndex 3
|
||||||
|
double se2Buffer[];
|
||||||
|
|
||||||
|
#property indicator_label4 "X121 SE2"
|
||||||
|
#property indicator_type4 DRAW_LINE
|
||||||
|
#property indicator_color4 clrMagenta
|
||||||
|
#property indicator_style4 STYLE_SOLID
|
||||||
|
#property indicator_width4 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define le1StartBufferIndex 4
|
||||||
|
double le1StartBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label5 "X121 LE1 S"
|
||||||
|
#property indicator_type5 DRAW_ARROW
|
||||||
|
#property indicator_color5 clrLime
|
||||||
|
|
||||||
|
//
|
||||||
|
#define se1StartBufferIndex 5
|
||||||
|
double se1StartBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label6 "X121 SE1 S"
|
||||||
|
#property indicator_type6 DRAW_ARROW
|
||||||
|
#property indicator_color6 clrRed
|
||||||
|
|
||||||
|
//
|
||||||
|
#define le2StartBufferIndex 6
|
||||||
|
double le2StartBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label7 "X121 LE2 S"
|
||||||
|
#property indicator_type7 DRAW_ARROW
|
||||||
|
#property indicator_color7 clrLime
|
||||||
|
|
||||||
|
//
|
||||||
|
#define se2StartBufferIndex 7
|
||||||
|
double se2StartBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label8 "X121 SE2 S"
|
||||||
|
#property indicator_type8 DRAW_ARROW
|
||||||
|
#property indicator_color8 clrRed
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Working Array ...
|
||||||
|
double work[][6];
|
||||||
|
#define hi1Idx 0
|
||||||
|
#define lo1Idx 1
|
||||||
|
#define hi2Idx 2
|
||||||
|
#define lo2Idx 3
|
||||||
|
#define trend1Idx 4
|
||||||
|
#define trend2Idx 5
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// because in some cases we may have more than one input for
|
||||||
|
// calculation and we must prevent any calculation
|
||||||
|
// untill we pass the biggest input cheLength, here we get max Input cheLength
|
||||||
|
// 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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (Bars(_Symbol, _Period) < rates_total)
|
||||||
|
{
|
||||||
|
return (prev_calculated);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (ArrayRange(work, 0) != rates_total)
|
||||||
|
{
|
||||||
|
ArrayResize(work, rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = prev_calculated - 1;
|
||||||
|
if (limit < 0)
|
||||||
|
{
|
||||||
|
limit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit; i < rates_total && !IsStopped(); i++)
|
||||||
|
{
|
||||||
|
CalculateBuffers(
|
||||||
|
i,
|
||||||
|
prev_calculated,
|
||||||
|
rates_total,
|
||||||
|
//
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Input Args for Initialization ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
cheLength >= 9 &&
|
||||||
|
cheLoopback >= 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(cheLength, cheLoopback);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// LEVEL 1 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Long Exit 1 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Type ...
|
||||||
|
ENUM_DRAW_TYPE le1DrawType = showLE1 ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ENUM_DRAW_TYPE le1StartDrawType = showLE1 ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffer ...
|
||||||
|
SetIndexBuffer(le1BufferIndex, le1Buffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(le1BufferIndex, PLOT_SHOW_DATA, showLE1);
|
||||||
|
PlotIndexSetInteger(le1BufferIndex, PLOT_DRAW_TYPE, le1DrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start Buffer ...
|
||||||
|
SetIndexBuffer(le1StartBufferIndex, le1StartBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(le1StartBufferIndex, PLOT_SHOW_DATA, false);
|
||||||
|
PlotIndexSetInteger(le1StartBufferIndex, PLOT_DRAW_TYPE, le1StartDrawType);
|
||||||
|
PlotIndexSetInteger(le1StartBufferIndex, PLOT_ARROW, cheArrowCode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Short Exit 1 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Type ...
|
||||||
|
ENUM_DRAW_TYPE se1DrawType = showSE1 ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ENUM_DRAW_TYPE se1StartDrawType = showSE1 ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffer ...
|
||||||
|
SetIndexBuffer(se1BufferIndex, se1Buffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(se1BufferIndex, PLOT_SHOW_DATA, showSE1);
|
||||||
|
PlotIndexSetInteger(se1BufferIndex, PLOT_DRAW_TYPE, se1DrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start Buffer ...
|
||||||
|
SetIndexBuffer(se1StartBufferIndex, se1StartBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(se1StartBufferIndex, PLOT_SHOW_DATA, false);
|
||||||
|
PlotIndexSetInteger(se1StartBufferIndex, PLOT_DRAW_TYPE, se1StartDrawType);
|
||||||
|
PlotIndexSetInteger(se1StartBufferIndex, PLOT_ARROW, cheArrowCode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// LEVEL 2 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Long Exit 2 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Type ...
|
||||||
|
ENUM_DRAW_TYPE le2DrawType = showLE2 ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ENUM_DRAW_TYPE le2StartDrawType = showLE2 ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffer ...
|
||||||
|
SetIndexBuffer(le2BufferIndex, le2Buffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(le2BufferIndex, PLOT_SHOW_DATA, showLE2);
|
||||||
|
PlotIndexSetInteger(le2BufferIndex, PLOT_DRAW_TYPE, le2DrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start Buffer ...
|
||||||
|
SetIndexBuffer(le2StartBufferIndex, le2StartBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(le2StartBufferIndex, PLOT_SHOW_DATA, false);
|
||||||
|
PlotIndexSetInteger(le2StartBufferIndex, PLOT_DRAW_TYPE, le2StartDrawType);
|
||||||
|
PlotIndexSetInteger(le2StartBufferIndex, PLOT_ARROW, cheArrowCode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Short Exit 2 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw Type ...
|
||||||
|
ENUM_DRAW_TYPE se2DrawType = showSE2 ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ENUM_DRAW_TYPE se2StartDrawType = showSE2 ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffer ...
|
||||||
|
SetIndexBuffer(se2BufferIndex, se2Buffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(se2BufferIndex, PLOT_SHOW_DATA, showSE2);
|
||||||
|
PlotIndexSetInteger(se2BufferIndex, PLOT_DRAW_TYPE, se2DrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start Buffer ...
|
||||||
|
SetIndexBuffer(se2StartBufferIndex, se2StartBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetInteger(se2StartBufferIndex, PLOT_SHOW_DATA, false);
|
||||||
|
PlotIndexSetInteger(se2StartBufferIndex, PLOT_DRAW_TYPE, se2StartDrawType);
|
||||||
|
PlotIndexSetInteger(se2StartBufferIndex, PLOT_ARROW, cheArrowCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
int prevCalculated, // Previous Calculated
|
||||||
|
int ratesTotal, // Total Rates
|
||||||
|
const double &open[], // Rates Open ...
|
||||||
|
const double &high[], // Rates High ...
|
||||||
|
const double &low[], // Rates Low ...
|
||||||
|
const double &close[] // Rates Close ...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Cleanup Buffers ...
|
||||||
|
le1Buffer[bar_index] = le1StartBuffer[bar_index] = se1Buffer[bar_index] = se1StartBuffer[bar_index] = EMPTY_VALUE;
|
||||||
|
le2Buffer[bar_index] = le2StartBuffer[bar_index] = se2Buffer[bar_index] = se2StartBuffer[bar_index] = EMPTY_VALUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
int start = MathMax(bar_index - cheLoopback, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate ATR Value ...
|
||||||
|
double atrValue = 0;
|
||||||
|
for (int k = 1; k <= cheLength && (bar_index - k - 1) >= 0; k++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
atrValue += MathMax(high[bar_index - k], close[MathMax(bar_index - k - 1, 0)]) -
|
||||||
|
MathMin(low[bar_index - k], close[MathMax(bar_index - k - 1, 0)]);
|
||||||
|
}
|
||||||
|
atrValue /= (double)cheLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Highest High and Lowest Lows ...
|
||||||
|
double cheLoopbackMax = high[ArrayMaximum(high, start, cheLoopback)];
|
||||||
|
double cheLoopbackMin = low[ArrayMinimum(low, start, cheLoopback)];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill Multi Dimesional Working Array ...
|
||||||
|
work[bar_index][hi1Idx] = cheLoopbackMax - cheMultiplier1 * atrValue;
|
||||||
|
work[bar_index][lo1Idx] = cheLoopbackMin + cheMultiplier1 * atrValue;
|
||||||
|
work[bar_index][hi2Idx] = cheLoopbackMax - cheMultiplier2 * atrValue;
|
||||||
|
work[bar_index][lo2Idx] = cheLoopbackMin + cheMultiplier2 * atrValue;
|
||||||
|
work[bar_index][trend1Idx] = (bar_index > 0) ? work[bar_index - 1][trend1Idx] : 0;
|
||||||
|
work[bar_index][trend2Idx] = (bar_index > 0) ? work[bar_index - 1][trend2Idx] : 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (bar_index > 0)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Calculate Trends ...
|
||||||
|
if (close[bar_index] > work[bar_index - 1][lo1Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][trend1Idx] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (close[bar_index] < work[bar_index - 1][hi1Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][trend1Idx] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (close[bar_index] > work[bar_index - 1][lo2Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][trend2Idx] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (close[bar_index] < work[bar_index - 1][hi2Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][trend2Idx] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate Exit Values ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Exit 1 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Long ...
|
||||||
|
if (cheMultiplier1 > 0 && work[bar_index][trend1Idx] == 1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (work[bar_index][hi1Idx] < work[bar_index - 1][hi1Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][hi1Idx] = work[bar_index - 1][hi1Idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
le1Buffer[bar_index] = work[bar_index][hi1Idx];
|
||||||
|
|
||||||
|
//
|
||||||
|
if (le1Buffer[bar_index - 1] == EMPTY_VALUE)
|
||||||
|
{
|
||||||
|
le1StartBuffer[bar_index] = le1Buffer[bar_index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Short ...
|
||||||
|
if (cheMultiplier1 > 0 && work[bar_index][trend1Idx] == -1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (work[bar_index][lo1Idx] > work[bar_index - 1][lo1Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][lo1Idx] = work[bar_index - 1][lo1Idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
se1Buffer[bar_index] = work[bar_index][lo1Idx];
|
||||||
|
|
||||||
|
//
|
||||||
|
if (se1Buffer[bar_index - 1] == EMPTY_VALUE)
|
||||||
|
{
|
||||||
|
se1StartBuffer[bar_index] = se1Buffer[bar_index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Exit 2 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Long ...
|
||||||
|
if (cheMultiplier2 > 0 && work[bar_index][trend2Idx] == 1)
|
||||||
|
{
|
||||||
|
if (work[bar_index][hi2Idx] < work[bar_index - 1][hi2Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][hi2Idx] = work[bar_index - 1][hi2Idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
le2Buffer[bar_index] = work[bar_index][hi2Idx];
|
||||||
|
|
||||||
|
//
|
||||||
|
if (le2Buffer[bar_index - 1] == EMPTY_VALUE)
|
||||||
|
{
|
||||||
|
le2StartBuffer[bar_index] = le2Buffer[bar_index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Short ...
|
||||||
|
if (cheMultiplier2 > 0 && work[bar_index][trend2Idx] == -1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (work[bar_index][lo2Idx] > work[bar_index - 1][lo2Idx])
|
||||||
|
{
|
||||||
|
work[bar_index][lo2Idx] = work[bar_index - 1][lo2Idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
se2Buffer[bar_index] = work[bar_index][lo2Idx];
|
||||||
|
|
||||||
|
//
|
||||||
|
if (se2Buffer[bar_index - 1] == EMPTY_VALUE)
|
||||||
|
{
|
||||||
|
se2StartBuffer[bar_index] = se2Buffer[bar_index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -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 ...
|
||||||
|
//
|
||||||
@@ -0,0 +1,692 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XDON
|
||||||
|
// Description: XDON ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XDON Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XDON"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
input int donchainLength = 40; // Donchain Length
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showUpper = true; // Show Upper Band
|
||||||
|
input bool showLower = true; // Show Lower Band
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showOpen = true; // Show Open
|
||||||
|
input bool showHigh = true; // Show High
|
||||||
|
input bool showClose = true; // Show Close
|
||||||
|
input bool showLow = true; // Show Low
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 8
|
||||||
|
#property indicator_plots 8
|
||||||
|
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donOpenUpperBufferIndex 0
|
||||||
|
double donOpenUpperBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donOpenUpperPlotBufferIndex 0
|
||||||
|
#property indicator_label1 "X121 O U"
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 clrCornflowerBlue
|
||||||
|
#property indicator_width1 1
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donOpenLowerBufferIndex 1
|
||||||
|
double donOpenLowerBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donOpenLowerPlotBufferIndex 1
|
||||||
|
#property indicator_label2 "X121 O L"
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color2 clrCornflowerBlue
|
||||||
|
#property indicator_width2 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// High ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donHighUpperBufferIndex 2
|
||||||
|
double donHighUpperBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donHighUpperPlotBufferIndex 2
|
||||||
|
#property indicator_label3 "X121 H U"
|
||||||
|
#property indicator_type3 DRAW_LINE
|
||||||
|
#property indicator_color3 clrAquamarine
|
||||||
|
#property indicator_width3 1
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donHighLowerBufferIndex 3
|
||||||
|
double donHighLowerBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donHighLowerPlotBufferIndex 3
|
||||||
|
#property indicator_label4 "X121 H L"
|
||||||
|
#property indicator_type4 DRAW_LINE
|
||||||
|
#property indicator_color4 clrAquamarine
|
||||||
|
#property indicator_width4 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Low ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donLowUpperBufferIndex 4
|
||||||
|
double donLowUpperBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donLowUpperPlotBufferIndex 4
|
||||||
|
#property indicator_label5 "X121 L U"
|
||||||
|
#property indicator_type5 DRAW_LINE
|
||||||
|
#property indicator_color5 clrDarkOrchid
|
||||||
|
#property indicator_width5 1
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donLowLowerBufferIndex 5
|
||||||
|
double donLowLowerBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donLowLowerPlotBufferIndex 5
|
||||||
|
#property indicator_label6 "X121 L L"
|
||||||
|
#property indicator_type6 DRAW_LINE
|
||||||
|
#property indicator_color6 clrDarkOrchid
|
||||||
|
#property indicator_width6 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donCloseUpperBufferIndex 6
|
||||||
|
double donCloseUpperBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donCloseUpperPlotBufferIndex 6
|
||||||
|
#property indicator_label7 "X121 C U"
|
||||||
|
#property indicator_type7 DRAW_LINE
|
||||||
|
#property indicator_color7 clrCoral
|
||||||
|
#property indicator_width7 1
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donCloseLowerBufferIndex 7
|
||||||
|
double donCloseLowerBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define donCloseLowerPlotBufferIndex 7
|
||||||
|
#property indicator_label8 "X121 C L"
|
||||||
|
#property indicator_type8 DRAW_LINE
|
||||||
|
#property indicator_color8 clrCoral
|
||||||
|
#property indicator_width8 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int mLastBufferIndex = 7;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
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);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Calculated Bars ...
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateBuffers(
|
||||||
|
i,
|
||||||
|
prev_calculated,
|
||||||
|
rates_total,
|
||||||
|
//
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tick_volume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Input Args for Initialization ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
donchainLength > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
//
|
||||||
|
// Open ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// UPPER ...
|
||||||
|
bool canShowCOpenUpper = showUpper && showOpen;
|
||||||
|
ENUM_DRAW_TYPE donOpenUpperDrawType = canShowCOpenUpper ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donOpenUpperBuffer, true);
|
||||||
|
SetIndexBuffer(donOpenUpperBufferIndex, donOpenUpperBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donOpenUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donOpenUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCOpenUpper);
|
||||||
|
PlotIndexSetInteger(donOpenUpperPlotBufferIndex, PLOT_DRAW_TYPE, donOpenUpperDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOWER ...
|
||||||
|
bool canShowCOpenLower = showLower && showOpen;
|
||||||
|
ENUM_DRAW_TYPE donOpenLowerDrawType = canShowCOpenLower ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donOpenLowerBuffer, true);
|
||||||
|
SetIndexBuffer(donOpenLowerBufferIndex, donOpenLowerBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donOpenLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donOpenLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCOpenLower);
|
||||||
|
PlotIndexSetInteger(donOpenLowerPlotBufferIndex, PLOT_DRAW_TYPE, donOpenLowerDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// UPPER ...
|
||||||
|
bool canShowCCloseUpper = showUpper && showClose;
|
||||||
|
ENUM_DRAW_TYPE donCloseUpperDrawType = canShowCCloseUpper ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donCloseUpperBuffer, true);
|
||||||
|
SetIndexBuffer(donCloseUpperBufferIndex, donCloseUpperBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donCloseUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donCloseUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCCloseUpper);
|
||||||
|
PlotIndexSetInteger(donCloseUpperPlotBufferIndex, PLOT_DRAW_TYPE, donCloseUpperDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOWER ...
|
||||||
|
bool canShowCCloseLower = showLower && showClose;
|
||||||
|
ENUM_DRAW_TYPE donCloseLowerDrawType = canShowCCloseLower ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donCloseLowerBuffer, true);
|
||||||
|
SetIndexBuffer(donCloseLowerBufferIndex, donCloseLowerBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donCloseLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donCloseLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCCloseLower);
|
||||||
|
PlotIndexSetInteger(donCloseLowerPlotBufferIndex, PLOT_DRAW_TYPE, donCloseLowerDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// High ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// UPPER ...
|
||||||
|
bool canShowCHighUpper = showUpper && showHigh;
|
||||||
|
ENUM_DRAW_TYPE donHighUpperDrawType = canShowCHighUpper ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donHighUpperBuffer, true);
|
||||||
|
SetIndexBuffer(donHighUpperBufferIndex, donHighUpperBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donHighUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donHighUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCHighUpper);
|
||||||
|
PlotIndexSetInteger(donHighUpperPlotBufferIndex, PLOT_DRAW_TYPE, donHighUpperDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOWER ...
|
||||||
|
bool canShowCHighLower = showLower && showHigh;
|
||||||
|
ENUM_DRAW_TYPE donHighLowerDrawType = canShowCHighLower ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donHighLowerBuffer, true);
|
||||||
|
SetIndexBuffer(donHighLowerBufferIndex, donHighLowerBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donHighLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donHighLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCHighLower);
|
||||||
|
PlotIndexSetInteger(donHighLowerPlotBufferIndex, PLOT_DRAW_TYPE, donHighLowerDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Low ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// UPPER ...
|
||||||
|
bool canShowCLowUpper = showUpper && showLow;
|
||||||
|
ENUM_DRAW_TYPE donLowUpperDrawType = canShowCLowUpper ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donLowUpperBuffer, true);
|
||||||
|
SetIndexBuffer(donLowUpperBufferIndex, donLowUpperBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donLowUpperPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donLowUpperPlotBufferIndex, PLOT_SHOW_DATA, canShowCLowUpper);
|
||||||
|
PlotIndexSetInteger(donLowUpperPlotBufferIndex, PLOT_DRAW_TYPE, donLowUpperDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOWER ...
|
||||||
|
bool canShowCLowLower = showLower && showLow;
|
||||||
|
ENUM_DRAW_TYPE donLowLowerDrawType = canShowCLowLower ? DRAW_LINE : DRAW_NONE;
|
||||||
|
ArraySetAsSeries(donLowLowerBuffer, true);
|
||||||
|
SetIndexBuffer(donLowLowerBufferIndex, donLowLowerBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(donLowLowerPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(donLowLowerPlotBufferIndex, PLOT_SHOW_DATA, canShowCLowLower);
|
||||||
|
PlotIndexSetInteger(donLowLowerPlotBufferIndex, PLOT_DRAW_TYPE, donLowLowerDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateDonchains(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FillBuffersZero(bar_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer ...
|
||||||
|
*/
|
||||||
|
void FillBuffersZero(int barIndex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
donOpenUpperBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
donOpenLowerBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
donCloseUpperBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
donCloseLowerBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
donHighUpperBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
donHighLowerBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
donLowUpperBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
donLowLowerBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Donchain ...
|
||||||
|
*
|
||||||
|
* @param bar_index: Integer, Bar Index ...
|
||||||
|
* @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 ...
|
||||||
|
* @param _length: Integer, Donchain Length ...
|
||||||
|
* @param _ouBuffer: Double Array Reference ...
|
||||||
|
* @param _olBuffer: Double Array Reference ...
|
||||||
|
* @param _huBuffer: Double Array Reference ...
|
||||||
|
* @param _hlBuffer: Double Array Reference ...
|
||||||
|
* @param _luBuffer: Double Array Reference ...
|
||||||
|
* @param _llBuffer: Double Array Reference ...
|
||||||
|
* @param _cuBuffer: Double Array Reference ...
|
||||||
|
* @param _clBuffer: Double Array Reference ...
|
||||||
|
*/
|
||||||
|
void CalculateDonchain(
|
||||||
|
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 _length,
|
||||||
|
//
|
||||||
|
double &_ouBuffer[],
|
||||||
|
double &_olBuffer[],
|
||||||
|
double &_huBuffer[],
|
||||||
|
double &_hlBuffer[],
|
||||||
|
double &_luBuffer[],
|
||||||
|
double &_llBuffer[],
|
||||||
|
double &_cuBuffer[],
|
||||||
|
double &_clBuffer[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double iUpper = 0;
|
||||||
|
double iLower = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// OPEN ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int from = bar_index;
|
||||||
|
|
||||||
|
//
|
||||||
|
iUpper = open[ArrayMaximum(open, from, _length)];
|
||||||
|
iLower = open[ArrayMinimum(open, from, _length)];
|
||||||
|
|
||||||
|
//
|
||||||
|
_ouBuffer[bar_index] = iUpper;
|
||||||
|
_olBuffer[bar_index] = iLower;
|
||||||
|
|
||||||
|
//
|
||||||
|
// HIGH ...
|
||||||
|
|
||||||
|
//
|
||||||
|
iUpper = high[ArrayMaximum(high, from, _length)];
|
||||||
|
iLower = high[ArrayMinimum(high, from, _length)];
|
||||||
|
|
||||||
|
//
|
||||||
|
_huBuffer[bar_index] = iUpper;
|
||||||
|
_hlBuffer[bar_index] = iLower;
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOW ...
|
||||||
|
|
||||||
|
//
|
||||||
|
iUpper = low[ArrayMaximum(low, from, _length)];
|
||||||
|
iLower = low[ArrayMinimum(low, from, _length)];
|
||||||
|
|
||||||
|
//
|
||||||
|
_luBuffer[bar_index] = iUpper;
|
||||||
|
_llBuffer[bar_index] = iLower;
|
||||||
|
|
||||||
|
//
|
||||||
|
// CLOSE ...
|
||||||
|
|
||||||
|
//
|
||||||
|
iUpper = close[ArrayMaximum(close, from, _length)];
|
||||||
|
iLower = close[ArrayMinimum(close, from, _length)];
|
||||||
|
|
||||||
|
//
|
||||||
|
_cuBuffer[bar_index] = iUpper;
|
||||||
|
_clBuffer[bar_index] = iLower;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Different VWaps ...
|
||||||
|
*
|
||||||
|
* @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 CalculateDonchains(
|
||||||
|
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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateDonchain(
|
||||||
|
//
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
//
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume,
|
||||||
|
//
|
||||||
|
donchainLength,
|
||||||
|
//
|
||||||
|
donOpenUpperBuffer,
|
||||||
|
donOpenLowerBuffer,
|
||||||
|
donHighUpperBuffer,
|
||||||
|
donHighLowerBuffer,
|
||||||
|
donLowUpperBuffer,
|
||||||
|
donLowLowerBuffer,
|
||||||
|
donCloseUpperBuffer,
|
||||||
|
donCloseLowerBuffer //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,616 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XHK
|
||||||
|
// Description: XHK ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XHK Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XHK"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
input int xhkSmoothingLength = 14; // Length
|
||||||
|
input ENUM_X_MA_METHOD xhkSmoothingMode = X_MA_MODE_EMA; // Smoothing Method
|
||||||
|
input bool xhkIgnoreSmoothingShadows = false; // Ignore Smoothed Bar Shadows
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool drawRawXHKCandles = true; // Draw Raw Candle
|
||||||
|
input bool drawSmoothedXHKCandles = true; // Draw Smoothed Candle
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 10
|
||||||
|
#property indicator_plots 2
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// PLOTTED Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define openHKBufferIndex 0
|
||||||
|
double openHKBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define highHKBufferIndex 1
|
||||||
|
double highHKBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define lowHKBufferIndex 2
|
||||||
|
double lowHKBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define closeHKBufferIndex 3
|
||||||
|
double closeHKBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define rawHKColorBufferIndex 4
|
||||||
|
double rawHKColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define rawHKBufferIndex 0
|
||||||
|
#property indicator_label1 "X121 XHK Open;X121 XHK High;X121 XHK Low;X121 XHK Close"
|
||||||
|
#property indicator_type1 DRAW_COLOR_CANDLES
|
||||||
|
#property indicator_color1 CLR_NONE, clrDodgerBlue, clrDarkGoldenrod
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open ...
|
||||||
|
#define openBufferIndex 5
|
||||||
|
double openBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// High ...
|
||||||
|
#define highBufferIndex 6
|
||||||
|
double highBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Low ...
|
||||||
|
#define lowBufferIndex 7
|
||||||
|
double lowBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close ...
|
||||||
|
#define closeBufferIndex 8
|
||||||
|
double closeBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Candle Color ...
|
||||||
|
#define candleColorBufferIndex 9
|
||||||
|
double candleColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define candlesBufferIndex 1
|
||||||
|
#property indicator_label2 "X121 XHKSM Open;X121 XHKSM High;X121 XHKSM Low;X121 XHKSM Close"
|
||||||
|
#property indicator_type2 DRAW_COLOR_CANDLES
|
||||||
|
#property indicator_color2 CLR_NONE, clrAqua, clrMagenta
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
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);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fill All Buffers by Zero ...
|
||||||
|
if (prev_calculated == 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
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 =
|
||||||
|
//
|
||||||
|
true
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(0, xhkSmoothingLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
// RAW ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Raw Candles Color ...
|
||||||
|
ArraySetAsSeries(rawHKColorBuffer, true);
|
||||||
|
SetIndexBuffer(rawHKColorBufferIndex, rawHKColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set EMPTY_VALUE on Candles Buffer ...
|
||||||
|
PlotIndexSetDouble(rawHKBufferIndex, PLOT_EMPTY_VALUE, 0.0);
|
||||||
|
PlotIndexSetInteger(rawHKBufferIndex, PLOT_SHOW_DATA, false);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open ...
|
||||||
|
ArraySetAsSeries(openHKBuffer, true);
|
||||||
|
SetIndexBuffer(openHKBufferIndex, openHKBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
// High ...
|
||||||
|
ArraySetAsSeries(highHKBuffer, true);
|
||||||
|
SetIndexBuffer(highHKBufferIndex, highHKBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close ...
|
||||||
|
ArraySetAsSeries(closeHKBuffer, true);
|
||||||
|
SetIndexBuffer(closeHKBufferIndex, closeHKBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Low ...
|
||||||
|
ArraySetAsSeries(lowHKBuffer, true);
|
||||||
|
SetIndexBuffer(lowHKBufferIndex, lowHKBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SMOOTHED ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Candles Color ...
|
||||||
|
ArraySetAsSeries(candleColorBuffer, true);
|
||||||
|
SetIndexBuffer(candleColorBufferIndex, candleColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set EMPTY_VALUE on Candles Buffer ...
|
||||||
|
PlotIndexSetDouble(candlesBufferIndex, PLOT_EMPTY_VALUE, 0.0);
|
||||||
|
PlotIndexSetInteger(candlesBufferIndex, PLOT_SHOW_DATA, false);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open ...
|
||||||
|
ArraySetAsSeries(openBuffer, true);
|
||||||
|
SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
// High ...
|
||||||
|
ArraySetAsSeries(highBuffer, true);
|
||||||
|
SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close ...
|
||||||
|
ArraySetAsSeries(closeBuffer, true);
|
||||||
|
SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Low ...
|
||||||
|
ArraySetAsSeries(lowBuffer, true);
|
||||||
|
SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
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 =
|
||||||
|
barsLimit == 0 ||
|
||||||
|
bar_index <= barsLimit;
|
||||||
|
if (canCalculate)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateXHK(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FillBuffersZero(bar_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer ...
|
||||||
|
*/
|
||||||
|
void FillBuffersZero(int barIndex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
lowHKBuffer[barIndex] = 0.0;
|
||||||
|
openHKBuffer[barIndex] = 0.0;
|
||||||
|
highHKBuffer[barIndex] = 0.0;
|
||||||
|
closeHKBuffer[barIndex] = 0.0;
|
||||||
|
rawHKColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
|
||||||
|
//
|
||||||
|
lowBuffer[barIndex] = 0.0;
|
||||||
|
openBuffer[barIndex] = 0.0;
|
||||||
|
highBuffer[barIndex] = 0.0;
|
||||||
|
closeBuffer[barIndex] = 0.0;
|
||||||
|
candleColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate ATR Zones ...
|
||||||
|
*
|
||||||
|
* @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 ...
|
||||||
|
*/
|
||||||
|
void CalculateXHK(
|
||||||
|
int bar_index, // Selected Bar Index
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal,
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &close[],
|
||||||
|
const double &low[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double mPrevHKOpenValue;
|
||||||
|
double mPrevHKCloseValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (ArraySize(open) <= bar_index + 1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mPrevHKOpenValue = 0;
|
||||||
|
mPrevHKCloseValue = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mPrevHKOpenValue = openHKBuffer[bar_index + 1];
|
||||||
|
mPrevHKCloseValue = closeHKBuffer[bar_index + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2;
|
||||||
|
double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4;
|
||||||
|
double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue));
|
||||||
|
double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue));
|
||||||
|
|
||||||
|
//
|
||||||
|
double candleColorValue =
|
||||||
|
mHKOpenValue < mHKCloseValue ? bullishColorIDX : bearishColorIDX;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Raw HK Buffers ...
|
||||||
|
openHKBuffer[bar_index] = mHKOpenValue;
|
||||||
|
highHKBuffer[bar_index] = mHKHighValue;
|
||||||
|
lowHKBuffer[bar_index] = mHKLowValue;
|
||||||
|
closeHKBuffer[bar_index] = mHKCloseValue;
|
||||||
|
rawHKColorBuffer[bar_index] = drawRawXHKCandles ? candleColorValue : hideColorIDX;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Apply Smoothing ...
|
||||||
|
bool canSmooth = xhkSmoothingLength > 0 &&
|
||||||
|
xhkSmoothingMode != X_MA_MODE_NONE;
|
||||||
|
if (!canSmooth)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double min = MathMin(mHKOpenValue, mHKCloseValue);
|
||||||
|
double max = MathMax(mHKOpenValue, mHKCloseValue);
|
||||||
|
|
||||||
|
//
|
||||||
|
openBuffer[bar_index] = mHKOpenValue;
|
||||||
|
highBuffer[bar_index] = xhkIgnoreSmoothingShadows ? max : mHKHighValue;
|
||||||
|
lowBuffer[bar_index] = xhkIgnoreSmoothingShadows ? min : mHKLowValue;
|
||||||
|
closeBuffer[bar_index] = mHKCloseValue;
|
||||||
|
candleColorBuffer[bar_index] = drawSmoothedXHKCandles ? candleColorValue : hideColorIDX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Open ...
|
||||||
|
iMAOnBuffer(
|
||||||
|
ratesTotal,
|
||||||
|
prevCalculated,
|
||||||
|
bar_index,
|
||||||
|
xhkSmoothingLength,
|
||||||
|
openHKBuffer,
|
||||||
|
openBuffer,
|
||||||
|
xhkSmoothingMode //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Close ...
|
||||||
|
iMAOnBuffer(
|
||||||
|
ratesTotal,
|
||||||
|
prevCalculated,
|
||||||
|
bar_index,
|
||||||
|
xhkSmoothingLength,
|
||||||
|
closeHKBuffer,
|
||||||
|
closeBuffer,
|
||||||
|
xhkSmoothingMode //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ignoring Shadows ...
|
||||||
|
if (!xhkIgnoreSmoothingShadows)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// High ...
|
||||||
|
iMAOnBuffer(
|
||||||
|
ratesTotal,
|
||||||
|
prevCalculated,
|
||||||
|
bar_index,
|
||||||
|
xhkSmoothingLength,
|
||||||
|
highHKBuffer,
|
||||||
|
highBuffer,
|
||||||
|
xhkSmoothingMode //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Low ...
|
||||||
|
iMAOnBuffer(
|
||||||
|
ratesTotal,
|
||||||
|
prevCalculated,
|
||||||
|
bar_index,
|
||||||
|
xhkSmoothingLength,
|
||||||
|
lowHKBuffer,
|
||||||
|
lowBuffer,
|
||||||
|
xhkSmoothingMode //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double min = MathMin(closeBuffer[bar_index], openBuffer[bar_index]);
|
||||||
|
double max = MathMin(closeBuffer[bar_index], openBuffer[bar_index]);
|
||||||
|
|
||||||
|
//
|
||||||
|
lowBuffer[bar_index] = min;
|
||||||
|
highBuffer[bar_index] = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate Smoothed Color ...
|
||||||
|
candleColorValue =
|
||||||
|
openBuffer[bar_index] < closeBuffer[bar_index] ? bullishColorIDX : bearishColorIDX;
|
||||||
|
candleColorBuffer[bar_index] = drawSmoothedXHKCandles ? candleColorValue : hideColorIDX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,574 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XMAS
|
||||||
|
// Description: XMAS ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XMAS Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121_XMAS"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Imports ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
input int length = 14; // MA Length
|
||||||
|
input ENUM_MA_METHOD method = MODE_EMA; // MA Method
|
||||||
|
input ENUM_APPLIED_PRICE upperAppliedTo = PRICE_HIGH; // Upper Applied To
|
||||||
|
input ENUM_APPLIED_PRICE midAppliedTo = PRICE_MEDIAN; // Mid Applied To
|
||||||
|
input ENUM_APPLIED_PRICE lowerAppliedTo = PRICE_LOW; // Lower Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
input bool showUpper = true; // Show Upper
|
||||||
|
input bool showMid = true; // Show Mid
|
||||||
|
input bool showLower = true; // Show Lower
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 3
|
||||||
|
#property indicator_plots 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// UPPER ...
|
||||||
|
#define upperBufferIndex 0
|
||||||
|
double upperBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label1 "X121 MASU"
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 clrAqua
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
#property indicator_width1 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// MID ...
|
||||||
|
#define midBufferIndex 1
|
||||||
|
double midBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label2 "X121 MASM"
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color2 clrLightBlue
|
||||||
|
#property indicator_style2 STYLE_SOLID
|
||||||
|
#property indicator_width2 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// LOWER ...
|
||||||
|
#define lowerBufferIndex 2
|
||||||
|
double lowerBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label3 "X121 MASL"
|
||||||
|
#property indicator_type3 DRAW_LINE
|
||||||
|
#property indicator_color3 clrMagenta
|
||||||
|
#property indicator_style3 STYLE_SOLID
|
||||||
|
#property indicator_width3 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int mLastBufferIndex = 2;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
int upperHandler = INVALID_HANDLE;
|
||||||
|
int midHandler = INVALID_HANDLE;
|
||||||
|
int lowerHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
upperHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
length,
|
||||||
|
0,
|
||||||
|
method,
|
||||||
|
upperAppliedTo //
|
||||||
|
);
|
||||||
|
bool isInited = upperHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
midHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
length,
|
||||||
|
0,
|
||||||
|
method,
|
||||||
|
midAppliedTo //
|
||||||
|
);
|
||||||
|
isInited = midHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
lowerHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
length,
|
||||||
|
0,
|
||||||
|
method,
|
||||||
|
lowerAppliedTo //
|
||||||
|
);
|
||||||
|
isInited = lowerHandler != 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();
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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(upperHandler);
|
||||||
|
IndicatorRelease(midHandler);
|
||||||
|
IndicatorRelease(lowerHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
int upperCalculatedBars = BarsCalculated(upperHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
int midCalculatedBars = BarsCalculated(midHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
int lowerCalculatedBars = BarsCalculated(lowerHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isPassedRequiredCalculatedBars =
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
upperCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
midCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
lowerCalculatedBars >= maxLength
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCalculatedBars)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
int copiedUppers = CopyBuffer(upperHandler, 0, 0, limit, upperBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
int copiedMids = CopyBuffer(midHandler, 0, 0, limit, midBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
int copiedLowers = CopyBuffer(lowerHandler, 0, 0, limit, lowerBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Copied Items ...
|
||||||
|
bool isPassedRequiredCopiedItems =
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
copiedUppers > 0 &&
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
copiedMids > 0 &&
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
copiedLowers > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
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 = length > 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(result, length);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Upper ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE upperDrawType = showUpper ? DRAW_LINE : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(upperBuffer, true);
|
||||||
|
SetIndexBuffer(upperBufferIndex, upperBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(upperBufferIndex, PLOT_SHOW_DATA, showUpper);
|
||||||
|
PlotIndexSetInteger(upperBufferIndex, PLOT_DRAW_TYPE, upperDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(upperBufferIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE midDrawType = showMid ? DRAW_LINE : DRAW_NONE;
|
||||||
|
|
||||||
|
ArraySetAsSeries(midBuffer, true);
|
||||||
|
SetIndexBuffer(midBufferIndex, midBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(midBufferIndex, PLOT_SHOW_DATA, showMid);
|
||||||
|
PlotIndexSetInteger(midBufferIndex, PLOT_DRAW_TYPE, midDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(midBufferIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lower ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE lowerDrawType = showLower ? DRAW_LINE : DRAW_NONE;
|
||||||
|
|
||||||
|
ArraySetAsSeries(lowerBuffer, true);
|
||||||
|
SetIndexBuffer(lowerBufferIndex, lowerBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(lowerBufferIndex, PLOT_SHOW_DATA, showLower);
|
||||||
|
PlotIndexSetInteger(lowerBufferIndex, PLOT_DRAW_TYPE, lowerDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(lowerBufferIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
upperBuffer[barIndex] = 0;
|
||||||
|
midBuffer[barIndex] = 0;
|
||||||
|
lowerBuffer[barIndex] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Vales ...
|
||||||
|
*
|
||||||
|
* @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 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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Implement Colorify Mechanism ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,637 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XSTR
|
||||||
|
// Description: XSTR ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XSTR Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XSTR"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
input int strLength = 14; // Length
|
||||||
|
input double strMultiplier = 3; // Multiplier
|
||||||
|
input ENUM_APPLIED_PRICE strAppliedTo = PRICE_MEDIAN; // Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showStr = true; // Show Str
|
||||||
|
input bool showStrUpper = true; // Show Str Upper
|
||||||
|
input bool showStrLower = true; // Show Str Lower
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 7
|
||||||
|
#property indicator_plots 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// STR ...
|
||||||
|
#define strBufferIndex 0
|
||||||
|
double strBuffer[];
|
||||||
|
|
||||||
|
#define strColorBufferIndex 1
|
||||||
|
double strColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define strPlotBufferIndex 0
|
||||||
|
#property indicator_label1 "X121 STR"
|
||||||
|
#property indicator_type1 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color1 CLR_NONE, clrLime, clrRed, clrGray
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
#property indicator_width1 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Up ...
|
||||||
|
#define strUpBufferIndex 2
|
||||||
|
double strUpBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define strUpPlotBufferIndex 1
|
||||||
|
#property indicator_label2 "X121 STR U"
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color2 C'255,106,0'
|
||||||
|
#property indicator_style2 STYLE_SOLID
|
||||||
|
#property indicator_width2 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Down ...
|
||||||
|
#define strDownBufferIndex 3
|
||||||
|
double strDownBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define strDownPlotBufferIndex 2
|
||||||
|
#property indicator_label3 "X121 STR D"
|
||||||
|
#property indicator_type3 DRAW_LINE
|
||||||
|
#property indicator_color3 C'255,106,0'
|
||||||
|
#property indicator_style3 STYLE_SOLID
|
||||||
|
#property indicator_width3 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int mLastBufferIndex = 3;
|
||||||
|
|
||||||
|
//
|
||||||
|
// STR ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Atr ...
|
||||||
|
#define atrBufferIndex mLastBufferIndex + 1
|
||||||
|
double atrBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Price ...
|
||||||
|
#define strPriceBufferIndex mLastBufferIndex + 2
|
||||||
|
double strPriceBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trend ...
|
||||||
|
#define strStateBufferIndex mLastBufferIndex + 3
|
||||||
|
double strStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR Handler ...
|
||||||
|
int atrHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isStrTrendChanged;
|
||||||
|
bool isStrStartBearishTrend;
|
||||||
|
bool isStrStartBullishTrend;
|
||||||
|
|
||||||
|
//
|
||||||
|
int changeOfTrend;
|
||||||
|
int startBearishTrend;
|
||||||
|
int startBullishTrend;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
atrHandler = iATR(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
strLength //
|
||||||
|
);
|
||||||
|
bool isInited = atrHandler != 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(atrHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Calculated Bars ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
int atrCalculatedBars = BarsCalculated(atrHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isPassedRequiredCalculatedBars =
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
atrCalculatedBars >= 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCalculatedBars)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// checking for the limit start of calculation of an indicator ...
|
||||||
|
limit =
|
||||||
|
(prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? maxLength
|
||||||
|
: prev_calculated - 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
int copiedAtrs = CopyBuffer(atrHandler, 0, 0, rates_total, atrBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Copied Items ...
|
||||||
|
bool isPassedRequiredCopiedItems =
|
||||||
|
//
|
||||||
|
// ATR ...
|
||||||
|
copiedAtrs >= 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCopiedItems)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit; i < rates_total && !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 =
|
||||||
|
//
|
||||||
|
// STR ...
|
||||||
|
strLength > 0 &&
|
||||||
|
strMultiplier > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(1, strLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// STR ...
|
||||||
|
SetIndexBuffer(strBufferIndex, strBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(strColorBufferIndex, strColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE strUpDrawType = showStrUpper ? DRAW_LINE : DRAW_NONE;
|
||||||
|
SetIndexBuffer(strUpBufferIndex, strUpBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(strUpPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_SHOW_DATA, showStrUpper);
|
||||||
|
PlotIndexSetInteger(strUpPlotBufferIndex, PLOT_DRAW_TYPE, strUpDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE strDownDrawType = showStrLower ? DRAW_LINE : DRAW_NONE;
|
||||||
|
SetIndexBuffer(strDownBufferIndex, strDownBuffer, INDICATOR_DATA);
|
||||||
|
PlotIndexSetDouble(strDownPlotBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
|
||||||
|
PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_SHOW_DATA, showStrLower);
|
||||||
|
PlotIndexSetInteger(strDownPlotBufferIndex, PLOT_DRAW_TYPE, strDownDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// STR ...
|
||||||
|
|
||||||
|
//
|
||||||
|
SetIndexBuffer(strPriceBufferIndex, strPriceBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
SetIndexBuffer(strStateBufferIndex, strStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateStr(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer ...
|
||||||
|
*/
|
||||||
|
void FillBuffersZero(int barIndex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// STR ...
|
||||||
|
strBuffer[barIndex] = 0;
|
||||||
|
strUpBuffer[barIndex] = 0;
|
||||||
|
strDownBuffer[barIndex] = 0;
|
||||||
|
strPriceBuffer[barIndex] = 0;
|
||||||
|
strColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
strStateBuffer[barIndex] = hideColorIDX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate STR ...
|
||||||
|
*
|
||||||
|
* @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 ...
|
||||||
|
*/
|
||||||
|
void CalculateStr(
|
||||||
|
int bar_index, // Selected Bar Index
|
||||||
|
const int prevCalculated,
|
||||||
|
const int ratesTotal,
|
||||||
|
const double &open[],
|
||||||
|
const double &high[],
|
||||||
|
const double &close[],
|
||||||
|
const double &low[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Calculated Price ...
|
||||||
|
ENUM_X_PRICE mPTYpe = ToXPrice(strAppliedTo);
|
||||||
|
double price = GetAppliedPrice(
|
||||||
|
mPTYpe,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close,
|
||||||
|
bar_index //
|
||||||
|
);
|
||||||
|
strPriceBuffer[bar_index] = price;
|
||||||
|
|
||||||
|
//
|
||||||
|
double atr = atrBuffer[bar_index];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Up ...
|
||||||
|
strUpBuffer[bar_index] = price + (strMultiplier * atr);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Down ...
|
||||||
|
strDownBuffer[bar_index] = price - (strMultiplier * atr);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (close[bar_index] > strUpBuffer[bar_index - 1])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
strStateBuffer[bar_index] = 1;
|
||||||
|
if (strStateBuffer[bar_index - 1] == -1)
|
||||||
|
{
|
||||||
|
changeOfTrend = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (close[bar_index] < strDownBuffer[bar_index - 1])
|
||||||
|
{
|
||||||
|
//
|
||||||
|
strStateBuffer[bar_index] = -1;
|
||||||
|
if (strStateBuffer[bar_index - 1] == 1)
|
||||||
|
{
|
||||||
|
changeOfTrend = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strStateBuffer[bar_index - 1] == 1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
strStateBuffer[bar_index] = 1;
|
||||||
|
changeOfTrend = 0;
|
||||||
|
}
|
||||||
|
else if (strStateBuffer[bar_index - 1] == -1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
strStateBuffer[bar_index] = -1;
|
||||||
|
changeOfTrend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Down Trend Starting ...
|
||||||
|
if (strStateBuffer[bar_index] < 0 && strStateBuffer[bar_index - 1] > 0)
|
||||||
|
{
|
||||||
|
startBearishTrend = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startBearishTrend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Up Trend Starting ...
|
||||||
|
if (strStateBuffer[bar_index] > 0 && strStateBuffer[bar_index - 1] < 0)
|
||||||
|
{
|
||||||
|
startBullishTrend = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startBullishTrend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (strStateBuffer[bar_index] > 0 && strDownBuffer[bar_index] < strDownBuffer[bar_index - 1])
|
||||||
|
{
|
||||||
|
strDownBuffer[bar_index] = strDownBuffer[bar_index - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (strStateBuffer[bar_index] < 0 && strUpBuffer[bar_index] > strUpBuffer[bar_index - 1])
|
||||||
|
{
|
||||||
|
strUpBuffer[bar_index] = strUpBuffer[bar_index - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (startBearishTrend == 1)
|
||||||
|
{
|
||||||
|
strUpBuffer[bar_index] = strPriceBuffer[bar_index] + (strMultiplier * atr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (startBullishTrend == 1)
|
||||||
|
{
|
||||||
|
strDownBuffer[bar_index] = strPriceBuffer[bar_index] - (strMultiplier * atr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Draw the indicator ...
|
||||||
|
|
||||||
|
//
|
||||||
|
double colorIDX = hideColorIDX;
|
||||||
|
strColorBuffer[bar_index] = colorIDX;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (strStateBuffer[bar_index] == 1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
strBuffer[bar_index] = strDownBuffer[bar_index];
|
||||||
|
if (changeOfTrend == 1)
|
||||||
|
{
|
||||||
|
strBuffer[bar_index - 1] = strBuffer[bar_index - 2];
|
||||||
|
changeOfTrend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
colorIDX = bullishColorIDX;
|
||||||
|
}
|
||||||
|
else if (strStateBuffer[bar_index] == -1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
strBuffer[bar_index] = strUpBuffer[bar_index];
|
||||||
|
if (changeOfTrend == 1)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
strBuffer[bar_index - 1] = strBuffer[bar_index - 2];
|
||||||
|
changeOfTrend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
colorIDX = bearishColorIDX;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (showStr)
|
||||||
|
{
|
||||||
|
strColorBuffer[bar_index] = colorIDX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,701 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XTREND
|
||||||
|
// Description: XTREND ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XTREND Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XTREND"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
|
||||||
|
input ENUM_APPLIED_PRICE trendPriceType = PRICE_CLOSE; // Detect Trend Price Type
|
||||||
|
|
||||||
|
input group "MA Detection";
|
||||||
|
input int maLength = 50; // MA Length
|
||||||
|
input ENUM_MA_METHOD maMethod = MODE_EMA; // MA Method
|
||||||
|
input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // MA Applied To
|
||||||
|
|
||||||
|
input group "ADX Detection";
|
||||||
|
input int adxLength = 14; // ADX Length
|
||||||
|
input double adxThreshold = 25; // ADX Threshold for Strong Trends
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
input int upTrendArrowCode = 233; // Up Trend Arrow Code
|
||||||
|
input int downTrendArrowCode = 234; // Down Trend Arrow Code
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showOnlyTrendStart = true; // Show Only Trend Start
|
||||||
|
input bool showUpTrend = true; // Show Up Trend
|
||||||
|
input bool showDownTrend = true; // Show Down Trend
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 8
|
||||||
|
#property indicator_plots 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define upTrendBufferIndex 0
|
||||||
|
double upTrendBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label1 "X121 XTREND Up"
|
||||||
|
#property indicator_type1 DRAW_ARROW
|
||||||
|
#property indicator_color1 clrAqua
|
||||||
|
#property indicator_width1 1
|
||||||
|
|
||||||
|
//
|
||||||
|
#define downTrendBufferIndex 1
|
||||||
|
double downTrendBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_label2 "X121 XTREND Down"
|
||||||
|
#property indicator_type2 DRAW_ARROW
|
||||||
|
#property indicator_color2 clrMagenta
|
||||||
|
#property indicator_width2 1
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int mLastBufferIndex = 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
#define maBufferIndex mLastBufferIndex + 1
|
||||||
|
double maBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define adxBufferIndex mLastBufferIndex + 2
|
||||||
|
double adxBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define adxPBufferIndex mLastBufferIndex + 3
|
||||||
|
double adxPBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define adxMBufferIndex mLastBufferIndex + 4
|
||||||
|
double adxMBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define upTBufferIndex mLastBufferIndex + 5
|
||||||
|
double upTBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define downTBufferIndex mLastBufferIndex + 6
|
||||||
|
double downTBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
int maxLength;
|
||||||
|
|
||||||
|
//
|
||||||
|
double lastValue = 0;
|
||||||
|
ENUM_X_DIRECTION lastTrendDir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// MA Handler ...
|
||||||
|
int maHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ADX Handler ...
|
||||||
|
int adxHandler = INVALID_HANDLE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handlers ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Indicator ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Validate Inputs ...
|
||||||
|
if (!ValidateInputs())
|
||||||
|
{
|
||||||
|
return INIT_PARAMETERS_INCORRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Indicator Handlers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// MA ...
|
||||||
|
maHandler = iMA(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
maLength,
|
||||||
|
0,
|
||||||
|
maMethod,
|
||||||
|
maAppliedTo //
|
||||||
|
);
|
||||||
|
bool isInited = maHandler != INVALID_HANDLE;
|
||||||
|
if (!isInited)
|
||||||
|
{
|
||||||
|
return INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ADx ...
|
||||||
|
adxHandler = iADX(
|
||||||
|
_Symbol,
|
||||||
|
_Period,
|
||||||
|
adxLength //
|
||||||
|
);
|
||||||
|
isInited = maHandler != 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();
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS, 2);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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(maHandler);
|
||||||
|
IndicatorRelease(adxHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// MA ...
|
||||||
|
int maCalculatedBars = BarsCalculated(maHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ADX ...
|
||||||
|
int adxCalculatedBars = BarsCalculated(adxHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isPassedRequiredCalculatedBars =
|
||||||
|
//
|
||||||
|
// MA ...
|
||||||
|
maCalculatedBars >= maxLength &&
|
||||||
|
//
|
||||||
|
// ADX ...
|
||||||
|
adxCalculatedBars >= maxLength
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!isPassedRequiredCalculatedBars)
|
||||||
|
{
|
||||||
|
return prev_calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// MA ...
|
||||||
|
int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// ADX ...
|
||||||
|
int copiedAdxs = CopyBuffer(adxHandler, MAIN_LINE, 0, limit, adxBuffer);
|
||||||
|
int copiedAdxPs = CopyBuffer(adxHandler, PLUSDI_LINE, 0, limit, adxPBuffer);
|
||||||
|
int copiedAdxMs = CopyBuffer(adxHandler, MINUSDI_LINE, 0, limit, adxMBuffer);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Copied Items ...
|
||||||
|
bool isPassedRequiredCopiedItems =
|
||||||
|
//
|
||||||
|
// MA ...
|
||||||
|
copiedMas > 0 &&
|
||||||
|
//
|
||||||
|
// ADX ...
|
||||||
|
copiedAdxs > 0 &&
|
||||||
|
copiedAdxPs > 0 &&
|
||||||
|
copiedAdxMs > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
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 =
|
||||||
|
//
|
||||||
|
// MA ...
|
||||||
|
maLength > 0 &&
|
||||||
|
//
|
||||||
|
// ADX ...
|
||||||
|
adxLength > 0 &&
|
||||||
|
adxThreshold > 0
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = MathMax(maLength, adxLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// UP Trend ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE upTrendDrawType = showUpTrend ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(upTrendBuffer, true);
|
||||||
|
SetIndexBuffer(upTrendBufferIndex, upTrendBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(upTrendBufferIndex, PLOT_SHOW_DATA, showUpTrend);
|
||||||
|
PlotIndexSetInteger(upTrendBufferIndex, PLOT_DRAW_TYPE, upTrendDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(upTrendBufferIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
PlotIndexSetInteger(upTrendBufferIndex, PLOT_ARROW, upTrendArrowCode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// DOWN Trend ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ENUM_DRAW_TYPE downTrendDrawType = showDownTrend ? DRAW_ARROW : DRAW_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(downTrendBuffer, true);
|
||||||
|
SetIndexBuffer(downTrendBufferIndex, downTrendBuffer, INDICATOR_DATA);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetInteger(downTrendBufferIndex, PLOT_SHOW_DATA, showDownTrend);
|
||||||
|
PlotIndexSetInteger(downTrendBufferIndex, PLOT_DRAW_TYPE, downTrendDrawType);
|
||||||
|
|
||||||
|
//
|
||||||
|
PlotIndexSetDouble(downTrendBufferIndex, PLOT_EMPTY_VALUE, 0);
|
||||||
|
PlotIndexSetInteger(downTrendBufferIndex, PLOT_ARROW, downTrendArrowCode);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(maBuffer, true);
|
||||||
|
SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(adxBuffer, true);
|
||||||
|
SetIndexBuffer(adxBufferIndex, adxBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(adxPBuffer, true);
|
||||||
|
SetIndexBuffer(adxPBufferIndex, adxPBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(adxMBuffer, true);
|
||||||
|
SetIndexBuffer(adxMBufferIndex, adxMBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(upTBuffer, true);
|
||||||
|
SetIndexBuffer(upTBufferIndex, upTBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
ArraySetAsSeries(downTBuffer, true);
|
||||||
|
SetIndexBuffer(downTBufferIndex, downTBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateTrend(
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
upTrendBuffer[barIndex] = 0;
|
||||||
|
downTrendBuffer[barIndex] = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
maBuffer[barIndex] = 0;
|
||||||
|
adxBuffer[barIndex] = 0;
|
||||||
|
adxPBuffer[barIndex] = 0;
|
||||||
|
adxMBuffer[barIndex] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Trends ...
|
||||||
|
*
|
||||||
|
* @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 CalculateTrend(
|
||||||
|
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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ENUM_X_PRICE mPType = ToXPrice(trendPriceType);
|
||||||
|
double iPrice = GetAppliedPrice(
|
||||||
|
mPType,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close,
|
||||||
|
bar_index //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
double iMa = maBuffer[bar_index];
|
||||||
|
double iAdx = adxBuffer[bar_index];
|
||||||
|
double points = GetPoints(_Symbol);
|
||||||
|
double points10 = 10 * points;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isUpTrend =
|
||||||
|
iPrice > iMa &&
|
||||||
|
iAdx > adxThreshold;
|
||||||
|
bool isDownTrend =
|
||||||
|
iPrice < iMa &&
|
||||||
|
iAdx > adxThreshold;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (isUpTrend)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// double iLastValue =
|
||||||
|
// prevCalculated <= 0
|
||||||
|
// ? 0
|
||||||
|
// : upTrendBuffer[bar_index + 1];
|
||||||
|
// if (iLastValue > 0 &&
|
||||||
|
// iValue > iLastValue)
|
||||||
|
// {
|
||||||
|
// iValue = iLastValue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
double selectedValue = low[bar_index] - points10;
|
||||||
|
|
||||||
|
//
|
||||||
|
double iValue =
|
||||||
|
!IsBullish(lastTrendDir) ? selectedValue
|
||||||
|
: !showOnlyTrendStart
|
||||||
|
? lastValue
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
upTrendBuffer[bar_index] = iValue;
|
||||||
|
upTBuffer[bar_index] = selectedValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
downTrendBuffer[bar_index] = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
lastValue = iValue;
|
||||||
|
lastTrendDir = X_DIRECTION_BULLISH;
|
||||||
|
}
|
||||||
|
else if (isDownTrend)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// double iLastValue =
|
||||||
|
// prevCalculated <= 0
|
||||||
|
// ? 0
|
||||||
|
// : downTrendBuffer[bar_index + 1];
|
||||||
|
// if (iLastValue > 0 &&
|
||||||
|
// iValue < iLastValue)
|
||||||
|
// {
|
||||||
|
// iValue = iLastValue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//
|
||||||
|
double selectedValue = high[bar_index] + points10;
|
||||||
|
|
||||||
|
//
|
||||||
|
double iValue =
|
||||||
|
!IsBearish(lastTrendDir) ? selectedValue
|
||||||
|
: !showOnlyTrendStart
|
||||||
|
? lastValue
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
upTrendBuffer[bar_index] = 0;
|
||||||
|
downTrendBuffer[bar_index] = iValue;
|
||||||
|
downTBuffer[bar_index] = selectedValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
lastValue = iValue;
|
||||||
|
lastTrendDir = X_DIRECTION_BEARISH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double iValue =
|
||||||
|
IsBullish(lastTrendDir)
|
||||||
|
? showOnlyTrendStart
|
||||||
|
? 0
|
||||||
|
: lastValue
|
||||||
|
: IsBearish(lastTrendDir)
|
||||||
|
? showOnlyTrendStart
|
||||||
|
? 0
|
||||||
|
: lastValue
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
upTrendBuffer[bar_index] = 0;
|
||||||
|
downTrendBuffer[bar_index] = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
upTBuffer[bar_index] = 0;
|
||||||
|
downTBuffer[bar_index] = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
lastValue = 0;
|
||||||
|
lastTrendDir = X_DIRECTION_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,712 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Indicator
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name: X121 XVWAP
|
||||||
|
// Description: XVWAP ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 XVWAP Indicator"
|
||||||
|
#property strict
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define ShortName "X121 XVWAP"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Includes Common Library ...
|
||||||
|
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inputs ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Market ...
|
||||||
|
input group "Market";
|
||||||
|
input int vwapFastLength = 20; // Fast Length
|
||||||
|
input int vwapMidLength = 40; // Mid Length
|
||||||
|
input int vwapSlowLength = 60; // Slow Length
|
||||||
|
input ENUM_APPLIED_PRICE vwapAppliedTo = PRICE_CLOSE; // Applied To
|
||||||
|
|
||||||
|
//
|
||||||
|
// Presentation ...
|
||||||
|
input group "Presentation";
|
||||||
|
|
||||||
|
//
|
||||||
|
input int startCalculationForLastBars = 1000; // Calculate Last n Bars
|
||||||
|
|
||||||
|
//
|
||||||
|
input bool showVWapFast = true; // Show VWap Fast
|
||||||
|
input bool showVWapMedium = true; // Show VWap Medium
|
||||||
|
input bool showVWapSlow = true; // Show VWap Slow
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
#define hideColorIDX 0
|
||||||
|
#define bullishColorIDX 1
|
||||||
|
#define bearishColorIDX 2
|
||||||
|
#define neuturalColorIDX 3
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_chart_window
|
||||||
|
|
||||||
|
//
|
||||||
|
#property indicator_buffers 11
|
||||||
|
#property indicator_plots 3
|
||||||
|
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// FAST ...
|
||||||
|
#define vwapFastBufferIndex 0
|
||||||
|
double vwapFastBuffer[];
|
||||||
|
|
||||||
|
#define vwapFastColorBufferIndex 1
|
||||||
|
double vwapFastColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define vwapFastPlotBufferIndex 0
|
||||||
|
#property indicator_label1 "X121 VWF"
|
||||||
|
#property indicator_type1 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color1 CLR_NONE, clrAqua, clrMagenta, clrGray
|
||||||
|
#property indicator_style1 STYLE_SOLID
|
||||||
|
#property indicator_width1 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// MID ...
|
||||||
|
#define vwapMidBufferIndex 2
|
||||||
|
double vwapMidBuffer[];
|
||||||
|
|
||||||
|
#define vwapMidColorBufferIndex 3
|
||||||
|
double vwapMidColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define vwapMidPlotBufferIndex 1
|
||||||
|
#property indicator_label2 "X121 VWM"
|
||||||
|
#property indicator_type2 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color2 CLR_NONE, clrGreen, clrRed, clrGray
|
||||||
|
#property indicator_style2 STYLE_SOLID
|
||||||
|
#property indicator_width2 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// SLOW ...
|
||||||
|
#define vwapSlowBufferIndex 4
|
||||||
|
double vwapSlowBuffer[];
|
||||||
|
|
||||||
|
#define vwapSlowColorBufferIndex 5
|
||||||
|
double vwapSlowColorBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
#define vwapSlowPlotBufferIndex 2
|
||||||
|
#property indicator_label3 "X121 VWS"
|
||||||
|
#property indicator_type3 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color3 CLR_NONE, clrSteelBlue, clrDarkRed, clrGray
|
||||||
|
#property indicator_style3 STYLE_SOLID
|
||||||
|
#property indicator_width3 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
int mLastBufferIndex = 5;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Volume ...
|
||||||
|
#define vwapVolumeBufferIndex mLastBufferIndex + 1
|
||||||
|
double vwapVolumeBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Price ...
|
||||||
|
#define vwapPriceBufferIndex mLastBufferIndex + 2
|
||||||
|
double vwapPriceBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast State ...
|
||||||
|
#define vwapFastStateBufferIndex mLastBufferIndex + 3
|
||||||
|
double vwapFastStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid State ...
|
||||||
|
#define vwapMidStateBufferIndex mLastBufferIndex + 4
|
||||||
|
double vwapMidStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow State ...
|
||||||
|
#define vwapSlowStateBufferIndex mLastBufferIndex + 5
|
||||||
|
double vwapSlowStateBuffer[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables, Properties and etc ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// this counts Available Bars ...
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
//
|
||||||
|
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);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Calculated Bars ...
|
||||||
|
|
||||||
|
//
|
||||||
|
limit = (prev_calculated > rates_total || prev_calculated <= 0)
|
||||||
|
? rates_total
|
||||||
|
: (rates_total - prev_calculated) + 1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Buffers Copy ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main Loop ...
|
||||||
|
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateBuffers(
|
||||||
|
i,
|
||||||
|
prev_calculated,
|
||||||
|
rates_total,
|
||||||
|
//
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tick_volume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return rates_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Input Args for Initialization ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool ValidateInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
vwapFastLength > 2 &&
|
||||||
|
vwapMidLength > vwapFastLength &&
|
||||||
|
vwapSlowLength > vwapMidLength
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract Max Length of Inputs ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int ExtractMaxLengthOfInputs()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// XVWAP ...
|
||||||
|
result = MathMax(result, vwapFastLength);
|
||||||
|
result = MathMax(result, vwapMidLength);
|
||||||
|
result = MathMax(result, vwapSlowLength);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Required Buffers ...
|
||||||
|
*/
|
||||||
|
void DefineBuffers()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Plot Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast ...
|
||||||
|
ArraySetAsSeries(vwapFastBuffer, true);
|
||||||
|
ArraySetAsSeries(vwapFastColorBuffer, true);
|
||||||
|
SetIndexBuffer(vwapFastBufferIndex, vwapFastBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(vwapFastColorBufferIndex, vwapFastColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
ArraySetAsSeries(vwapMidBuffer, true);
|
||||||
|
ArraySetAsSeries(vwapMidColorBuffer, true);
|
||||||
|
SetIndexBuffer(vwapMidBufferIndex, vwapMidBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(vwapMidColorBufferIndex, vwapMidColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow ...
|
||||||
|
ArraySetAsSeries(vwapSlowBuffer, true);
|
||||||
|
ArraySetAsSeries(vwapSlowColorBuffer, true);
|
||||||
|
SetIndexBuffer(vwapSlowBufferIndex, vwapSlowBuffer, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(vwapSlowColorBufferIndex, vwapSlowColorBuffer, INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Data Buffers ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// Volumes ...
|
||||||
|
ArraySetAsSeries(vwapVolumeBuffer, true);
|
||||||
|
SetIndexBuffer(vwapVolumeBufferIndex, vwapVolumeBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Price ...
|
||||||
|
ArraySetAsSeries(vwapPriceBuffer, true);
|
||||||
|
SetIndexBuffer(vwapPriceBufferIndex, vwapPriceBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast State ...
|
||||||
|
ArraySetAsSeries(vwapFastStateBuffer, true);
|
||||||
|
SetIndexBuffer(vwapFastStateBufferIndex, vwapFastStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid State ...
|
||||||
|
ArraySetAsSeries(vwapMidStateBuffer, true);
|
||||||
|
SetIndexBuffer(vwapMidStateBufferIndex, vwapMidStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Slow State ...
|
||||||
|
ArraySetAsSeries(vwapSlowStateBuffer, true);
|
||||||
|
SetIndexBuffer(vwapSlowStateBufferIndex, vwapSlowStateBuffer, INDICATOR_CALCULATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Indicator Short Name and also we can define Buffers Labels ...
|
||||||
|
*/
|
||||||
|
void SetIndicatorName()
|
||||||
|
{
|
||||||
|
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 Required VWAP Data Buffers ...
|
||||||
|
if (ratesTotal - bar_index <= maxLength)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateVWAPDataBuffers(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prevent Moving Forward ...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
CalculateVWAPDataBuffers(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
CalculateVWAPS(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FillBuffersZero(bar_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill All Bufers to Zero Vlue for Specified Bar Index ...
|
||||||
|
*
|
||||||
|
* @param barIndex: Integer ...
|
||||||
|
*/
|
||||||
|
void FillBuffersZero(int barIndex)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
vwapFastBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
vwapMidBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
vwapSlowBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
vwapVolumeBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
vwapPriceBuffer[barIndex] = EMPTY_VALUE;
|
||||||
|
|
||||||
|
//
|
||||||
|
vwapFastColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
vwapMidColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
vwapSlowColorBuffer[barIndex] = hideColorIDX;
|
||||||
|
vwapFastStateBuffer[barIndex] = hideColorIDX;
|
||||||
|
vwapMidStateBuffer[barIndex] = hideColorIDX;
|
||||||
|
vwapSlowStateBuffer[barIndex] = hideColorIDX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate VWAP Value for Specified Bar ...
|
||||||
|
*
|
||||||
|
* @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 ...
|
||||||
|
* @param _length: Integer, Specified VWAP Length ...
|
||||||
|
* @param _show: Boolean, Specified Show Buffer or not ...
|
||||||
|
* @param _buffer: Double Array Reference, Points to Buffer ...
|
||||||
|
* @param _colorBuffer: Double Array Reference, Points to Color Buffer ...
|
||||||
|
* @param _stateBuffer: Double Array Reference, Points to State Buffer ...
|
||||||
|
*/
|
||||||
|
void CalculateVWAP(
|
||||||
|
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 _length, // Calculation Length
|
||||||
|
bool _show,
|
||||||
|
double &_buffer[],
|
||||||
|
double &_colorBuffer[],
|
||||||
|
double &_stateBuffer[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
double vSum = 0;
|
||||||
|
double pSum = 0;
|
||||||
|
double mSum = 0;
|
||||||
|
for (int x = 0; x < _length; x++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
pSum += vwapPriceBuffer[x + bar_index];
|
||||||
|
vSum += vwapVolumeBuffer[x + bar_index];
|
||||||
|
mSum += vwapPriceBuffer[x + bar_index] * vwapVolumeBuffer[x + bar_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double iValue = mSum / vSum;
|
||||||
|
iValue = NormalizeDouble(iValue, _Digits);
|
||||||
|
|
||||||
|
//
|
||||||
|
_buffer[bar_index] = iValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isBullish = low[bar_index] > iValue;
|
||||||
|
bool isBearish = high[bar_index] < iValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
double iColor =
|
||||||
|
isBullish
|
||||||
|
? bullishColorIDX
|
||||||
|
: isBearish
|
||||||
|
? bearishColorIDX
|
||||||
|
: neuturalColorIDX;
|
||||||
|
|
||||||
|
//
|
||||||
|
_colorBuffer[bar_index] = hideColorIDX;
|
||||||
|
_stateBuffer[bar_index] = iColor;
|
||||||
|
if (_show)
|
||||||
|
{
|
||||||
|
_colorBuffer[bar_index] = iColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate VWAP Required Data 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 CalculateVWAPDataBuffers(
|
||||||
|
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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ENUM_X_PRICE mPType = ToXPrice(vwapAppliedTo);
|
||||||
|
double price = GetAppliedPrice(
|
||||||
|
mPType,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
low,
|
||||||
|
close,
|
||||||
|
bar_index //
|
||||||
|
);
|
||||||
|
vwapPriceBuffer[bar_index] = price;
|
||||||
|
vwapVolumeBuffer[bar_index] = (double)tickVolume[bar_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Different VWaps ...
|
||||||
|
*
|
||||||
|
* @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 CalculateVWAPS(
|
||||||
|
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[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Fast ...
|
||||||
|
CalculateVWAP(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume,
|
||||||
|
//
|
||||||
|
vwapFastLength,
|
||||||
|
showVWapFast,
|
||||||
|
vwapFastBuffer,
|
||||||
|
vwapFastColorBuffer,
|
||||||
|
vwapFastStateBuffer //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mid ...
|
||||||
|
CalculateVWAP(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume,
|
||||||
|
//
|
||||||
|
vwapMidLength,
|
||||||
|
showVWapMedium,
|
||||||
|
vwapMidBuffer,
|
||||||
|
vwapMidColorBuffer,
|
||||||
|
vwapMidStateBuffer //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fast ...
|
||||||
|
CalculateVWAP(
|
||||||
|
bar_index,
|
||||||
|
prevCalculated,
|
||||||
|
ratesTotal,
|
||||||
|
open,
|
||||||
|
high,
|
||||||
|
close,
|
||||||
|
low,
|
||||||
|
tickVolume,
|
||||||
|
//
|
||||||
|
vwapSlowLength,
|
||||||
|
showVWapSlow,
|
||||||
|
vwapSlowBuffer,
|
||||||
|
vwapSlowColorBuffer,
|
||||||
|
vwapSlowStateBuffer //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
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,627 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Class Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: XSCX121SMCBaseStrategy
|
||||||
|
// 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-bar.analyser.class.mq5"
|
||||||
|
#include "../../Classes/x-saherelm.x-poi.class.mq5"
|
||||||
|
#include "../../Classes/x-saherelm.x-trade.class.mq5"
|
||||||
|
#include "../Classes/x-121.smc.cobjects.class.mq5"
|
||||||
|
#include "../Libraries/x-121.smc.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Helper(s) ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// XStrategy Class Implementation(s) ...
|
||||||
|
class XCX121SMCBaseStrategy : public XCBaseAlert
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Public ...
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
XCAccount mAccount;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor(s) ...
|
||||||
|
XCX121SMCBaseStrategy(
|
||||||
|
//
|
||||||
|
// Base ...
|
||||||
|
string _symbol, // Trading Symbol
|
||||||
|
ENUM_TIMEFRAMES _period // Trading TimeFrame
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mSymbol = _symbol;
|
||||||
|
mPeriod = _period;
|
||||||
|
|
||||||
|
//
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
~XCX121SMCBaseStrategy()
|
||||||
|
{
|
||||||
|
DeInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Getter / Setter (s) ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve Symbol ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GetSymbol()
|
||||||
|
{
|
||||||
|
return mSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve TimeFrame ...
|
||||||
|
*
|
||||||
|
* @return ( ENUM_TIMEFRAMES )
|
||||||
|
*/
|
||||||
|
ENUM_TIMEFRAMES GetPeriod()
|
||||||
|
{
|
||||||
|
return mPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Strategy is Disabled or not ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsDisabled()
|
||||||
|
{
|
||||||
|
return mForceDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Signal Volume ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double Volume()
|
||||||
|
{
|
||||||
|
return mVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Signal Volume ...
|
||||||
|
*
|
||||||
|
* @param value: Double ...
|
||||||
|
*/
|
||||||
|
void Volume(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (value < 0.01)
|
||||||
|
{
|
||||||
|
value = 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
mVolume = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Risk/Reward Ratio ...
|
||||||
|
*
|
||||||
|
* @return ( double )
|
||||||
|
*/
|
||||||
|
double R2R()
|
||||||
|
{
|
||||||
|
return mR2R;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Risk/Reward Ratio ...
|
||||||
|
*
|
||||||
|
* @param value: Double ...
|
||||||
|
*/
|
||||||
|
void R2R(double value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
value = 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
mR2R = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Long Signalling State ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool AllowLong()
|
||||||
|
{
|
||||||
|
return mAllowLong;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Long Signalling State ...
|
||||||
|
*
|
||||||
|
* @param value: Boolean ...
|
||||||
|
*/
|
||||||
|
void AllowLong(bool value)
|
||||||
|
{
|
||||||
|
mAllowLong = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Short Signalling State ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool AllowShort()
|
||||||
|
{
|
||||||
|
return mAllowShort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Short Signalling State ...
|
||||||
|
*
|
||||||
|
* @param value: Argument 1
|
||||||
|
*/
|
||||||
|
void AllowShort(bool value)
|
||||||
|
{
|
||||||
|
mAllowShort = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable Strategy ...
|
||||||
|
*/
|
||||||
|
void Disable()
|
||||||
|
{
|
||||||
|
mForceDisabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable Strategy ...
|
||||||
|
*/
|
||||||
|
void Enable()
|
||||||
|
{
|
||||||
|
mForceDisabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register Signal Event Handler ...
|
||||||
|
*
|
||||||
|
* @param handler: an Instance of TOnXSignal ...
|
||||||
|
*/
|
||||||
|
void AddXSignalEventHandler(TOnX121SMCSignal handler)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
Add(
|
||||||
|
handler,
|
||||||
|
mSignalEventHandlers //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Virtual Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy All Class Implementations ...
|
||||||
|
*/
|
||||||
|
virtual void Destroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Tick Processing ...
|
||||||
|
*
|
||||||
|
* @param positions: XPosition instance Collection ...
|
||||||
|
*/
|
||||||
|
virtual void HandleTick()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
DoUnwaitedTicksWork();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check State ...
|
||||||
|
if (IsDisabled())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Signalling State ...
|
||||||
|
if (!AllowLong() && !AllowShort())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bar Tracker State ...
|
||||||
|
if (!mBarTracker.CanProcessBar())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Retrieve Current Tick and Check it's Time
|
||||||
|
// by Last Issued Tick ...
|
||||||
|
MqlTick cTick;
|
||||||
|
bool hasTick = GetTick(
|
||||||
|
mSymbol,
|
||||||
|
cTick //
|
||||||
|
);
|
||||||
|
bool isSameAsLast = cTick.time == mLastTick.time;
|
||||||
|
if (isSameAsLast)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update Last Issued Tick ...
|
||||||
|
mLastTick = cTick;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Current Processing Tick has Signal or not ...
|
||||||
|
XSignal signal;
|
||||||
|
X121SMCStrategyConditions conditions;
|
||||||
|
bool hasSignal = HasSignal(
|
||||||
|
signal,
|
||||||
|
conditions //
|
||||||
|
);
|
||||||
|
if (!hasSignal)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Waits Until Next Candle if Current Tick has Signal ...
|
||||||
|
mBarTracker.Waits();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Notify Signal Event Handlers ...
|
||||||
|
NotifyOnSignalEventHandlers(
|
||||||
|
signal,
|
||||||
|
conditions //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for any Guards ...
|
||||||
|
*
|
||||||
|
* @param guards: X121SMCGuard instance Collection ...
|
||||||
|
* @param positions: XPosition instance Collection ...
|
||||||
|
*
|
||||||
|
* @return ( virtual bool )
|
||||||
|
*/
|
||||||
|
virtual bool HandleGuard(
|
||||||
|
X121SMCGuard &guards[],
|
||||||
|
XPosition &positions[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check State ...
|
||||||
|
if (IsDisabled())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Signalling State ...
|
||||||
|
if (!AllowLong() && !AllowShort())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Bar Tracker State ...
|
||||||
|
if (!mGuardBarTracker.CanProcessBar())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check For Guards ...
|
||||||
|
result = CheckGuard(
|
||||||
|
guards,
|
||||||
|
positions //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Waits Until Next Candle if Current Tick has Guard ...
|
||||||
|
mGuardBarTracker.Waits();
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(positions);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check For Signal ...
|
||||||
|
*
|
||||||
|
* @param signal: XSignal instance ...
|
||||||
|
* @param conditions: X121SMCStrategyConditions instance ...
|
||||||
|
*
|
||||||
|
* @return ( virtual bool )
|
||||||
|
*/
|
||||||
|
virtual bool HasSignal(
|
||||||
|
XSignal &signal,
|
||||||
|
X121SMCStrategyConditions &conditions //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
signal.Clean();
|
||||||
|
conditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for any Guard Actions ...
|
||||||
|
*
|
||||||
|
* @param guards: X121SMCGuard instance Collection ...
|
||||||
|
*
|
||||||
|
* @return ( virtual bool )
|
||||||
|
*/
|
||||||
|
virtual bool CheckGuard(
|
||||||
|
X121SMCGuard &guards[],
|
||||||
|
const XPosition &positions[] // Positions ...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all Requirements without waiting ...
|
||||||
|
*/
|
||||||
|
virtual void DoUnwaitedTicksWork()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect SL Candidates based on Strategy and Conditions ...
|
||||||
|
*
|
||||||
|
* @param result: Double array reference ...
|
||||||
|
* @param entry: Double, Position Entry Price ...
|
||||||
|
* @param conditions: X121SMCStrategyConditions instance, Provides Configurations ...
|
||||||
|
* @param type: ENUM_X_POSITION_TYPES member, Specified Position Type ...
|
||||||
|
*/
|
||||||
|
virtual void DetectSLCandidates(
|
||||||
|
double &result[],
|
||||||
|
double entry,
|
||||||
|
X121SMCStrategyConditions &conditions,
|
||||||
|
ENUM_X_POSITION_TYPES type //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customize Strategy Identifier ...
|
||||||
|
*
|
||||||
|
* @return ( virtual string )
|
||||||
|
*/
|
||||||
|
virtual string GetTag()
|
||||||
|
{
|
||||||
|
return X121SMCStrategyToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Protected ...
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
MqlTick mLastTick; // Last Issued Tick ...
|
||||||
|
|
||||||
|
//
|
||||||
|
XBarTracker mBarTracker; // Strategy Bar Tracker ...
|
||||||
|
XBarTracker mGuardBarTracker; // Strategy Guard Bar Tracker ...
|
||||||
|
XCBarAnalyser *mBarAnalyser; // Bar Analyser Instance
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare and Normalize Signal for Execution in Strategy ...
|
||||||
|
*
|
||||||
|
* @param signal: XSignal instance ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool PrepareSignal(XSignal &signal)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check Strategy Is Enables ...
|
||||||
|
result = !IsDisabled();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Signal ...
|
||||||
|
result = signal.IsValid();
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
bool isLong = IsLong(signal.type);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Implement Signal Preparation Mechanism here ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notified Signal Event Handler(s) ...
|
||||||
|
*
|
||||||
|
* @param signal: XSignal instance ...
|
||||||
|
* @param conditions: XStrategyConditions instance ...
|
||||||
|
*/
|
||||||
|
void NotifyOnSignalEventHandlers(
|
||||||
|
XSignal &signal,
|
||||||
|
X121SMCStrategyConditions &conditions //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
if (!signal.IsValid() || !conditions.IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
int count = ArraySize(mSignalEventHandlers);
|
||||||
|
if (!IsValidSize(count))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mSignalEventHandlers[i](
|
||||||
|
signal,
|
||||||
|
conditions //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private ...
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
|
||||||
|
//
|
||||||
|
string mSymbol; // Trading Symbol ...
|
||||||
|
ENUM_TIMEFRAMES mPeriod; // Trading TimeFrame ...
|
||||||
|
bool mForceDisabled; // Force Disabled ...
|
||||||
|
bool mAllowLong; // Allow Long Signals
|
||||||
|
bool mAllowShort; // Allow Short Signals
|
||||||
|
double mR2R; // Risk/Rewar Ratio ...
|
||||||
|
double mVolume; // Static Volume Per Trades ...
|
||||||
|
|
||||||
|
//
|
||||||
|
// On X121 Signal Recieved Event Handler(s) ...
|
||||||
|
TOnX121SMCSignal mSignalEventHandlers[];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install all Helpers and Prepare all Configurations for required Indicators ...
|
||||||
|
*/
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
mForceDisabled = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
R2R(1);
|
||||||
|
Volume(0.01);
|
||||||
|
|
||||||
|
//
|
||||||
|
string symbol = Symbol();
|
||||||
|
ENUM_TIMEFRAMES period = Period();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Bar Tracker ...
|
||||||
|
mBarTracker.Init(
|
||||||
|
symbol,
|
||||||
|
period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize Guard Bar Tracker ...
|
||||||
|
mGuardBarTracker.Init(
|
||||||
|
symbol,
|
||||||
|
period //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
mBarAnalyser = new XCBarAnalyser();
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De Initialize all Tools ...
|
||||||
|
*/
|
||||||
|
void DeInit()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ZeroMemory(mBarAnalyser);
|
||||||
|
|
||||||
|
//
|
||||||
|
delete mBarAnalyser;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(mSignalEventHandlers);
|
||||||
|
|
||||||
|
//
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reste Bar Tracker ...
|
||||||
|
*/
|
||||||
|
void ResetBarTracker()
|
||||||
|
{
|
||||||
|
mBarTracker.Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Class Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: XChartObjects
|
||||||
|
// Description: provides all require Chart Objects ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 "../../Classes/x-saherelm.x-cobject.class.mq5"
|
||||||
|
#include "../Libraries/x-121.smc.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
enum ENUM_X121SMC_CHARTOBJECTS
|
||||||
|
{
|
||||||
|
X_121_NONE_OBJ
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementations ...
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Class Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: XC121Panel
|
||||||
|
// 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-app-dialog.class.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementation ...
|
||||||
|
|
||||||
|
//
|
||||||
|
class X121CAppDialog : public XCAppDialog
|
||||||
|
{
|
||||||
|
//
|
||||||
|
public:
|
||||||
|
//
|
||||||
|
// Constructor(s) ...
|
||||||
|
void X121CAppDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deconstructor ...
|
||||||
|
void ~X121CAppDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void Configure()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Configure Dialog ...
|
||||||
|
BackgroundColor(clrBlack);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
protected:
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
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,970 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 X121 SMC Signal Class
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Name:
|
||||||
|
// Description: provide all Global Guarding 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 "../Classes/x-121.smc.market.cycle.helper.class.mq5"
|
||||||
|
#include "../Libraries/x-121.smc.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
bool DetectX121SMCGuards(
|
||||||
|
//
|
||||||
|
string signalProvider, // Provider ...
|
||||||
|
X121SMCGuard &guards[],
|
||||||
|
const XPosition &positions[],
|
||||||
|
X121SMCStrategySignalProviderData &provider,
|
||||||
|
//
|
||||||
|
// Guard Types ...
|
||||||
|
ENUM_X_121_SMC_GUARD_ACTIONS &ignoreGuards[],
|
||||||
|
//
|
||||||
|
// Required Configurations ...
|
||||||
|
double breakEvenTPLevel = 2.0
|
||||||
|
//
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// bool isCycleHelpersValid =
|
||||||
|
// //
|
||||||
|
// visionCycleHelper != NULL &&
|
||||||
|
// analyseCycleHelper != NULL &&
|
||||||
|
// decisionCycleHelper != NULL &&
|
||||||
|
// consolidationCycleHelper != NULL
|
||||||
|
// //
|
||||||
|
// ;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Ignore Guards ...
|
||||||
|
// bool hasIgnoreGuards = HasChild(ignoreGuards);
|
||||||
|
// bool isColseIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_CLOSE,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
// bool isColseAllIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_CLOSE_ALL,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
// bool isColseLongsIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_CLOSE_LONGS,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
// bool isColseShortsIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_CLOSE_SHORTS,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
// bool isPartialColseIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
// bool isTrailStopIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_TRAIL_STOP,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
// bool isTrailTargetIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_TRAIL_TARGET,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
// bool isHedgeIgnored =
|
||||||
|
// hasIgnoreGuards &&
|
||||||
|
// Contains(
|
||||||
|
// X_121_SMC_GUARD_ACTION_HEDGE,
|
||||||
|
// ignoreGuards //
|
||||||
|
// );
|
||||||
|
|
||||||
|
// //
|
||||||
|
// bool isAllIgnores =
|
||||||
|
// //
|
||||||
|
// isColseIgnored &&
|
||||||
|
// isHedgeIgnored &&
|
||||||
|
// isColseAllIgnored &&
|
||||||
|
// isTrailStopIgnored &&
|
||||||
|
// isColseLongsIgnored &&
|
||||||
|
// isColseShortsIgnored &&
|
||||||
|
// isTrailTargetIgnored &&
|
||||||
|
// isPartialColseIgnored
|
||||||
|
// //
|
||||||
|
// ;
|
||||||
|
// result = !isAllIgnores &&
|
||||||
|
// isCycleHelpersValid;
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// int count = ArraySize(positions);
|
||||||
|
// result = IsValidSize(count);
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// string symbol = decisionCycleHelper.GetSymbol();
|
||||||
|
// ENUM_TIMEFRAMES period = decisionCycleHelper.GetPeriod();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XPosition ownPositions[];
|
||||||
|
// XPosition ownLongPositions[];
|
||||||
|
// XPosition ownShortPositions[];
|
||||||
|
// for (int i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XPosition iPosition = positions[i];
|
||||||
|
// bool isOwn = iPosition
|
||||||
|
// .IsFiltersPassed(
|
||||||
|
// symbol,
|
||||||
|
// provider,
|
||||||
|
// NULL,
|
||||||
|
// X_POSITION_TYPE_ALL,
|
||||||
|
// iPosition.magic //
|
||||||
|
// );
|
||||||
|
// if (isOwn)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iPosition,
|
||||||
|
// ownPositions //
|
||||||
|
// );
|
||||||
|
|
||||||
|
// //
|
||||||
|
// bool isLong = IsLong(positions[i].type);
|
||||||
|
// if (isLong)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iPosition,
|
||||||
|
// ownLongPositions //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// AddRef(
|
||||||
|
// iPosition,
|
||||||
|
// ownShortPositions //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// count = ArraySize(ownPositions);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// int longsCount = ArraySize(ownLongPositions);
|
||||||
|
// bool hasLongs = IsValidSize(longsCount);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// int shortsCount = ArraySize(ownShortPositions);
|
||||||
|
// bool hasShorts = IsValidSize(shortsCount);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// result = IsValidSize(count);
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// Clean(ownPositions);
|
||||||
|
// Clean(ownLongPositions);
|
||||||
|
// Clean(ownShortPositions);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Here we Are Sure there is Positions to Guard ...
|
||||||
|
// // based on Current Provider ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Detect Required Data for Analyse Market to Guard Positions ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// int zIndex = 0;
|
||||||
|
// int cIndex = zIndex + 1;
|
||||||
|
// int pIndex = cIndex + 1;
|
||||||
|
// int ppIndex = pIndex + 1;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// int loopback = 10;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XOHCL zBar;
|
||||||
|
// result = zBar.Init(
|
||||||
|
// symbol,
|
||||||
|
// period,
|
||||||
|
// zIndex //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// result = HasChild(guards);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XOHCL cBar;
|
||||||
|
// result = cBar.Init(
|
||||||
|
// symbol,
|
||||||
|
// period,
|
||||||
|
// cIndex //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// result = HasChild(guards);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XOHCL pBar;
|
||||||
|
// result = pBar.Init(
|
||||||
|
// symbol,
|
||||||
|
// period,
|
||||||
|
// pIndex //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// pBar.Clean();
|
||||||
|
// result = HasChild(guards);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// XOHCL ppBar;
|
||||||
|
// result = ppBar.Init(
|
||||||
|
// symbol,
|
||||||
|
// period,
|
||||||
|
// ppIndex //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// pBar.Clean();
|
||||||
|
// ppBar.Clean();
|
||||||
|
// result = HasChild(guards);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// double ask = GetAsk(symbol);
|
||||||
|
// double bid = GetBid(symbol);
|
||||||
|
// datetime cTime = TimeCurrent();
|
||||||
|
// double points = GetPoints(symbol);
|
||||||
|
|
||||||
|
// //
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Cycles Conditions ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Decision ...
|
||||||
|
// ENUM_XPOI_EVENTS decisionPoiEvents[];
|
||||||
|
// ENUM_X_CYCLE_EVENTS decisionCycleEvents[];
|
||||||
|
// X121SMCCycleConditions decisionConditions;
|
||||||
|
// result = decisionCycleHelper.GetConditions(
|
||||||
|
// decisionCycleEvents,
|
||||||
|
// decisionPoiEvents,
|
||||||
|
// decisionConditions,
|
||||||
|
// zIndex,
|
||||||
|
// loopback //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// pBar.Clean();
|
||||||
|
// ppBar.Clean();
|
||||||
|
// result = HasChild(guards);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(decisionPoiEvents);
|
||||||
|
// Clean(decisionCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// decisionConditions.Clean();
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Analyse ...
|
||||||
|
// ENUM_XPOI_EVENTS analysePoiEvents[];
|
||||||
|
// ENUM_X_CYCLE_EVENTS analyseCycleEvents[];
|
||||||
|
// X121SMCCycleConditions analyseConditions;
|
||||||
|
// result = analyseCycleHelper.GetConditions(
|
||||||
|
// analyseCycleEvents,
|
||||||
|
// analysePoiEvents,
|
||||||
|
// analyseConditions,
|
||||||
|
// zIndex,
|
||||||
|
// loopback //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// pBar.Clean();
|
||||||
|
// ppBar.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(decisionPoiEvents);
|
||||||
|
// Clean(decisionCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// decisionConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(analysePoiEvents);
|
||||||
|
// Clean(analyseCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// analyseConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// result = HasChild(guards);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Consolidation ...
|
||||||
|
// ENUM_XPOI_EVENTS consolidationPoiEvents[];
|
||||||
|
// ENUM_X_CYCLE_EVENTS consolidationCycleEvents[];
|
||||||
|
// X121SMCCycleConditions consolidationConditions;
|
||||||
|
// result = consolidationCycleHelper.GetConditions(
|
||||||
|
// consolidationCycleEvents,
|
||||||
|
// consolidationPoiEvents,
|
||||||
|
// consolidationConditions,
|
||||||
|
// zIndex,
|
||||||
|
// loopback //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// pBar.Clean();
|
||||||
|
// ppBar.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(decisionPoiEvents);
|
||||||
|
// Clean(decisionCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// decisionConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(analysePoiEvents);
|
||||||
|
// Clean(analyseCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// analyseConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(consolidationPoiEvents);
|
||||||
|
// Clean(consolidationCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// consolidationConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// result = HasChild(guards);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Vision ...
|
||||||
|
// ENUM_XPOI_EVENTS visionPoiEvents[];
|
||||||
|
// ENUM_X_CYCLE_EVENTS visionCycleEvents[];
|
||||||
|
// X121SMCCycleConditions visionConditions;
|
||||||
|
// result = visionCycleHelper.GetConditions(
|
||||||
|
// visionCycleEvents,
|
||||||
|
// visionPoiEvents,
|
||||||
|
// visionConditions,
|
||||||
|
// zIndex,
|
||||||
|
// loopback //
|
||||||
|
// );
|
||||||
|
// if (!result)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// pBar.Clean();
|
||||||
|
// ppBar.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(decisionPoiEvents);
|
||||||
|
// Clean(decisionCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// decisionConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(analysePoiEvents);
|
||||||
|
// Clean(analyseCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// analyseConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(consolidationPoiEvents);
|
||||||
|
// Clean(consolidationCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// consolidationConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(visionPoiEvents);
|
||||||
|
// Clean(visionCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// visionConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// result = HasChild(guards);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Cycles POI States ...
|
||||||
|
// XPOIState decisionState = decisionConditions.state;
|
||||||
|
// XPOIState analyseState = analyseConditions.state;
|
||||||
|
// XPOIState consolidationState = consolidationConditions.state;
|
||||||
|
// XPOIState visionState = visionConditions.state;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Cycle X121Conditions ...
|
||||||
|
// X121Conditions decisionXConditions = decisionConditions.x121Conditions;
|
||||||
|
// X121Conditions analyseXConditions = analyseConditions.x121Conditions;
|
||||||
|
// X121Conditions consolidationXConditions = consolidationConditions.x121Conditions;
|
||||||
|
// X121Conditions visionXConditions = visionConditions.x121Conditions;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// //
|
||||||
|
// //
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // // Detect Consolidation Zone ...
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // // Detect Consolidation Zones ...
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // XBoxZone lastBullishBox;
|
||||||
|
// // XBoxZone prevLastBullishBox;
|
||||||
|
// // bool hasLastBullishBox = false;
|
||||||
|
// // bool hasPrevLastBullishBox = false;
|
||||||
|
// // XConsolidationZone lastBullishZone;
|
||||||
|
// // bool isLastBullishAbovePrev = false;
|
||||||
|
// // bool isLastBullishBelowPrev = false;
|
||||||
|
// // XConsolidationZone prevLastBullishZone;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // XBoxZone lastBearishBox;
|
||||||
|
// // XBoxZone prevLastBearishBox;
|
||||||
|
// // bool hasLastBearishBox = false;
|
||||||
|
// // bool hasPrevLastBearishBox = false;
|
||||||
|
// // XConsolidationZone lastBearishZone;
|
||||||
|
// // bool isLastBearishAbovePrev = false;
|
||||||
|
// // bool isLastBearishBelowPrev = false;
|
||||||
|
// // XConsolidationZone prevLastBearishZone;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // int bullishConsolidationZonesCount = 0;
|
||||||
|
// // int bearishConsolidationZonesCount = 0;
|
||||||
|
// // bool hasBullishConsolidationZones = false;
|
||||||
|
// // bool hasBearishConsolidationZones = false;
|
||||||
|
// // XConsolidationZone bullishConsolidationZones[];
|
||||||
|
// // XConsolidationZone bearishConsolidationZones[];
|
||||||
|
// // bool hasConsolidationZones = decisionCycleHelper.HasConsolidationZones();
|
||||||
|
// // int consolidationZonesCount = decisionCycleHelper.CountConsolidationZones();
|
||||||
|
// // if (hasConsolidationZones)
|
||||||
|
// // {
|
||||||
|
// // //
|
||||||
|
// // bullishConsolidationZonesCount = decisionCycleHelper
|
||||||
|
// // .FillConsolidationZones(
|
||||||
|
// // X_DIRECTION_BULLISH,
|
||||||
|
// // bullishConsolidationZones //
|
||||||
|
// // );
|
||||||
|
// // hasBullishConsolidationZones = IsValidSize(bullishConsolidationZonesCount);
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // bearishConsolidationZonesCount = decisionCycleHelper
|
||||||
|
// // .FillConsolidationZones(
|
||||||
|
// // X_DIRECTION_BEARISH,
|
||||||
|
// // bearishConsolidationZones //
|
||||||
|
// // );
|
||||||
|
// // hasBearishConsolidationZones = IsValidSize(bearishConsolidationZonesCount);
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // //
|
||||||
|
// // //
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // if (hasBullishConsolidationZones &&
|
||||||
|
// // bullishConsolidationZonesCount >= 2)
|
||||||
|
// // {
|
||||||
|
// // //
|
||||||
|
// // lastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 1];
|
||||||
|
// // prevLastBullishZone = bullishConsolidationZones[bullishConsolidationZonesCount - 2];
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // hasLastBullishBox = ToBox(
|
||||||
|
// // lastBullishBox,
|
||||||
|
// // lastBullishZone //
|
||||||
|
// // );
|
||||||
|
// // hasPrevLastBullishBox = ToBox(
|
||||||
|
// // prevLastBullishBox,
|
||||||
|
// // prevLastBullishZone //
|
||||||
|
// // );
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // isLastBullishAbovePrev = hasLastBullishBox &&
|
||||||
|
// // hasPrevLastBullishBox &&
|
||||||
|
// // IsBoxAbove(
|
||||||
|
// // lastBullishBox,
|
||||||
|
// // prevLastBullishBox //
|
||||||
|
// // );
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // isLastBullishBelowPrev = hasLastBullishBox &&
|
||||||
|
// // hasPrevLastBullishBox &&
|
||||||
|
// // IsBoxBelow(
|
||||||
|
// // lastBullishBox,
|
||||||
|
// // prevLastBullishBox //
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // if (hasBearishConsolidationZones &&
|
||||||
|
// // bearishConsolidationZonesCount >= 2)
|
||||||
|
// // {
|
||||||
|
// // //
|
||||||
|
// // lastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 1];
|
||||||
|
// // prevLastBearishZone = bearishConsolidationZones[bearishConsolidationZonesCount - 2];
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // hasLastBearishBox = ToBox(
|
||||||
|
// // lastBearishBox,
|
||||||
|
// // lastBearishZone //
|
||||||
|
// // );
|
||||||
|
// // hasPrevLastBearishBox = ToBox(
|
||||||
|
// // prevLastBearishBox,
|
||||||
|
// // prevLastBearishZone //
|
||||||
|
// // );
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // isLastBearishAbovePrev = hasLastBearishBox &&
|
||||||
|
// // hasPrevLastBearishBox &&
|
||||||
|
// // IsBoxAbove(
|
||||||
|
// // lastBearishBox,
|
||||||
|
// // prevLastBearishBox //
|
||||||
|
// // );
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // isLastBearishBelowPrev = hasLastBearishBox &&
|
||||||
|
// // hasPrevLastBearishBox &&
|
||||||
|
// // IsBoxBelow(
|
||||||
|
// // lastBearishBox,
|
||||||
|
// // prevLastBearishBox //
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Detect High Probability Swings ...
|
||||||
|
// // bool isSwingLow =
|
||||||
|
// // //
|
||||||
|
// // cBar.low > pBar.low &&
|
||||||
|
// // ppBar.low > pBar.low &&
|
||||||
|
// // //
|
||||||
|
// // zBar.low > pBar.low
|
||||||
|
// // //
|
||||||
|
// // ;
|
||||||
|
// // bool isSwingHigh =
|
||||||
|
// // //
|
||||||
|
// // cBar.high < pBar.high &&
|
||||||
|
// // ppBar.high < pBar.high &&
|
||||||
|
// // //
|
||||||
|
// // zBar.high < pBar.high
|
||||||
|
// // //
|
||||||
|
// // ;
|
||||||
|
// // bool isStrongSwingLow =
|
||||||
|
// // pBar.IsBullish() &&
|
||||||
|
// // pBar.GetLowShadow() >= pBar.GetBody() * 2;
|
||||||
|
// // bool isStrongSwingHigh =
|
||||||
|
// // pBar.IsBearish() &&
|
||||||
|
// // pBar.GetHighShadow() >= pBar.GetBody() * 2;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // bool isStrongSwingLowAboveLastBullishBox =
|
||||||
|
// // isStrongSwingLow &&
|
||||||
|
// // hasLastBullishBox &&
|
||||||
|
// // pBar.low > lastBullishBox.upper;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // bool isStrongSwingHighBelowLastBearishBox =
|
||||||
|
// // isStrongSwingHigh &&
|
||||||
|
// // hasLastBearishBox &&
|
||||||
|
// // pBar.high < lastBearishBox.lower;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Here We Have all Requirements for Guarding Positions ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Available Guards:
|
||||||
|
// // X_121_SMC_GUARD_ACTION_NONE
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE_ALL
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE_LONGS
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS
|
||||||
|
// // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE
|
||||||
|
// // X_121_SMC_GUARD_ACTION_TRAIL_STOP
|
||||||
|
// // X_121_SMC_GUARD_ACTION_TRAIL_TARGET
|
||||||
|
// // X_121_SMC_GUARD_ACTION_HEDGE
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE:
|
||||||
|
// // Close Specified Position on Specified Conditions ...
|
||||||
|
// if (!isColseIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// // TODO:
|
||||||
|
// // - [] Implement Close on Nearest on TP ...
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE_ALL:
|
||||||
|
// // Close All Positions on Specified Conditions ...
|
||||||
|
// if (!isColseAllIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// // TODO:
|
||||||
|
// // - [] Implement Close All Positions on Weekend ...
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE_LONGS:
|
||||||
|
// // Close All Long Positions on Specified Conditions ...
|
||||||
|
// if (!isColseLongsIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_CLOSE_SHORTS:
|
||||||
|
// // Close All Short Positions on Specified Conditions ...
|
||||||
|
// if (!isColseShortsIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE:
|
||||||
|
// // Partial Close Specified Position on Specified Conditions ...
|
||||||
|
// if (!isPartialColseIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// // Breake Even ...
|
||||||
|
// // Usually Break Even Works on TP2 Reached ...
|
||||||
|
// // when tp reached to required Level, we Close 50% of Entered Volume ...
|
||||||
|
// bool canBreakEven = breakEvenTPLevel >= 0;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// for (int i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XPosition iPosition = ownPositions[i];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// bool isInProfit = iPosition.profit > 0;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// double reachedTPLevel = 0;
|
||||||
|
// double reachedTPPrice = 0;
|
||||||
|
// if (isInProfit)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// iPosition.CalculateReahedTP(
|
||||||
|
// reachedTPLevel,
|
||||||
|
// reachedTPPrice //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Break Event ...
|
||||||
|
// if (canBreakEven)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// // Position Must be In Profit ...
|
||||||
|
// if (!isInProfit)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// bool canDoBreakEven = reachedTPLevel == breakEvenTPLevel &&
|
||||||
|
// reachedTPPrice > 0;
|
||||||
|
// if (canDoBreakEven)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// X121SMCGuard iGuard;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// iGuard.time = cTime;
|
||||||
|
// iGuard.symbol = symbol;
|
||||||
|
// iGuard.provider = provider;
|
||||||
|
// iGuard.action = X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// iGuard.ticket = iPosition.ticket;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// iGuard.volumeMultiplier = 0.5;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// AddGuard(
|
||||||
|
// iGuard,
|
||||||
|
// guards //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_TRAIL_STOP:
|
||||||
|
// // Trail Stop Specified Position on Specified Conditions ...
|
||||||
|
// if (!isTrailStopIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// for (int i = 0; i < count; i++)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// XPosition iPosition = ownPositions[i];
|
||||||
|
|
||||||
|
// //
|
||||||
|
// bool isLong = IsLong(iPosition.type);
|
||||||
|
// bool isInProfit = iPosition.profit > 0;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// double reachedTPLevel = 0;
|
||||||
|
// double reachedTPPrice = 0;
|
||||||
|
// if (isInProfit)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// iPosition.CalculateReahedTP(
|
||||||
|
// reachedTPLevel,
|
||||||
|
// reachedTPPrice //
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Trai Stop ...
|
||||||
|
// if (!isInProfit)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// double trailedStop = 0;
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Trail Stop Senarios ...
|
||||||
|
// // - occures two same type consolidation zones in order of positions type;
|
||||||
|
// // - occures a swing in order of consolidation zones ...
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // bool canTrailBasedOnTwoZone =
|
||||||
|
// // isLong
|
||||||
|
// // ? isLastBullishAbovePrev
|
||||||
|
// // : isLastBearishBelowPrev;
|
||||||
|
// // if (canTrailBasedOnTwoZone)
|
||||||
|
// // {
|
||||||
|
// // //
|
||||||
|
// // trailedStop =
|
||||||
|
// // isLong
|
||||||
|
// // ? prevLastBullishBox.lower
|
||||||
|
// // : prevLastBearishBox.upper;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // bool canTrailBasedOnZoneSwing =
|
||||||
|
// // trailedStop <= 0 &&
|
||||||
|
// // (isLong
|
||||||
|
// // ? isStrongSwingLowAboveLastBullishBox
|
||||||
|
// // : isStrongSwingHighBelowLastBearishBox);
|
||||||
|
// // if (canTrailBasedOnZoneSwing)
|
||||||
|
// // {
|
||||||
|
// // //
|
||||||
|
// // trailedStop =
|
||||||
|
// // isLong
|
||||||
|
// // ? pBar.low
|
||||||
|
// // : pBar.high;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // bool canDoTrailStop =
|
||||||
|
// // trailedStop > 0 &&
|
||||||
|
// // (
|
||||||
|
// // //
|
||||||
|
// // iPosition.sl == 0
|
||||||
|
// // ? (isLong
|
||||||
|
// // ? trailedStop > iPosition.entry &&
|
||||||
|
// // trailedStop < iPosition.price
|
||||||
|
// // : trailedStop < iPosition.entry &&
|
||||||
|
// // trailedStop > iPosition.price)
|
||||||
|
// // : (isLong
|
||||||
|
// // ? trailedStop > iPosition.sl &&
|
||||||
|
// // trailedStop > iPosition.entry &&
|
||||||
|
// // trailedStop < iPosition.price
|
||||||
|
// // : trailedStop < iPosition.sl &&
|
||||||
|
// // trailedStop < iPosition.entry &&
|
||||||
|
// // trailedStop > iPosition.price)
|
||||||
|
// // //
|
||||||
|
// // )
|
||||||
|
// // //
|
||||||
|
// // ;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // if (canDoTrailStop)
|
||||||
|
// // {
|
||||||
|
// // //
|
||||||
|
// // X121SMCGuard iGuard;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // iGuard.time = cTime;
|
||||||
|
// // iGuard.symbol = symbol;
|
||||||
|
// // iGuard.provider = provider;
|
||||||
|
// // iGuard.action = X_121_SMC_GUARD_ACTION_TRAIL_STOP;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // iGuard.ticket = iPosition.ticket;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // iGuard.sl = trailedStop;
|
||||||
|
|
||||||
|
// // //
|
||||||
|
// // AddGuard(
|
||||||
|
// // iGuard,
|
||||||
|
// // guards //
|
||||||
|
// // );
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_TRAIL_TARGET:
|
||||||
|
// // Trail Target Specified Position on Specified Conditions ...
|
||||||
|
// if (!isTrailTargetIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // X_121_SMC_GUARD_ACTION_HEDGE:
|
||||||
|
// // Hedge all Positions on Specified Conditions ...
|
||||||
|
// if (!isHedgeIgnored)
|
||||||
|
// {
|
||||||
|
// //
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Cleanup Collections ...
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(ownPositions);
|
||||||
|
// Clean(ownLongPositions);
|
||||||
|
// Clean(ownShortPositions);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// zBar.Clean();
|
||||||
|
// cBar.Clean();
|
||||||
|
// pBar.Clean();
|
||||||
|
// ppBar.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// Clean(visionPoiEvents);
|
||||||
|
// Clean(analysePoiEvents);
|
||||||
|
// Clean(visionCycleEvents);
|
||||||
|
// Clean(decisionPoiEvents);
|
||||||
|
// Clean(analyseCycleEvents);
|
||||||
|
// Clean(decisionCycleEvents);
|
||||||
|
// Clean(consolidationPoiEvents);
|
||||||
|
// Clean(consolidationCycleEvents);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// visionState.Clean();
|
||||||
|
// analyseState.Clean();
|
||||||
|
// decisionState.Clean();
|
||||||
|
// visionConditions.Clean();
|
||||||
|
// analyseConditions.Clean();
|
||||||
|
// visionXConditions.Clean();
|
||||||
|
// decisionConditions.Clean();
|
||||||
|
// consolidationState.Clean();
|
||||||
|
// analyseXConditions.Clean();
|
||||||
|
// decisionXConditions.Clean();
|
||||||
|
// consolidationConditions.Clean();
|
||||||
|
// consolidationXConditions.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // lastBullishBox.Clean();
|
||||||
|
// // lastBearishBox.Clean();
|
||||||
|
// // lastBullishZone.Clean();
|
||||||
|
// // lastBearishZone.Clean();
|
||||||
|
// // prevLastBullishBox.Clean();
|
||||||
|
// // prevLastBearishBox.Clean();
|
||||||
|
// // prevLastBullishZone.Clean();
|
||||||
|
// // prevLastBearishZone.Clean();
|
||||||
|
|
||||||
|
// //
|
||||||
|
// count = ArraySize(guards);
|
||||||
|
// result = IsValidSize(count);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,737 @@
|
|||||||
|
///////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SaherElm IT Center MQL5 Common Library
|
||||||
|
// --------------------------------------
|
||||||
|
// Name: X121SMCLib
|
||||||
|
// 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 "../../Classes/x-saherelm.base.class.mq5"
|
||||||
|
#include "../../Classes/x-saherelm.x-poi.drawer.class.mq5"
|
||||||
|
#include "../../Helpers/x-saherelm.x121.helper.mq5"
|
||||||
|
#include "../../Libraries/x-saherelm.common.lib.mq5"
|
||||||
|
#include "../../Libraries/x-saherelm.x-poi.extensions.lib.mq5"
|
||||||
|
#include "../../Libraries/x-saherelm.x-poi.lib.mq5"
|
||||||
|
#include "../../Libraries/x-saherelm.x-trade.lib.mq5"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
const string X121SMCStrategyToken = "X121SMC";
|
||||||
|
|
||||||
|
//
|
||||||
|
const string X121SMCXWZToken = "X121XWZ";
|
||||||
|
|
||||||
|
//
|
||||||
|
// X121 SMC Providers ...
|
||||||
|
enum ENUM_X_121_SMC_PROVIDERS
|
||||||
|
{
|
||||||
|
//
|
||||||
|
X_121_SMC_PROVIDER_NONE,
|
||||||
|
X_121_SMC_PROVIDER_XWZ,
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Guard Actions ...
|
||||||
|
enum ENUM_X_121_SMC_GUARD_ACTIONS
|
||||||
|
{
|
||||||
|
X_121_SMC_GUARD_ACTION_NONE, // Nothing to Do
|
||||||
|
X_121_SMC_GUARD_ACTION_CLOSE, // Close Specified Position
|
||||||
|
X_121_SMC_GUARD_ACTION_CLOSE_ALL, // Close All Positions
|
||||||
|
X_121_SMC_GUARD_ACTION_CLOSE_LONGS, // Close All Long Positions
|
||||||
|
X_121_SMC_GUARD_ACTION_CLOSE_SHORTS, // Close All Short Position
|
||||||
|
X_121_SMC_GUARD_ACTION_PARTIAL_CLOSE, // Partial Close Specified Position
|
||||||
|
X_121_SMC_GUARD_ACTION_TRAIL_STOP, // Trail Stop of Specified Position
|
||||||
|
X_121_SMC_GUARD_ACTION_TRAIL_TARGET, // Trail Target of Specified Position
|
||||||
|
X_121_SMC_GUARD_ACTION_HEDGE, // Hedge Specified Positions
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Each Market Cycle (Time Frame) Conditions
|
||||||
|
// Model as this Structure ...
|
||||||
|
struct X121SMCCycleConditions
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbol;
|
||||||
|
ENUM_TIMEFRAMES period;
|
||||||
|
datetime time;
|
||||||
|
|
||||||
|
//
|
||||||
|
XPOIState state;
|
||||||
|
X121Conditions x121Conditions;
|
||||||
|
|
||||||
|
//
|
||||||
|
void X121SMCStrategyConditions()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup ...
|
||||||
|
*/
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
symbol = NULL;
|
||||||
|
period = NULL;
|
||||||
|
time = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
state.Clean();
|
||||||
|
x121Conditions.Clean();
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsSpecifiedValid(symbol) &&
|
||||||
|
IsSpecifiedValid(period) &&
|
||||||
|
IsSpecifiedValid(time);
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reporter Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Provided Scores ...
|
||||||
|
*
|
||||||
|
* @param bullishScore: Integer, reference ...
|
||||||
|
* @param bearishScore: Integer, referenceF ...
|
||||||
|
*/
|
||||||
|
void GenerateScore(
|
||||||
|
double &bullishScore,
|
||||||
|
double &bearishScore //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bullishScore = 0;
|
||||||
|
bearishScore = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double bullScore = 0;
|
||||||
|
double bearScore = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Summary ...
|
||||||
|
*
|
||||||
|
* @param onlyCommons: Boolean ...
|
||||||
|
* @param onlyConditions: Boolean ...
|
||||||
|
* @param includeScores: Boolean ...
|
||||||
|
* @param ignoreFalseConditions: Boolean ...
|
||||||
|
* @param separator: String ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GenerateSummary(
|
||||||
|
bool onlyCommons = false,
|
||||||
|
bool onlyConditions = false,
|
||||||
|
bool includeScores = true,
|
||||||
|
bool ignoreFalseConditions = true,
|
||||||
|
string separator = "\n" //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
double bullishScore = 0;
|
||||||
|
double bearishScore = 0;
|
||||||
|
GenerateScore(
|
||||||
|
bullishScore,
|
||||||
|
bearishScore //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
string commonStr = GenerateSpecifiedCommonSummary(
|
||||||
|
this,
|
||||||
|
separator,
|
||||||
|
includeScores,
|
||||||
|
true //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
string conditionsStr =
|
||||||
|
//
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
"[" + GetTag() + "]" + separator +
|
||||||
|
"----------" + separator +
|
||||||
|
(onlyConditions
|
||||||
|
? ""
|
||||||
|
: commonStr) +
|
||||||
|
" " + separator +
|
||||||
|
(onlyCommons
|
||||||
|
? ""
|
||||||
|
: conditionsStr) +
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Unique Identifier ...
|
||||||
|
*
|
||||||
|
* @param forObject: Boolean ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GetTag(
|
||||||
|
bool forObject = false //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
string typeName = GetTypeName(this);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!forObject)
|
||||||
|
{
|
||||||
|
result = typeName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = typeName + "_" +
|
||||||
|
symbol + "_" + ToString(period) + "_" +
|
||||||
|
ToMD5(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Model Signalling Conditions ...
|
||||||
|
struct X121SMCStrategyConditions
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string symbol;
|
||||||
|
ENUM_TIMEFRAMES period;
|
||||||
|
datetime time;
|
||||||
|
|
||||||
|
//
|
||||||
|
double sl;
|
||||||
|
double tp;
|
||||||
|
string provider;
|
||||||
|
double targets[];
|
||||||
|
ENUM_X_DIRECTION signalDir;
|
||||||
|
|
||||||
|
//
|
||||||
|
void X121SMCStrategyConditions()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup ...
|
||||||
|
*/
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
time = NULL;
|
||||||
|
symbol = NULL;
|
||||||
|
period = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
sl = 0;
|
||||||
|
tp = 0;
|
||||||
|
provider = NULL;
|
||||||
|
signalDir = X_DIRECTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
Clean(targets);
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = IsSpecifiedValid(symbol) &&
|
||||||
|
IsSpecifiedValid(period) &&
|
||||||
|
IsSpecifiedValid(time);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Conditions Has Valid Bullish Signal ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool HasBullishSignal()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
(sl > 0 ||
|
||||||
|
tp > 0) &&
|
||||||
|
IsValid() &&
|
||||||
|
HasDirection(signalDir);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
IsBullish(signalDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Conditions Has Valid Bearish Signal ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool HasBearishSignal()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
(sl > 0 ||
|
||||||
|
tp > 0) &&
|
||||||
|
IsValid() &&
|
||||||
|
HasDirection(signalDir);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
IsBearish(signalDir);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reporter Functions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Provided Scores ...
|
||||||
|
*
|
||||||
|
* @param bullishScore: Integer, reference ...
|
||||||
|
* @param bearishScore: Integer, referenceF ...
|
||||||
|
*/
|
||||||
|
void GenerateScore(
|
||||||
|
double &bullishScore,
|
||||||
|
double &bearishScore //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bullishScore = 0;
|
||||||
|
bearishScore = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
double bullScore = 0;
|
||||||
|
double bearScore = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Summary ...
|
||||||
|
*
|
||||||
|
* @param onlyCommons: Boolean ...
|
||||||
|
* @param onlyConditions: Boolean ...
|
||||||
|
* @param includeScores: Boolean ...
|
||||||
|
* @param ignoreFalseConditions: Boolean ...
|
||||||
|
* @param separator: String ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GenerateSummary(
|
||||||
|
bool onlyCommons = false,
|
||||||
|
bool onlyConditions = false,
|
||||||
|
bool includeScores = true,
|
||||||
|
bool ignoreFalseConditions = true,
|
||||||
|
string separator = "\n" //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
double bullishScore = 0;
|
||||||
|
double bearishScore = 0;
|
||||||
|
GenerateScore(
|
||||||
|
bullishScore,
|
||||||
|
bearishScore //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
string commonStr = GenerateSpecifiedCommonSummary(
|
||||||
|
this,
|
||||||
|
separator,
|
||||||
|
includeScores,
|
||||||
|
true //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
string conditionsStr =
|
||||||
|
//
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
"[" + GetTag() + "]" + separator +
|
||||||
|
"----------" + separator +
|
||||||
|
(onlyConditions
|
||||||
|
? ""
|
||||||
|
: commonStr) +
|
||||||
|
" " + separator +
|
||||||
|
(onlyCommons
|
||||||
|
? ""
|
||||||
|
: conditionsStr) +
|
||||||
|
""
|
||||||
|
//
|
||||||
|
;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Unique Identifier ...
|
||||||
|
*
|
||||||
|
* @param forObject: Boolean ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string GetTag(
|
||||||
|
bool forObject = false //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
string typeName = GetTypeName(this);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!forObject)
|
||||||
|
{
|
||||||
|
result = typeName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
result = typeName + "_" +
|
||||||
|
symbol + "_" + ToString(period) + "_" +
|
||||||
|
ToMD5(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Model a Guard Action ...
|
||||||
|
struct X121SMCGuard
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Props ...
|
||||||
|
ENUM_X_121_SMC_GUARD_ACTIONS action;
|
||||||
|
datetime time;
|
||||||
|
|
||||||
|
//
|
||||||
|
string symbol;
|
||||||
|
string provider;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Specified Position ...
|
||||||
|
ulong ticket;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Partial Close ...
|
||||||
|
double volumeMultiplier;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SL Trial ...
|
||||||
|
double sl;
|
||||||
|
|
||||||
|
//
|
||||||
|
// TP Trial ...
|
||||||
|
double tp;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Constructor ...
|
||||||
|
X121SMCGuard()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tools ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup ...
|
||||||
|
*/
|
||||||
|
void Clean()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
time = NULL;
|
||||||
|
action = X_121_SMC_GUARD_ACTION_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
symbol = NULL;
|
||||||
|
provider = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
ticket = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
volumeMultiplier = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
sl = 0;
|
||||||
|
tp = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
ZeroMemory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result =
|
||||||
|
//
|
||||||
|
IsValid(time) &&
|
||||||
|
IsValid(symbol) &&
|
||||||
|
IsValid(provider) &&
|
||||||
|
action != X_121_SMC_GUARD_ACTION_NONE
|
||||||
|
//
|
||||||
|
;
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Validate Model Based On Specified Guard Actions ...
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Guard to Collection ...
|
||||||
|
*
|
||||||
|
* @param guard: X121SMCGuard instance ...
|
||||||
|
* @param guards: X121SMCGuard instance Collection ...
|
||||||
|
*
|
||||||
|
* @return ( int )
|
||||||
|
*/
|
||||||
|
int AddGuard(
|
||||||
|
X121SMCGuard &guard,
|
||||||
|
X121SMCGuard &guards[] //
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!guard.IsValid())
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
AddRef(
|
||||||
|
guard,
|
||||||
|
guards //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
result = ArraySize(guards);
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef void (*TOnX121SMCSignal)(
|
||||||
|
XSignal &signal,
|
||||||
|
X121SMCStrategyConditions &conditions //
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extentions ...
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a Signal Provider ...
|
||||||
|
*
|
||||||
|
* @param value: ENUM_X_121_SMC_PROVIDERS member ...
|
||||||
|
*
|
||||||
|
* @return ( bool )
|
||||||
|
*/
|
||||||
|
bool IsValid(ENUM_X_121_SMC_PROVIDERS value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
result = value != X_121_SMC_PROVIDER_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a Signal Provider to String ...
|
||||||
|
*
|
||||||
|
* @param value: ENUM_X_121_SMC_PROVIDERS member ...
|
||||||
|
*
|
||||||
|
* @return ( string )
|
||||||
|
*/
|
||||||
|
string ToString(ENUM_X_121_SMC_PROVIDERS value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
string result = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid(value))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
case X_121_SMC_PROVIDER_XWZ:
|
||||||
|
result = X121SMCXWZToken;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse Specified String as a Signal Provider ...
|
||||||
|
*
|
||||||
|
* @param value: String ...
|
||||||
|
*
|
||||||
|
* @return ( ENUM_X_121_SMC_PROVIDERS )
|
||||||
|
*/
|
||||||
|
ENUM_X_121_SMC_PROVIDERS ParseProvider(string value)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
ENUM_X_121_SMC_PROVIDERS result = X_121_SMC_PROVIDER_NONE;
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!IsValid(value))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (Contains(X121SMCXWZToken, value))
|
||||||
|
{
|
||||||
|
result = X_121_SMC_PROVIDER_XWZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
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
Reference in New Issue
Block a user