update workspace ...

This commit is contained in:
2024-05-17 04:54:01 +03:30
parent 3fa288c92c
commit 642713072e
429 changed files with 111729 additions and 9330 deletions
@@ -0,0 +1,385 @@
///////////////////////////////////////////////////////
//
// 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
//
// START Definitions ...
//
//
enum X_HTTP_METHOD
{
X_HTTP_GET,
X_HTTP_POST
};
//
// 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;
}
//
// END Definitions ...
//
//
// START Import and Inclused requirements ...
//
//
// Includes ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Import and Inclused requirements ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Class for Manage Account ...
class XSCHttp
{
//
// Public ...
public:
//
// Constructor ...
void XSCHttp()
{
XSCHttp("", 10000);
}
void XSCHttp(
string path, // Base Folder to Store Data
int timeout // base timeout for Requests
)
{
//
Path(path);
Timeout(timeout);
}
//
// Deconstructor ...
void ~XSCHttp()
{
}
//
// START Getter(s)/Setter(s) ...
//
//
// Path ...
void Path(string value)
{
mPath = value;
}
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;
}
//
// END Getter(s)/Setter(s) ...
//
//
// START Provided Functions ...
//
//
// 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;
}
};
//
// START Usefull Functions ...
//
//
// END Usefull Functions ...
//
@@ -0,0 +1,62 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSC121Provider
// Description: a Market Analyser and Signal Provider
//
//
// 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
//
// TODO:
// - [] add XCT for Candle Timing ...
// - [] add XCS for Candle Styling ...
// - [] add Support for XZG Indicator ...
// - [] implement XPV based on Market Cycles ...
// - [] create XPV Helper class ...
// - [] create XZG Helper class ...
// - [] add Pivots Functionality based on XZG and XPV ...
// - [] add File as Struct functionality and implement it ...
// - [] add Support for OnSignal Event ...
// - [] add support for Alerting ...
// - [] Refactor XSignal:
// -- [] Add support for Multiple TPS and Trailing Stops ...
// -- [] Add support for Clean, Constructor and Init Functions on struct ...
// -- [] Add support for Prepare Signal inside struct ...
// -- [] Add Support for Position Management inside XTrade Class for Handling
// Trail SL, or Partial Close Positions ...
// -- [] Convert providers from Array to string ...
// -- [] Add Support For Serializing and also Deseriallizing functionality ...
//
// Imports ...
//
#include "../Classes/x-saherelm.x121.xmcycle.class.mq5"
//
// Definitions ...
//
// Configuration of X121 Provider ...
struct X121ProviderInputs
{
};
//
// Class ...
//
// Tools ...
File diff suppressed because it is too large Load Diff
@@ -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 <Trade/AccountInfo.mqh>
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Import and Inclused requirements ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Class for Manage Account ...
class XSCAccount
{
//
// Public ...
public:
//
// Constructor ...
void XSCAccount()
{
//
mAccountInfo = new CAccountInfo();
}
//
// Deconstructor ...
void ~XSCAccount()
{
}
//
// 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 ...
//
@@ -0,0 +1,444 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCDataCollector
// Description: provides Data Collection 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 "../Libraries/x-saherelm.common.lib.mq5"
//
template <typename T>
class XSCDataCollector
{
//
// Public ...
public:
//
// Props ...
//
// Constructors ...
void XSCDataCollector(
string path = NULL, // Base Folder for Data Store
string fileName = NULL // File Name for Data Store
)
{
//
if (!IsValid(path))
{
path = GetType();
}
//
if (!IsValid(fileName))
{
fileName = GetType() + ".txt";
}
//
Path(path);
FileName(fileName);
}
//
// Deconstructor ...
void ~XSCDataCollector() {}
//
// Properties ...
//
bool Path(string value)
{
//
bool result = false;
//
result = IsValid(value);
if (!result)
{
return result;
}
//
result = value != mPath;
if (!result)
{
return result;
}
//
mPath = value;
//
return result;
}
//
string Path()
{
return mPath;
}
//
bool FileName(string value)
{
//
bool result = false;
//
result = IsValid(value);
if (!result)
{
return result;
}
//
result = value != mFileName;
if (!result)
{
return result;
}
//
mFileName = value;
//
return result;
}
//
string FileName()
{
return mFileName;
}
//
// Tools ...
//
// Clear Exists Collected Data ...
void Clear()
{
//
ResetLastError();
//
string dataStorePath = GetStorePath();
//
// Check Data Store Exists or not ...
bool isExists = FileIsExist(dataStorePath);
if (!isExists)
{
return;
}
//
FileDelete(dataStorePath);
}
//
// Collect All Stored Items ...
int Collect(
T &items[] // Hold Result
)
{
//
int result = 0;
//
Clean(items);
//
// Reading Store Whole Content ...
//
string storePath = GetStorePath();
int mFileHandler = FileOpen(
storePath,
FILE_READ | FILE_TXT);
result = mFileHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
// Parse Store Content and Read Data ...
while (!FileIsEnding(mFileHandler))
{
//
// Each Line Represent One Model ...
string content = FileReadString(mFileHandler);
//
T iItem;
bool isValid = iItem.Parse(content);
if (isValid)
{
//
AddRef(
iItem,
items
//
);
}
}
//
// Close File ...
FileClose(mFileHandler);
//
result = ArraySize(items);
//
return result;
}
//
// Add Item ...
bool Add(
T &item // Item to Store
)
{
//
bool result = false;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
string content = item.ToString();
result = IsValid(content);
if (!result)
{
return result;
}
//
string storePath = GetStorePath();
int mFileHandler = FileOpen(
storePath,
FILE_READ | FILE_WRITE | FILE_TXT);
result = mFileHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
FileSeek(mFileHandler, 0, SEEK_END);
FileWrite(mFileHandler, content);
FileFlush(mFileHandler);
FileClose(mFileHandler);
//
return result;
}
//
// Add Items ...
int Add(
T &items[] // Items to Add ...
)
{
//
int result = 0;
//
int itemsCount = ArraySize(items);
if (itemsCount <= 0)
{
return result;
}
//
for (int i = 0; i < itemsCount; i++)
{
//
T iItem = items[i];
//
if (!iItem.IsValid())
{
continue;
}
//
bool isAdded = Add(iItem);
if (isAdded)
{
result++;
}
}
//
return result;
}
//
// Remove Item ...
bool Remove(
T &item // Item to Remove
)
{
//
bool result = false;
//
result = item.IsValid();
if (!result)
{
return result;
}
//
T items[];
int itemsCount = Collect(items);
if (itemsCount <= 0)
{
return result;
}
//
int itemIndex = item.FindIndex(items);
result = ArrayRemove(
items,
itemIndex,
1);
if (!result)
{
return result;
}
//
Clear();
//
int itemsAdded = Add(items);
//
result = itemsAdded == ArraySize(items);
//
return result;
}
//
// Protected ...
protected:
//
// Tools ...
//
// Retrieve Type of Class as String ...
string GetType()
{
//
string mType = (string) typename(T);
//
string result = mType;
//
string parts[];
int partsCount = SplitContent(
parts,
result,
" "
//
);
if (partsCount <= 0)
{
//
result = mType;
return result;
}
//
bool hasLastPart = GetLastItem(
result,
parts
//
);
if (!hasLastPart)
{
//
result = mType;
return result;
}
//
return result;
}
//
// Pricate ...
private:
//
// Props ...
//
string mPath; // Path
string mFileName; // Data Store File Name
//
// Tools ...
//
// Generate Full File Path ...
string GetFilePath(string fileName)
{
//
string result = "";
//
result =
//
Path() + "\\" + fileName
//
;
//
return result;
}
//
// Retrieve Data Store File Address ...
string GetStorePath()
{
//
string result = NULL;
//
result = GetFilePath(mFileName);
//
return result;
}
};
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,123 @@
///////////////////////////////////////////////////////
//
// 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 "../Libraries/x-saherelm.common.lib.mq5"
//
// Definitions ...
//
// a Class for Handle base requirements ...
// for indicators ...
class XSCBaseHelper
{
//
// Public ...
public:
//
// Constructor ...
void XSCBaseHelper(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period // Trading Time Frame
)
{
//
mSymbol = symbol;
mPeriod = period;
}
//
// Deconstructor ...
void ~XSCBaseHelper()
{
//
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;
}
//
int CountCalculatedBars()
{
return BarsCalculated(mHandler);
}
//
// Functions ...
//
// Protected ...
protected:
//
// Props ...
//
// Symbol ...
string mSymbol;
//
// Period ...
ENUM_TIMEFRAMES mPeriod;
//
// Indicator Handler ...
int mHandler;
//
// Private ...
private:
//
};
//
// Tools ....
@@ -0,0 +1,441 @@
///////////////////////////////////////////////////////
//
// 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 XSCMD5
{
//
// Public Provides ...
public:
//
// Protected Provides ...
//
// Constructor ...
XSCMD5(void) {}
//
// Deconstructor ...
~XSCMD5(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;
}
};
@@ -0,0 +1,319 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCEABaseProvider
// Description: provides base requirements for
// Specific Sgnal Provider ...
//
//
// 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 Import and Inclused requirements ...
//
//
// Includes ...
#include "../Libraries/x-saherelm.log.lib.mq5"
#include "../Libraries/x-saherelm.draw.lib.mq5"
#include "../Libraries/x-saherelm.models.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Import and Inclused requirements ...
//
//
// START Definitions ...
//
//
// Notified a Signal was Appears ...
typedef void (*OnSignal)(
XSignal &signal);
//
// Notified a Guard Appears ...
typedef void (*OnGuard)(XGuard &guard);
//
// END Definitions ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Base Class for All of our EA's ...
class XSCEABaseProvider
{
//
// Public ...
public:
//
// Constructor ...
void XSCEABaseProvider()
{
mSymbol = _Symbol;
mPeriod = _Period;
}
void XSCEABaseProvider(
string symbol,
ENUM_TIMEFRAMES period,
bool ignoreTicksAfterSignalTillNewCandle = true)
{
//
mSymbol = symbol;
mPeriod = period;
//
mTag = mSymbol + "," + ToString(mPeriod);
//
mIsInTestMode = IsRunningOnTestMode();
//
mIgnoreTicksAfterSignalTillNewCandle = ignoreTicksAfterSignalTillNewCandle;
}
//
// Deconstructor ...
void ~XSCEABaseProvider()
{
}
//
bool CanIgnoreTick()
{
//
mIsNewCandle = IsNewCandle(
mSymbol,
mPeriod);
bool result = mIsInTestMode
? !mIsNewCandle
: !mIsNewCandle && mWaitUntilNewCandle;
//
if (result)
{
//
result = mIgnoreTicksAfterSignalTillNewCandle;
}
//
return result;
}
//
// Prepare State ...
void OnTick()
{
//
mIsNewCandle = IsNewCandle(
mSymbol,
mPeriod);
mCanIgnoreTick = mIsInTestMode
? !mIsNewCandle
: !mIsNewCandle && mWaitUntilNewCandle;
//
ProcessBuffers();
//
if (mCanIgnoreTick)
{
return;
}
//
mWaitUntilNewCandle = false;
//
ProcessTick();
}
//
virtual void PrepareTag();
//
// Initialize Indicators and Requirements ...
virtual bool Init();
//
virtual int GetMaxLength();
//
virtual int GetCalculatedBars();
//
// Handle Update Buffers ...
virtual void ProcessBuffers()
{
return;
}
//
// Handle On Tick Event ...
virtual void ProcessTick()
{
return;
}
//
// Check for Guards ...
virtual bool GuardCheck(XGuard &guards[]);
//
// Add Specific On Signal Event Handler ...
int AddOnSignalEventHandler(OnSignal handler)
{
//
ArrayResize(
mSignalEventHandlers,
ArraySize(mSignalEventHandlers) + 1);
//
int result = ArraySize(mSignalEventHandlers) - 1;
mSignalEventHandlers[result] = handler;
//
return result;
}
//
// Remove All On Signal Event Handler ...
void ReoveOnSignalEventHandlers()
{
//
ArrayFree(mSignalEventHandlers);
}
//
// Notify a Signal Found on all Event Listeners ...
void NotifyOnSignalEvent(XSignal &info)
{
//
int listenerCount = ArraySize(mSignalEventHandlers);
if (listenerCount <= 0)
{
return;
}
//
// Loop Through Listeners ...
for (int i = 0; i < listenerCount; i++)
{
//
OnSignal listener = mSignalEventHandlers[i];
//
listener(info);
}
}
//
// Protected ...
protected:
//
string mSymbol;
//
ENUM_TIMEFRAMES mPeriod;
//
string mTag;
//
bool mIsNewCandle;
bool mIsInTestMode;
bool mCanIgnoreTick;
bool mWaitUntilNewCandle;
//
// Private ...
private:
//
// Signal Event Handlers ...
OnSignal mSignalEventHandlers[];
//
bool mIgnoreTicksAfterSignalTillNewCandle;
};
//
// START Definitions ...
//
//
// Model Signal Providers Definitions ...
struct XBaseSignalProvider
{
//
// Provider use Which Symbol ...
string symbol;
//
// Provider use Which Time Frame ...
ENUM_TIMEFRAMES period;
//
// Risk Amount Per Trades Related to Time Frames ...
// Percent of Available Balance ...
double riskAmount;
//
// Desired Magic Number ...
ulong magicNumber;
};
//
struct XLastSignal
{
datetime at;
string provider;
};
//
// END Definitions ...
//
//
// START Usefull Functions ...
//
//
// Add Specific Provider to List ...
void Add(
XBaseSignalProvider &item, // item want to add
XBaseSignalProvider &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
//
// END Usefull Functions ...
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,348 @@
//////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// ---------------------------------------------
// Name: X121_XDEMA
// Description: Super Trend 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_XAMA Indicator"
#property strict
//
// START Constants ...
//
#define ShortName "X121_XDEMA"
//
// END Constants ...
//
//
// START Inputs ...
//
//
// Market ...
input group "Market";
input int length = 200; // Length
input int shift = 0; // Shift
//
// Presentation ...
input group "Presentation";
input bool showDema = true; // Show Dema
input bool showEMA = false; // Show EMA
input bool showEMAOfEMA = false; // Show EMA of EMA
//
// END Inputs ...
//
//
// Includes Common Library ...
#include <MovingAverages.mqh>
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// START Buffers ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 6
#property indicator_plots 6
//
#define demaBufferIndex 0
double demaBuffer[];
//
#define demaColorBufferIndex 1
double demaColorBuffer[];
//
#property indicator_label1 "X121_XDEMA DEMA"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 clrDodgerBlue, CLR_NONE
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//
#define emaBufferIndex 2
double emaBuffer[];
//
#define emaColorBufferIndex 3
double emaColorBuffer[];
//
#property indicator_label2 "X121_XDEMA EMA"
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_color2 clrBlue, CLR_NONE
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//
#define emaOfEMABufferIndex 4
double emaOfEMABuffer[];
//
#define emaOfEMAColorBufferIndex 5
double emaOfEMAColorBuffer[];
//
#property indicator_label3 "X121_XDEMA EMA of EMA"
#property indicator_type3 DRAW_COLOR_LINE
#property indicator_color3 clrOrange, CLR_NONE
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
int maxLength;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
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 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;
}
//
// 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
}
//
// Do Calculations ...
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
//
ArraySetAsSeries(price, true);
//
// check for data ...
if (rates_total < 2 * length - 2)
{
return 0;
}
//
int limit;
//
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
//
// calculate EMA ...
ExponentialMAOnBuffer(rates_total, prev_calculated, 0, length, price, emaBuffer);
//
// calculate EMA on EMA array ...
ExponentialMAOnBuffer(rates_total, prev_calculated, length - 1, length, emaBuffer, emaOfEMABuffer);
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
// calculate DEMA ...
demaBuffer[i] = 2 * emaBuffer[i] - emaOfEMABuffer[i];
//
double showColorIDX = 0;
double hideColorIDX = 1;
//
demaColorBuffer[i] = hideColorIDX;
emaColorBuffer[i] = hideColorIDX;
emaOfEMAColorBuffer[i] = hideColorIDX;
//
if (showDema)
{
demaColorBuffer[i] = showColorIDX;
}
//
if (showEMA)
{
emaColorBuffer[i] = showColorIDX;
}
//
if (showEMAOfEMA)
{
emaOfEMAColorBuffer[i] = showColorIDX;
}
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result =
//
(length > 2 &&
shift >= 0)
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
// Peaks and Vales ...
result = length;
//
return result;
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// DEMA ...
//
// Buffer ...
ArraySetAsSeries(demaBuffer, true);
SetIndexBuffer(demaBufferIndex, demaBuffer, INDICATOR_DATA);
PlotIndexSetInteger(demaBufferIndex, PLOT_SHOW_DATA, showDema);
//
// Color Buffer ...
ArraySetAsSeries(demaColorBuffer, true);
SetIndexBuffer(demaColorBufferIndex, demaColorBuffer, INDICATOR_COLOR_INDEX);
//
// EMA ...
//
// Buffer ...
ArraySetAsSeries(emaBuffer, true);
SetIndexBuffer(emaBufferIndex, emaBuffer, INDICATOR_DATA);
PlotIndexSetInteger(emaBufferIndex, PLOT_SHOW_DATA, showEMA);
//
// Color Buffer ...
ArraySetAsSeries(emaColorBuffer, true);
SetIndexBuffer(emaColorBufferIndex, emaColorBuffer, INDICATOR_COLOR_INDEX);
//
// EMA of EMA ...
//
// Buffer ...
ArraySetAsSeries(emaOfEMABuffer, true);
SetIndexBuffer(emaOfEMABufferIndex, emaOfEMABuffer, INDICATOR_DATA);
PlotIndexSetInteger(emaOfEMABufferIndex, PLOT_SHOW_DATA, showEMAOfEMA);
//
// Color Buffer ...
ArraySetAsSeries(emaOfEMAColorBuffer, true);
SetIndexBuffer(emaOfEMAColorBufferIndex, emaOfEMAColorBuffer, INDICATOR_COLOR_INDEX);
}
//
// END Functions ...
//
@@ -0,0 +1,365 @@
///////////////////////////////////////////////////////
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------
// Name: XDON
// Description: DONCHAIN Channel ...
//
// 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 XDON Indicator"
#property strict
//
#define ShortName "XDON"
//
// INPUT ...
//
input int length = 52; // Market Length
input double offset = 0; // Offset
//
// BUFFERS ...
//
#property indicator_chart_window
//
#property indicator_buffers 8
#property indicator_plots 8
//
#define upperOBufferIndex 0
double upperOBuffer[];
//
#property indicator_label1 "XDON OU"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrCornflowerBlue
#property indicator_width1 2
//
#define lowerOBufferIndex 1
double lowerOBuffer[];
//
#property indicator_label2 "XDON OL"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrCornflowerBlue
#property indicator_width2 2
//
#define upperCBufferIndex 2
double upperCBuffer[];
//
#property indicator_label3 "XDON CU"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrCoral
#property indicator_width3 2
//
#define lowerCBufferIndex 3
double lowerCBuffer[];
//
#property indicator_label4 "XDON CL"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrCoral
#property indicator_width4 2
//
#define upperHBufferIndex 4
double upperHBuffer[];
//
#property indicator_label5 "XDON HU"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrAquamarine
#property indicator_width5 2
//
#define lowerHBufferIndex 5
double lowerHBuffer[];
//
#property indicator_label6 "XDON HL"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrAquamarine
#property indicator_width6 2
//
#define upperLBufferIndex 6
double upperLBuffer[];
//
#property indicator_label7 "XDON LU"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrDarkOrchid
#property indicator_width7 2
//
#define lowerLBufferIndex 7
double lowerLBuffer[];
//
#property indicator_label8 "XDON LL"
#property indicator_type8 DRAW_LINE
#property indicator_color8 clrDarkOrchid
#property indicator_width8 2
//
// EVENT Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Define Index Buffers ...
DefineBuffers();
//
// 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
}
//
// Calculating what we want ...
int OnCalculate(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
const int &spread[])
{
//
if (rates_total < length - 1)
{
return prev_calculated;
}
//
int start = prev_calculated == 0
? length
: prev_calculated - 1;
//
// Main Loop ...
for (int barIndex = start; barIndex < rates_total; barIndex++)
{
//
// OPEN ...
//
double upperOValue = open[ArrayMaximum(open, barIndex - length + 1, length)];
double lowerOValue = open[ArrayMinimum(open, barIndex - length + 1, length)];
//
double oDelta = MathAbs(upperOValue - lowerOValue);
double oOffsetValue = oDelta * (offset) * 0.01;
//
upperOBuffer[barIndex] = upperOValue - oOffsetValue;
lowerOBuffer[barIndex] = lowerOValue + oOffsetValue;
//
// CLOSE ...
//
double upperCValue = close[ArrayMaximum(close, barIndex - length + 1, length)];
double lowerCValue = close[ArrayMinimum(close, barIndex - length + 1, length)];
//
double cDelta = MathAbs(upperCValue - lowerCValue);
double cOffsetValue = cDelta * (offset) * 0.01;
//
upperCBuffer[barIndex] = upperCValue - cOffsetValue;
lowerCBuffer[barIndex] = lowerCValue + cOffsetValue;
//
// HIGH ...
//
double upperHValue = high[ArrayMaximum(high, barIndex - length + 1, length)];
double lowerHValue = high[ArrayMinimum(high, barIndex - length + 1, length)];
//
double hDelta = MathAbs(upperHValue - lowerHValue);
double hOffsetValue = hDelta * (offset) * 0.01;
//
upperHBuffer[barIndex] = upperHValue - hOffsetValue;
lowerHBuffer[barIndex] = lowerHValue + hOffsetValue;
//
// LOW ...
//
double upperLValue = low[ArrayMaximum(low, barIndex - length + 1, length)];
double lowerLValue = low[ArrayMinimum(low, barIndex - length + 1, length)];
//
double lDelta = MathAbs(upperLValue - lowerLValue);
double lOffsetValue = lDelta * (offset) * 0.01;
//
upperLBuffer[barIndex] = upperLValue - lOffsetValue;
lowerLBuffer[barIndex] = lowerLValue + lOffsetValue;
}
//
return rates_total;
}
//
// CUSTOM Functions ...
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = false;
//
result = length >= 7;
//
return result;
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// Open ...
//
// UPPER ...
SetIndexBuffer(upperOBufferIndex, upperOBuffer, INDICATOR_DATA);
PlotIndexSetInteger(upperOBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(upperOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//
// LOWER ...
SetIndexBuffer(lowerOBufferIndex, lowerOBuffer, INDICATOR_DATA);
PlotIndexSetInteger(lowerOBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(lowerOBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//
// Close ...
//
// UPPER ...
SetIndexBuffer(upperCBufferIndex, upperCBuffer, INDICATOR_DATA);
PlotIndexSetInteger(upperCBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(upperCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//
// LOWER ...
SetIndexBuffer(lowerCBufferIndex, lowerCBuffer, INDICATOR_DATA);
PlotIndexSetInteger(lowerCBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(lowerCBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//
// High ...
//
// UPPER ...
SetIndexBuffer(upperHBufferIndex, upperHBuffer, INDICATOR_DATA);
PlotIndexSetInteger(upperHBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(upperHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//
// LOWER ...
SetIndexBuffer(lowerHBufferIndex, lowerHBuffer, INDICATOR_DATA);
PlotIndexSetInteger(lowerHBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(lowerHBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//
// Low ...
//
// UPPER ...
SetIndexBuffer(upperLBufferIndex, upperLBuffer, INDICATOR_DATA);
PlotIndexSetInteger(upperLBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(upperLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
//
// LOWER ...
SetIndexBuffer(lowerLBufferIndex, lowerLBuffer, INDICATOR_DATA);
PlotIndexSetInteger(lowerLBufferIndex, PLOT_SHOW_DATA, true);
PlotIndexSetDouble(lowerLBufferIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE);
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
@@ -0,0 +1,964 @@
///////////////////////////////////////////////////////
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------
// Name: XDSR
// Description: Dynamic Support and Resistances ...
//
// 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 XDSR Indicator"
#property strict
//
#define ShortName "XDSR"
//
// Includes ...
#include "../Libraries/x-saherelm.log.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// INPUT ...
//
// Maarket ...
input group "Cycles";
//
// Short ...
input group "Short";
input ENUM_X_PERIOD_METHOD scMode = X_PERIOD_MANUALLY; // Method
input ENUM_TIMEFRAMES scPeriod = PERIOD_H4; // Period
//
// Medium ...
input group "Medium";
input ENUM_X_PERIOD_METHOD mcMode = X_PERIOD_MANUALLY; // Method
input ENUM_TIMEFRAMES mcPeriod = PERIOD_H12; // Mid Period
//
// Long ...
input group "Long";
input ENUM_X_PERIOD_METHOD lcMode = X_PERIOD_MANUALLY; // Method
input ENUM_TIMEFRAMES lcPeriod = PERIOD_D1; // Long Period
//
// Hind ...
input group "Hind";
input ENUM_X_PERIOD_METHOD hcMode = X_PERIOD_MANUALLY; // Method
input ENUM_TIMEFRAMES hcPeriod = PERIOD_W1; // Hind Period
//
// BUFFERS ...
//
#property indicator_chart_window
//
#property indicator_buffers 24
#property indicator_plots 24
//
// Short ...
//
// Open ...
//
#define scOpenBufferIndex 0
#define scOpenBufferPlotIndex 0
double scOpenBuffer[];
//
#define scOpenColorBufferIndex 1
double scOpenColorBuffer[];
//
#property indicator_label1 "X121_XDSR SC O"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 clrGreen, clrRed
#property indicator_width1 1
//
// High ...
#define scHighBufferIndex 2
#define scHighBufferPlotIndex 1
double scHighBuffer[];
//
#property indicator_label2 "X121_XDSR SC H"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrAqua
#property indicator_width2 1
//
// Close ...
//
#define scCloseBufferIndex 3
#define scCloseBufferPlotIndex 2
double scCloseBuffer[];
//
#define scCloseColorBufferIndex 4
double scCloseColorBuffer[];
//
#property indicator_label3 "X121_XDSR SC C"
#property indicator_type3 DRAW_COLOR_LINE
#property indicator_color3 clrGreen, clrRed
#property indicator_width3 1
//
// Low ...
#define scLowBufferIndex 5
#define scLowBufferPlotIndex 3
double scLowBuffer[];
//
#property indicator_label4 "X121_XDSR SC L"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrMagenta
#property indicator_width4 1
//
// Medium ...
//
// Open ...
//
#define mcOpenBufferIndex 6
#define mcOpenBufferPlotIndex 4
double mcOpenBuffer[];
//
#define mcOpenColorBufferIndex 7
double mcOpenColorBuffer[];
//
#property indicator_label5 "X121_XDSR MC O"
#property indicator_type5 DRAW_COLOR_LINE
#property indicator_color5 clrGreen, clrRed
#property indicator_width5 1
//
// High ...
#define mcHighBufferIndex 8
#define mcHighBufferPlotIndex 5
double mcHighBuffer[];
//
#property indicator_label6 "X121_XDSR MC H"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrAqua
#property indicator_width6 1
//
// Close ...
//
#define mcCloseBufferIndex 9
#define mcCloseBufferPlotIndex 6
double mcCloseBuffer[];
//
#define mcCloseColorBufferIndex 10
double mcCloseColorBuffer[];
//
#property indicator_label7 "X121_XDSR MC C"
#property indicator_type7 DRAW_COLOR_LINE
#property indicator_color7 clrGreen, clrRed
#property indicator_width7 1
//
// Low ...
#define mcLowBufferIndex 11
#define mcLowBufferPlotIndex 7
double mcLowBuffer[];
//
#property indicator_label8 "X121_XDSR MC L"
#property indicator_type8 DRAW_LINE
#property indicator_color8 clrMagenta
#property indicator_width8 1
//
// Long ...
//
// Open ...
//
#define lcOpenBufferIndex 12
#define lcOpenBufferPlotIndex 8
double lcOpenBuffer[];
//
#define lcOpenColorBufferIndex 13
double lcOpenColorBuffer[];
//
#property indicator_label9 "X121_XDSR LC O"
#property indicator_type9 DRAW_COLOR_LINE
#property indicator_color9 clrGreen, clrRed
#property indicator_width9 1
//
// High ...
#define lcHighBufferIndex 14
#define lcHighBufferPlotIndex 9
double lcHighBuffer[];
//
#property indicator_label10 "X121_XDSR LC H"
#property indicator_type10 DRAW_LINE
#property indicator_color10 clrAqua
#property indicator_width10 1
//
// Close ...
//
#define lcCloseBufferIndex 15
#define lcCloseBufferPlotIndex 10
double lcCloseBuffer[];
//
#define lcCloseColorBufferIndex 16
double lcCloseColorBuffer[];
//
#property indicator_label11 "X121_XDSR LC C"
#property indicator_type11 DRAW_COLOR_LINE
#property indicator_color11 clrGreen, clrRed
#property indicator_width11 1
//
// Low ...
#define lcLowBufferIndex 17
#define lcLowBufferPlotIndex 11
double lcLowBuffer[];
//
#property indicator_label12 "X121_XDSR LC L"
#property indicator_type12 DRAW_LINE
#property indicator_color12 clrMagenta
#property indicator_width12 1
//
// Hind ...
//
// Open ...
//
#define hcOpenBufferIndex 18
#define hcOpenBufferPlotIndex 12
double hcOpenBuffer[];
//
#define hcOpenColorBufferIndex 19
double hcOpenColorBuffer[];
//
#property indicator_label13 "X121_XDSR HC O"
#property indicator_type13 DRAW_COLOR_LINE
#property indicator_color13 clrGreen, clrRed
#property indicator_width13 1
//
// High ...
#define hcHighBufferIndex 20
#define hcHighBufferPlotIndex 13
double hcHighBuffer[];
//
#property indicator_label14 "X121_XDSR HC H"
#property indicator_type14 DRAW_LINE
#property indicator_color14 clrAqua
#property indicator_width14 1
//
// Close ...
//
#define hcCloseBufferIndex 21
#define hcCloseBufferPlotIndex 14
double hcCloseBuffer[];
//
#define hcCloseColorBufferIndex 22
double hcCloseColorBuffer[];
//
#property indicator_label15 "X121_XDSR HC C"
#property indicator_type15 DRAW_COLOR_LINE
#property indicator_color15 clrGreen, clrRed
#property indicator_width15 1
//
// Low ...
#define hcLowBufferIndex 23
#define hcLowBufferPlotIndex 15
double hcLowBuffer[];
//
#property indicator_label16 "X121_XDSR HC L"
#property indicator_type16 DRAW_LINE
#property indicator_color16 clrMagenta
#property indicator_width16 1
//
// VARIABLES ...
//
// Cycles Definitions ...
XMarketCycle sc;
XMarketCycle mc;
XMarketCycle lc;
XMarketCycle hc;
//
// EVENT Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
logTag = ShortName;
//
// Define Index Buffers ...
DefineBuffers();
//
// Set Indicator ShortName ...
SetIndicatorName();
//
// Initial Market Cycles ...
if (!InitMarketCycles())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// 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(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
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);
//
// this counts Available Bars ...
int limit;
//
limit = (prev_calculated > rates_total || prev_calculated <= 0)
? rates_total - 1
: (rates_total - prev_calculated);
//
// Main Loop ...
for (int i = limit; i >= 0 && !IsStopped(); i--)
{
//
// Calculate Buffers ...
CalculateBuffer(i);
}
//
return rates_total;
}
//
// CUSTOM Functions ...
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
// Short ...
IsValidCycle(
scMode,
scPeriod)
//
&&
//
// Medium ...
IsValidCycle(
mcMode,
mcPeriod)
//
&&
//
// Long ...
IsValidCycle(
lcMode,
lcPeriod)
//
&&
//
// Hind ...
IsValidCycle(
hcMode,
hcPeriod)
//
;
//
return result;
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// Short ...
//
// High ...
//
ArraySetAsSeries(scHighBuffer, true);
SetIndexBuffer(scHighBufferIndex, scHighBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(scHighBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(scHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(scHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Low ...
//
ArraySetAsSeries(scLowBuffer, true);
SetIndexBuffer(scLowBufferIndex, scLowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(scLowBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(scLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(scLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Open ...
//
ArraySetAsSeries(scOpenBuffer, true);
SetIndexBuffer(scOpenBufferIndex, scOpenBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(scOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(scOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(scOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(scOpenColorBuffer, true);
SetIndexBuffer(scOpenColorBufferIndex, scOpenColorBuffer, INDICATOR_COLOR_INDEX);
//
// Close ...
ArraySetAsSeries(scCloseBuffer, true);
SetIndexBuffer(scCloseBufferIndex, scCloseBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(scCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(scCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(scCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(scCloseColorBuffer, true);
SetIndexBuffer(scCloseColorBufferIndex, scCloseColorBuffer, INDICATOR_COLOR_INDEX);
//
// Medium ...
//
// High ...
//
ArraySetAsSeries(mcHighBuffer, true);
SetIndexBuffer(mcHighBufferIndex, mcHighBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(mcHighBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(mcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(mcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Low ...
//
ArraySetAsSeries(mcLowBuffer, true);
SetIndexBuffer(mcLowBufferIndex, mcLowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(mcLowBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(mcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(mcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Open ...
//
ArraySetAsSeries(mcOpenBuffer, true);
SetIndexBuffer(mcOpenBufferIndex, mcOpenBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(mcOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(mcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(mcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(mcOpenColorBuffer, true);
SetIndexBuffer(mcOpenColorBufferIndex, mcOpenColorBuffer, INDICATOR_COLOR_INDEX);
//
// Close ...
ArraySetAsSeries(mcCloseBuffer, true);
SetIndexBuffer(mcCloseBufferIndex, mcCloseBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(mcCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(mcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(mcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(mcCloseColorBuffer, true);
SetIndexBuffer(mcCloseColorBufferIndex, mcCloseColorBuffer, INDICATOR_COLOR_INDEX);
//
// Long ...
//
// High ...
//
ArraySetAsSeries(lcHighBuffer, true);
SetIndexBuffer(lcHighBufferIndex, lcHighBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(lcHighBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(lcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(lcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Low ...
//
ArraySetAsSeries(lcLowBuffer, true);
SetIndexBuffer(lcLowBufferIndex, lcLowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(lcLowBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(lcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(lcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Open ...
//
ArraySetAsSeries(lcOpenBuffer, true);
SetIndexBuffer(lcOpenBufferIndex, lcOpenBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(lcOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(lcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(lcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(lcOpenColorBuffer, true);
SetIndexBuffer(lcOpenColorBufferIndex, lcOpenColorBuffer, INDICATOR_COLOR_INDEX);
//
// Close ...
ArraySetAsSeries(lcCloseBuffer, true);
SetIndexBuffer(lcCloseBufferIndex, lcCloseBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(lcCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(lcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(lcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(lcCloseColorBuffer, true);
SetIndexBuffer(lcCloseColorBufferIndex, lcCloseColorBuffer, INDICATOR_COLOR_INDEX);
//
// Hind ...
//
// High ...
//
ArraySetAsSeries(hcHighBuffer, true);
SetIndexBuffer(hcHighBufferIndex, hcHighBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(hcHighBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(hcHighBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(hcHighBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Low ...
//
ArraySetAsSeries(hcLowBuffer, true);
SetIndexBuffer(hcLowBufferIndex, hcLowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(hcLowBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(hcLowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(hcLowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Open ...
//
ArraySetAsSeries(hcOpenBuffer, true);
SetIndexBuffer(hcOpenBufferIndex, hcOpenBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(hcOpenBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(hcOpenBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(hcOpenBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(hcOpenColorBuffer, true);
SetIndexBuffer(hcOpenColorBufferIndex, hcOpenColorBuffer, INDICATOR_COLOR_INDEX);
//
// Close ...
ArraySetAsSeries(hcCloseBuffer, true);
SetIndexBuffer(hcCloseBufferIndex, hcCloseBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(hcCloseBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(hcCloseBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(hcCloseBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
ArraySetAsSeries(hcCloseColorBuffer, true);
SetIndexBuffer(hcCloseColorBufferIndex, hcCloseColorBuffer, INDICATOR_COLOR_INDEX);
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
void CalculateBuffer(const int barIndex)
{
//
// First Update Market Cycles ...
UpdateMarketCycles(barIndex);
//
double bullishColorIDX = 0;
double bearishColorIDX = 1;
//
// Short ...
int scBarIndex = sc.GetBarIndex(barIndex);
XOHCL scBar1 = sc.GetBar(scBarIndex + 1);
//
bool isSCBar1Bullish = scBar1.open < scBar1.close;
//
scOpenBuffer[barIndex] = scBar1.open;
scHighBuffer[barIndex] = scBar1.high;
scCloseBuffer[barIndex] = scBar1.close;
scLowBuffer[barIndex] = scBar1.low;
//
scOpenColorBuffer[barIndex] =
isSCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
//
scCloseColorBuffer[barIndex] =
isSCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
//
// Medium ...
int mcBarIndex = mc.GetBarIndex(barIndex);
XOHCL mcBar1 = mc.GetBar(mcBarIndex + 1);
//
bool isMCBar1Bullish = mcBar1.open < mcBar1.close;
//
mcOpenBuffer[barIndex] = mcBar1.open;
mcHighBuffer[barIndex] = mcBar1.high;
mcCloseBuffer[barIndex] = mcBar1.close;
mcLowBuffer[barIndex] = mcBar1.low;
//
mcOpenColorBuffer[barIndex] =
isMCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
//
mcCloseColorBuffer[barIndex] =
isMCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
//
// Long ...
int lcBarIndex = lc.GetBarIndex(barIndex);
XOHCL lcBar1 = lc.GetBar(lcBarIndex + 1);
//
bool isLCBar1Bullish = lcBar1.open < lcBar1.close;
//
lcOpenBuffer[barIndex] = lcBar1.open;
lcHighBuffer[barIndex] = lcBar1.high;
lcCloseBuffer[barIndex] = lcBar1.close;
lcLowBuffer[barIndex] = lcBar1.low;
//
lcOpenColorBuffer[barIndex] =
isLCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
//
lcCloseColorBuffer[barIndex] =
isLCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
//
// Hind ...
int hcBarIndex = hc.GetBarIndex(barIndex);
XOHCL hcBar1 = hc.GetBar(hcBarIndex + 1);
//
bool isHCBar1Bullish = hcBar1.open < hcBar1.close;
//
hcOpenBuffer[barIndex] = hcBar1.open;
hcHighBuffer[barIndex] = hcBar1.high;
hcCloseBuffer[barIndex] = hcBar1.close;
hcLowBuffer[barIndex] = hcBar1.low;
//
hcOpenColorBuffer[barIndex] =
isHCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
//
hcCloseColorBuffer[barIndex] =
isHCBar1Bullish
? bullishColorIDX
: bearishColorIDX;
}
//
// TOOLS ...
//
// Initial Market Cycles ...
bool InitMarketCycles()
{
//
bool result = false;
//
// Short ...
sc.method = scMode;
sc.period = scPeriod;
result = sc.Init(
_Symbol,
_Period,
X_MARKET_CYCLE_SHORT);
if (!result)
{
return result;
}
//
// Medium ...
mc.method = mcMode;
mc.period = mcPeriod;
result = mc.Init(
_Symbol,
_Period,
X_MARKET_CYCLE_MEDIUM);
if (!result)
{
return result;
}
//
// Long ...
lc.method = lcMode;
lc.period = lcPeriod;
result = lc.Init(
_Symbol,
_Period,
X_MARKET_CYCLE_LONG);
if (!result)
{
return result;
}
//
// Hind ...
hc.method = hcMode;
hc.period = hcPeriod;
result = hc.Init(
_Symbol,
_Period,
X_MARKET_CYCLE_HIND);
if (!result)
{
return result;
}
//
return result;
}
//
// Update Market Cycles ...
bool UpdateMarketCycles(int barIndex)
{
//
bool result = false;
//
// Short ...
result = sc.Update(barIndex);
if (!result)
{
return result;
}
//
// Medium ...
result = mc.Update(barIndex);
if (!result)
{
return result;
}
//
// Long ...
result = lc.Update(barIndex);
if (!result)
{
return result;
}
//
// Hind ...
result = hc.Update(barIndex);
if (!result)
{
return result;
}
//
return result;
}
@@ -0,0 +1,836 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121_XICH
// Description: Ichimoku Kinko Hyo ...
//
//
// 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_XICH Indicator"
#property strict
//
// START Constants ...
//
//
// Indicator Short Name ...
#define ShortName "X121_XICH"
//
// Ichimoku Golden Numbers ...
enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS
{
X_ICH_BASE = 9,
X_ICH_GOLDEN = 17,
X_ICH_CYCLE = 26,
X_ICH_PERIOD = 35,
X_ICH_STAR = 45,
X_ICH_MED = 52,
X_ICH_LONG = 63,
X_ICH_FULL = 72
};
//
// Ichimoku Lines Calculator Mode ...
enum ENUM_X_ICHIMOKU_CALCULATION_MODE
{
//
X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low
X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close
};
//
// END Constants ...
//
//
// START Inputs ...
//
//
// ICHIMOKU Kinko Hyo ...
//
// TENKANSEN ...
input group "Tenkan Sen";
input int tenkanSenLength = 9; // Length
input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode
//
// KIJUNSEN ...
input group "Kijun Sen";
input int kijunSenLength = 26; // Length
input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode
//
// SENKOUSPANB ...
input group "Senkou Span B";
input int senkouSpanBLength = 52; // Length
input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode
//
// CHIKOUSPAN ...
input group "Chikou Span";
input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type
//
input group "Presentation";
input bool showTenkanSen = true; // Show Tenkan Sen
input bool showKijunSen = true; // Show Kijun Sen
input bool showKijunSenPlus = false; // Show Kijun Sen +
input bool showKijunSenNegative = false; // Show Kijun Sen -
input bool showChikouSpan = true; // Show Chikou Span
input bool showSenkouSpanA = true; // Show Senkou Span A
input bool showSenkouSpanB = true; // Show Senkou Span B
input bool showKumo = true; // Show Kumo
input bool shiftKumo = true; // Shift Kumo to Future
//
// END Inputs ...
//
//
// START Includes and Imports ...
//
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Includes and Imports ...
//
//
// START Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 15
#property indicator_plots 8
//
// PLOTTED Buffers ...
//
// ICHIMOKU ...
//
// TENKANSEN ...
//
#define tenkanSenBufferIndex 0
double tenkanSenBuffer[];
//
#property indicator_label1 "X121_XICH TK"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBrown
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//
// KIJUNSEN ...
//
#define kijunSenBufferIndex 1
double kijunSenBuffer[];
//
#property indicator_label2 "X121_XICH KJ"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDodgerBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//
#define kijunSenPlusBufferIndex 2
double kijunSenPlusBuffer[];
//
#property indicator_label3 "X121_XICH KJ+"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrMediumTurquoise
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
#define kijunSenNegativeBufferIndex 3
double kijunSenNegativeBuffer[];
//
#property indicator_label4 "X121_XICH KJ-"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrDarkSeaGreen
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// CHIKOUSPAN ...
//
#define chikouSpanBufferIndex 4
double chikouSpanBuffer[];
//
#property indicator_label5 "X121_XICH CS"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrDarkGreen
#property indicator_style5 STYLE_SOLID
#property indicator_width5 1
//
#define senkouABufferIndex 5
double senkouABuffer[];
//
#property indicator_label6 "X121_XICH SSA"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrLightGray
#property indicator_style6 STYLE_DASHDOTDOT
#property indicator_width6 1
//
#define senkouBBufferIndex 6
double senkouBBuffer[];
//
#property indicator_label7 "X121_XICH SSB"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrLightGray
#property indicator_style7 STYLE_DASHDOTDOT
#property indicator_width7 1
//
// KUMO ...
//
// SENKOUSPANA ...
//
#define senkouSpanABufferIndex 7
double senkouSpanABuffer[];
//
// SENKOUSPANB ...
//
#define senkouSpanBBufferIndex 8
double senkouSpanBBuffer[];
//
// KUMOCLOUD ...
//
#define kumoBufferIndex 7
//
#property indicator_label8 "X121_XICH Kumo"
#property indicator_type8 DRAW_FILLING
#property indicator_color8 clrAqua, clrMagenta
#property indicator_style8 STYLE_SOLID
#property indicator_width8 1
//
// DATA Buffers ...
//
#define dTenkanBufferIndex 9
double dTenkanBuffer[];
//
#define dKijunBufferIndex 10
double dKijunBuffer[];
//
#define dChikouBufferIndex 11
double dChikouBuffer[];
//
#define dSSABufferIndex 12
double dSSABuffer[];
//
#define dSSBBufferIndex 13
double dSSBBuffer[];
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
int maxLength;
int mHandler;
//
ENUM_SERIESMODE mTenkanSenTopMode = NULL;
ENUM_SERIESMODE mTenkanSenBottomMode = NULL;
//
ENUM_SERIESMODE mKijunSenTopMode = NULL;
ENUM_SERIESMODE mKijunSenBottomMode = NULL;
//
ENUM_SERIESMODE mSenkouSpanBTopMode = NULL;
ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
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 length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Init Handler ...
mHandler = iIchimoku(
_Symbol,
_Period,
tenkanSenLength,
kijunSenLength,
senkouSpanBLength);
if (mHandler == INVALID_HANDLE)
{
return INIT_FAILED;
}
//
// 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
//
IndicatorRelease(mHandler);
}
//
// Calculating what we want ...
int OnCalculate(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
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);
//
// this counts Available Bars ...
int limit;
//
// Check Calculated Bars ...
int ichCalculatedBars = BarsCalculated(mHandler);
if (ichCalculatedBars < maxLength)
{
return prev_calculated;
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer);
int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer);
int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer);
int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer);
int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer);
if (
copiedSSAs < 0 ||
copiedSSBs < 0 ||
copiedKijuns < 0 ||
copiedTenkans < 0 ||
copiedChikous < 0)
{
return prev_calculated;
}
//
// 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 =
//
(tenkanSenLength > 2 &&
kijunSenLength > tenkanSenLength &&
senkouSpanBLength > kijunSenLength)
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
// Ichimoku ...
result = MathMax(result, tenkanSenLength);
result = MathMax(result, kijunSenLength);
result = MathMax(result, senkouSpanBLength);
//
return result;
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// ICHIMOKU ...
//
// TENKANSEN ...
//
ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(tenkanSenBuffer, true);
SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType);
//
// KIJUNSEN ...
//
ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(kijunSenBuffer, true);
SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType);
//
// KIJUNSEN Plus ...
//
ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(kijunSenPlusBuffer, true);
SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType);
//
// KIJUNSEN Negative ...
//
ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(kijunSenNegativeBuffer, true);
SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType);
//
// CHIKOUSPAN ...
//
ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(chikouSpanBuffer, true);
SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType);
//
// SENKOUSPAN A and B ...
int shiftSize = shiftKumo ? kijunSenLength : 0;
//
// SENKOUSPANA ...
ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(senkouABuffer, true);
SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA);
PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType);
//
// SENKOUSPANB ...
ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(senkouBBuffer, true);
SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB);
PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType);
//
// KUMO ...
//
// SENKOUSPANA ...
ArraySetAsSeries(senkouSpanABuffer, true);
SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength);
//
// SENKOUSPANB ...
ArraySetAsSeries(senkouSpanBBuffer, true);
SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength);
//
// KUMO ...
//
ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE;
//
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType);
//
// DATA Buffers ...
//
// D Tenkan ...
ArraySetAsSeries(dTenkanBuffer, true);
SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS);
//
// D Kijun ...
ArraySetAsSeries(dKijunBuffer, true);
SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS);
//
// D Chikou ...
ArraySetAsSeries(dChikouBuffer, true);
SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS);
//
// D SSA ...
ArraySetAsSeries(dSSABuffer, true);
SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS);
//
// D SSB ...
ArraySetAsSeries(dSSBBuffer, true);
SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS);
}
//
// 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
)
{
//
// ICHIMOKU ...
//
double topValue;
double bottomValue;
//
// TENKANSEN ...
//
// Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ...
if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL)
{
//
switch (tenkanSenMode)
{
//
case X_XICH_HH_LL_MODE:
//
mTenkanSenTopMode = MODE_HIGH;
mTenkanSenBottomMode = MODE_LOW;
break;
//
case X_XICH_HO_LC_MODE:
//
mTenkanSenTopMode = MODE_OPEN;
mTenkanSenBottomMode = MODE_CLOSE;
break;
}
}
//
// Calculate Top ...
topValue = GetHighestHigh(
_Symbol,
_Period,
mTenkanSenTopMode,
tenkanSenLength,
bar_index);
//
// Calculate Bottom ...
bottomValue = GetLowestLow(
_Symbol,
_Period,
mTenkanSenBottomMode,
tenkanSenLength,
bar_index);
//
double tenkanSenValue = (topValue + bottomValue) / 2;
tenkanSenBuffer[bar_index] = tenkanSenValue;
//
// KIJUNSEN ...
//
// Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ...
if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL)
{
//
switch (kijunSenMode)
{
//
case X_XICH_HH_LL_MODE:
//
mKijunSenTopMode = MODE_HIGH;
mKijunSenBottomMode = MODE_LOW;
break;
//
case X_XICH_HO_LC_MODE:
//
mKijunSenTopMode = MODE_OPEN;
mKijunSenBottomMode = MODE_CLOSE;
break;
}
}
//
// Calculate Top ...
topValue = GetHighestHigh(
_Symbol,
_Period,
mKijunSenTopMode,
kijunSenLength,
bar_index);
//
// Calculate Bottom ...
bottomValue = GetLowestLow(
_Symbol,
_Period,
mKijunSenBottomMode,
kijunSenLength,
bar_index);
//
double kijunSenValue = (topValue + bottomValue) / 2;
kijunSenBuffer[bar_index] = kijunSenValue;
//
kijunSenPlusBuffer[bar_index] = kijunSenValue;
kijunSenNegativeBuffer[bar_index] = kijunSenValue;
//
// CHIKOUSPAN ...
double chikouSpanValue = GetAppliedPrice(
bar_index,
chikuoSpanAppliedTo);
chikouSpanBuffer[bar_index] = chikouSpanValue;
//
// KUMO ...
//
// SENKOUSPANA ...
double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2;
senkouABuffer[bar_index] = senkouSpanAValue;
senkouSpanABuffer[bar_index] = senkouSpanAValue;
//
// SENKOUSPANB ...
//
// Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ...
if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL)
{
//
switch (senkouSpanBMode)
{
//
case X_XICH_HH_LL_MODE:
//
mSenkouSpanBTopMode = MODE_HIGH;
mSenkouSpanBBottomMode = MODE_LOW;
break;
//
case X_XICH_HO_LC_MODE:
//
mSenkouSpanBTopMode = MODE_OPEN;
mSenkouSpanBBottomMode = MODE_CLOSE;
break;
}
}
//
// Calculate Top ...
topValue = GetHighestHigh(
_Symbol,
_Period,
mSenkouSpanBTopMode,
senkouSpanBLength,
bar_index);
//
// Calculate Bottom ...
bottomValue = GetLowestLow(
_Symbol,
_Period,
mSenkouSpanBBottomMode,
senkouSpanBLength,
bar_index);
//
double senkouSpanBValue = (topValue + bottomValue) / 2;
senkouBBuffer[bar_index] = senkouSpanBValue;
senkouSpanBBuffer[bar_index] = senkouSpanBValue;
}
//
// END Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,603 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Seriallize Library
// ---------------------------------------
// Name: XSeriallizer
// Description: provides Seriallizing EA abilities ...
//
//
// 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.models.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
//
string XProviderToken = "PRV";
string XSupportToken = "SP";
string XSLTrailToken = "SLT";
string XPeriodToken = "PR";
//
string XConfigToken = "XPV";
string XItemSeparator = "|";
string XItemContentSeparator = ",";
//
string XFirstGenToken = "0";
//
// PERIOD ...
//
// Detect a Comment has period or not ...
bool HasPeriod(string comment)
{
//
bool result = false;
//
if (StringLen(comment) == 0)
{
return result;
}
//
int tokenPos = StringFind(
comment,
XPeriodToken);
result = tokenPos >= 0;
//
return result;
}
//
// Extract Period String ...
string ExtractPeriodString(string comment)
{
//
string result = "";
//
bool hasPeriod = HasPeriod(comment);
if (!hasPeriod)
{
return result;
}
//
result = ExtractString(
comment,
XPeriodToken + "(",
")");
//
return result;
}
//
// Extract Time Frame From Comment ...
ENUM_TIMEFRAMES ExtractPeriod(string comment)
{
//
ENUM_TIMEFRAMES result = NULL;
//
if (StringLen(comment) <= 0)
{
return result;
}
//
string periodStr = ExtractPeriodString(comment);
if (StringLen(periodStr) <= 0)
{
return result;
}
//
result = ToPeriod(periodStr);
//
return result;
}
//
// PROVIDER ...
//
// Extract a Provider name if exists from a Comment ...
string ExtractProvider(string comment)
{
//
string result = "";
if (StringLen(comment) <= 0)
{
return result;
}
//
result = ExtractString(
comment,
XProviderToken + "(",
")");
//
return result;
}
//
// Generate Provider String for Using in Positions Comment ...
// NOTE: if there is more than One Provider, it takes first
// provider as main and the others used to increase volume ...
string GenerateProvidersString(XSignal &signal)
{
//
string result = "";
//
int providersCount = ArraySize(signal.providers);
if (providersCount <= 0)
{
return result;
}
//
result = XProviderToken + "(" + signal.providers[0] + ")";
//
return result;
}
//
// SLTRAIL ...
//
string GenerateSLTrailComment(int level)
{
//
string result = "";
//
if (level <= 0)
{
return result;
}
//
result = XSLTrailToken + "(" + ToString(level) + ")";
//
return result;
}
//
int ExtractSLTrailLevel(string comment)
{
//
int result = 0;
//
if (StringLen(comment) == 0)
{
return result;
}
//
string levelStr = ExtractString(
comment,
XSLTrailToken + "(",
")");
if (StringLen(levelStr) == 0)
{
return result;
}
//
result = (int)levelStr;
//
return result;
}
//
string PrepareSLTrailComment(
const string comment // Original Position Comment ...
)
{
//
string result = "";
//
if (StringLen(comment) == 0)
{
return result;
}
//
int level = 0;
result = comment;
//
// Check Comment Contains SL Trailing or not ...
int lastTrailLevel = ExtractSLTrailLevel(comment);
if (lastTrailLevel <= 0)
{
level++;
}
else
{
//
level = lastTrailLevel + 1;
string lastLevelStr = GenerateSLTrailComment(lastTrailLevel);
StringReplace(
result,
lastLevelStr,
"");
}
//
// Generate level Comment ...
string levelStr = GenerateSLTrailComment(level);
result += levelStr;
//
return result;
}
//
// SUPPORT ...
//
// Generate Specific Position's Support Comment
// index is number of Supports ...
string GenerateSupportSignalComment(
ulong ticket, // Position/Order Ticket
int index // Support Index ...
)
{
//
string result = "";
//
result = XSupportToken + "(" + (string)ticket + "," + ToString(index) + ")";
//
return result;
}
//
// Extract Support Parameters String from specified Comment ...
string ExtractSupportParam(string comment)
{
//
string result = "";
if (StringLen(comment) <= 0)
{
return result;
}
//
result = ExtractString(
comment,
XSupportToken + "(",
")");
//
return result;
}
//
// Extract Support Info as String array for Specific Comment ...
bool ExtractSupportParams(
string comment, // Specified Comment ...
string &params[] // Hold Result ...
)
{
//
bool result = false;
//
string supParam = ExtractSupportParam(comment);
if (StringLen(supParam) == 0)
{
return result;
}
//
SplitContent(
params,
supParam);
int paramsCount = ArraySize(params);
//
result = paramsCount == 2;
//
return result;
}
//
// Extract Support Parent Ticket ...
ulong ExtractParentTicket(string comment)
{
//
ulong result = 0;
//
string params[];
bool isSupport = ExtractSupportParams(
comment,
params);
if (!isSupport)
{
return result;
}
//
result = (ulong)params[0];
//
return result;
}
//
// Extract Support Index ...
int ExtractSupportIndex(string comment)
{
//
int result = -1;
//
string params[];
bool isSupport = ExtractSupportParams(
comment,
params);
if (!isSupport)
{
return result;
}
//
result = (int)params[1];
//
return result;
}
//
// START XEQM Support ...
//
//
string XEQMSupportToken = "XEQM";
//
// Generate String Tag for EQM Support Signals ...
string GenerateXEQMSupportComment()
{
//
string result = XEQMSupportToken;
//
return result;
}
//
// Check a Comment belongs to a EQM Support or not ...
bool IsEQMSupport(string comment)
{
//
bool result = false;
//
if (StringLen(comment) <= 0)
{
return result;
}
//
int tokenPosition = StringFind(
comment,
XEQMSupportToken);
result = tokenPosition >= 0;
//
return result;
}
//
// Select EQM Support Orders ...
int GetEQMSupportOrders(
XOrder &supports[], // Hold Result ...
XOrder &orders[], // List of All Orders ...
ENUM_TIMEFRAMES period = NULL // Specified Period ...
)
{
//
int result = 0;
//
// Cleanup Array ...
Clean(supports);
//
// Count Orders ...
int ordersCount = ArraySize(orders);
if (ordersCount <= 0)
{
return result;
}
//
// Loop through Orders ...
for (int i = 0; i < ordersCount; i++)
{
//
// Select Indexed Order ...
XOrder iOrder = orders[i];
//
// Check Order is Support or not ...
bool isSupport = IsEQMSupport(iOrder.comment);
if (!isSupport)
{
continue;
}
//
// Check Order is not Triggered ...
if (iOrder.state != ORDER_STATE_PLACED)
{
continue;
}
//
// Check Period ...
if (period != NULL && iOrder.period != period)
{
continue;
}
//
// we now sure this order is EQM Support ...
Add(
iOrder,
supports);
}
//
// Count Result ...
result = ArraySize(supports);
//
return result;
}
//
// Select EQM Support Positions ...
int GetEQMSupportPositions(
XPosition &supports[], // Hold Result ...
XPosition &positions[], // List of All Positions ...
ENUM_TIMEFRAMES period = NULL // Specified Period ...
)
{
//
int result = 0;
//
// Cleanup Array ...
Clean(supports);
//
// Count Positions ...
int positionsCount = ArraySize(positions);
if (positionsCount <= 0)
{
return result;
}
//
// Loop through Positions ...
for (int i = 0; i < positionsCount; i++)
{
//
// Select Indexed Position ...
XPosition iPosition = positions[i];
//
// Check Position is Support or not ...
bool isSupport = IsEQMSupport(iPosition.comment);
if (!isSupport)
{
continue;
}
//
// Check Period ...
if (period != NULL && iPosition.period != period)
{
continue;
}
//
// we now sure this order is EQM Support ...
Add(
iPosition,
supports);
}
//
// Count Result ...
result = ArraySize(supports);
//
return result;
}
//
// END XEQM Support ...
//
//
// START FirstGen ...
//
//
string GenerateFirstGenIdentifier(const string signaller)
{
//
string result = "";
//
if (StringLen(signaller) <= 0)
{
return result;
}
//
return signaller + XFirstGenToken;
//
return result;
}
//
bool IsFirstGenOf(
const string signaller, // Specified Signaller
const string comment // Comment
)
{
//
bool result = false;
//
string id = GenerateFirstGenIdentifier(signaller);
//
int idPos = StringFind(
comment,
id
);
result = idPos >= 0;
//
return result;
}
//
// END FirstGen ...
//
@@ -0,0 +1,294 @@
//+------------------------------------------------------------------+
//| ZigZag.mq5 |
//| Copyright 2000-2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 1
//--- plot ZigZag
#property indicator_label1 "ZigZag"
#property indicator_type1 DRAW_SECTION
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int InpDepth =12; // Depth
input int InpDeviation=5; // Deviation
input int InpBackstep =3; // Back Step
//--- indicator buffers
double ZigZagBuffer[]; // main buffer
double HighMapBuffer[]; // ZigZag high extremes (peaks)
double LowMapBuffer[]; // ZigZag low extremes (bottoms)
int ExtRecalc=3; // number of last extremes for recalculation
enum EnSearchMode
{
Extremum=0, // searching for the first extremum
Peak=1, // searching for the next ZigZag peak
Bottom=-1 // searching for the next ZigZag bottom
};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ZigZagBuffer,INDICATOR_DATA);
SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
//--- set short name and digits
string short_name=StringFormat("ZigZag(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
PlotIndexSetString(0,PLOT_LABEL,short_name);
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set an empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
}
//+------------------------------------------------------------------+
//| ZigZag calculation |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total<100)
return(0);
//---
int i=0;
int start=0,extreme_counter=0,extreme_search=Extremum;
int shift=0,back=0,last_high_pos=0,last_low_pos=0;
double val=0,res=0;
double curlow=0,curhigh=0,last_high=0,last_low=0;
//--- initializing
if(prev_calculated==0)
{
ArrayInitialize(ZigZagBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
start=InpDepth;
}
//--- ZigZag was already calculated before
if(prev_calculated>0)
{
i=rates_total-1;
//--- searching for the third extremum from the last uncompleted bar
while(extreme_counter<ExtRecalc && i>rates_total-100)
{
res=ZigZagBuffer[i];
if(res!=0.0)
extreme_counter++;
i--;
}
i++;
start=i;
//--- what type of exremum we search for
if(LowMapBuffer[i]!=0.0)
{
curlow=LowMapBuffer[i];
extreme_search=Peak;
}
else
{
curhigh=HighMapBuffer[i];
extreme_search=Bottom;
}
//--- clear indicator values
for(i=start+1; i<rates_total && !IsStopped(); i++)
{
ZigZagBuffer[i] =0.0;
LowMapBuffer[i] =0.0;
HighMapBuffer[i]=0.0;
}
}
//--- searching for high and low extremes
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
//--- low
val=low[Lowest(low,InpDepth,shift)];
if(val==last_low)
val=0.0;
else
{
last_low=val;
if((low[shift]-val)>InpDeviation*_Point)
val=0.0;
else
{
for(back=1; back<=InpBackstep; back++)
{
res=LowMapBuffer[shift-back];
if((res!=0) && (res>val))
LowMapBuffer[shift-back]=0.0;
}
}
}
if(low[shift]==val)
LowMapBuffer[shift]=val;
else
LowMapBuffer[shift]=0.0;
//--- high
val=high[Highest(high,InpDepth,shift)];
if(val==last_high)
val=0.0;
else
{
last_high=val;
if((val-high[shift])>InpDeviation*_Point)
val=0.0;
else
{
for(back=1; back<=InpBackstep; back++)
{
res=HighMapBuffer[shift-back];
if((res!=0) && (res<val))
HighMapBuffer[shift-back]=0.0;
}
}
}
if(high[shift]==val)
HighMapBuffer[shift]=val;
else
HighMapBuffer[shift]=0.0;
}
//--- set last values
if(extreme_search==0) // undefined values
{
last_low=0.0;
last_high=0.0;
}
else
{
last_low=curlow;
last_high=curhigh;
}
//--- final selection of extreme points for ZigZag
for(shift=start; shift<rates_total && !IsStopped(); shift++)
{
res=0.0;
switch(extreme_search)
{
case Extremum:
if(last_low==0.0 && last_high==0.0)
{
if(HighMapBuffer[shift]!=0)
{
last_high=high[shift];
last_high_pos=shift;
extreme_search=Bottom;
ZigZagBuffer[shift]=last_high;
res=1;
}
if(LowMapBuffer[shift]!=0.0)
{
last_low=low[shift];
last_low_pos=shift;
extreme_search=Peak;
ZigZagBuffer[shift]=last_low;
res=1;
}
}
break;
case Peak:
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low && HighMapBuffer[shift]==0.0)
{
ZigZagBuffer[last_low_pos]=0.0;
last_low_pos=shift;
last_low=LowMapBuffer[shift];
ZigZagBuffer[shift]=last_low;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
last_high=HighMapBuffer[shift];
last_high_pos=shift;
ZigZagBuffer[shift]=last_high;
extreme_search=Bottom;
res=1;
}
break;
case Bottom:
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>last_high && LowMapBuffer[shift]==0.0)
{
ZigZagBuffer[last_high_pos]=0.0;
last_high_pos=shift;
last_high=HighMapBuffer[shift];
ZigZagBuffer[shift]=last_high;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
last_low=LowMapBuffer[shift];
last_low_pos=shift;
ZigZagBuffer[shift]=last_low;
extreme_search=Peak;
}
break;
default:
return(rates_total);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Search for the index of the highest bar |
//+------------------------------------------------------------------+
int Highest(const double &array[],const int depth,const int start)
{
if(start<0)
return(0);
double max=array[start];
int index=start;
//--- start searching
for(int i=start-1; i>start-depth && i>=0; i--)
{
if(array[i]>max)
{
index=i;
max=array[i];
}
}
//--- return index of the highest bar
return(index);
}
//+------------------------------------------------------------------+
//| Search for the index of the lowest bar |
//+------------------------------------------------------------------+
int Lowest(const double &array[],const int depth,const int start)
{
if(start<0)
return(0);
double min=array[start];
int index=start;
//--- start searching
for(int i=start-1; i>start-depth && i>=0; i--)
{
if(array[i]<min)
{
index=i;
min=array[i];
}
}
//--- return index of the lowest bar
return(index);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,34 @@
void CommentLab(string CommentText)
{
//
string CommentLabel;
int CommentIndex = 0;
//
if (CommentText == "")
{
//
// delete all Comment texts
while (ObjectFind(StringConcatenate("CommentLabel", CommentIndex)) >= 0)
{
//
ObjectDelete(StringConcatenate("CommentLabel", CommentIndex));
CommentIndex++;
}
return;
}
//
while (ObjectFind(StringConcatenate("CommentLabel", CommentIndex)) >= 0)
{
CommentIndex++;
}
//
CommentLabel = StringConcatenate("CommentLabel", CommentIndex);
ObjectCreate(CommentLabel, OBJ_LABEL, 0, 0, 0);
ObjectSet(CommentLabel, OBJPROP_CORNER, 0);
ObjectSet(CommentLabel, OBJPROP_XDISTANCE, 5);
ObjectSet(CommentLabel, OBJPROP_YDISTANCE, 15 + (CommentIndex * 15));
ObjectSetText(CommentLabel, CommentText, 10, "Tahoma", Status_Color);
}
@@ -0,0 +1,102 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Models Library
// ---------------------------------------
// Name: XModels
// Description: provides all required models ...
//
//
// 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 Inputs ...
//
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// How To Calculate Static Volume ...
enum ENUM_STATIC_VOLUME_METHODS
{
//
// Based On Deposit ...
X_STATIC_VOLUME_BASED_ON_DEPOSIT,
//
// Based On Balance ...
X_STATIC_VOLUME_BASED_ON_BALANCE,
};
//
// START Model Definitions ...
//
//
// Select Positions Type ...
enum ENUM_X_POSITION_SELECT_METHODS
{
X_POSITION_SELECT_NONE, // None
X_POSITION_SELECT_MAX, // Max
X_POSITION_SELECT_MIN, // Min
X_POSITION_SELECT_ALL, // Min
};
//
// Available Guard Action ...
enum ENUM_X_GUARD_ACTIONS
{
X_GUARD_ACTION_NOTHING, // Nothing
X_GUARD_ACTION_HEDGE, // Hedge
X_GUARD_PARTIAL_CLOSE, // Partial Close
X_GUARD_ACTION_TRAIL_STOP, // Trail StopLoss
X_GUARD_ACTION_FORCE_CLOSE, // Force Close
X_GUARD_ACTION_ADD_SUPPORT_SIGNAL, // Add Support Signal
X_GUARD_ACTION_CANCEL_PENDING_ORDERS, // Cancel Pending Orders
};
//
// Model Guard Info ...
struct XGuard
{
string symbol;
string provider;
ENUM_TIMEFRAMES period;
ENUM_POSITION_TYPE type;
ENUM_X_GUARD_ACTIONS action;
//
double dblPayLoad;
string strPayload;
};
//
// EXTENSION Methods ...
//
// END Provided Functions ...
//
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,728 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XSAMPLE MQL5 Expert Advisor
// -------------------------------------------------
// Name: XSAMPLE
// Description: an Exper Advisor which used RSI and MA
// to Analyse Market ...
//
// 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 XSAMPLE"
#property strict
//
#define ShortName "XSAMPLE"
//
#include "../Libraries/x-saherelm.log.lib.mq5"
#include "../Libraries/x-saherelm.draw.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
//
#include "../Helpers/x-saherelm.x121.xmc.helper.mq5"
#include "../Helpers/x-saherelm.x121.xstr.helper.mq5"
#include "../Helpers/x-saherelm.x121.xche.helper.mq5"
#include "../Helpers/x-saherelm.x121.xosc.helper.mq5"
//
#include "../Classes/x-saherelm.x121.xmcycle.class.mq5"
//
// Inputs ...
long xSampleEAMagicNumber = 78692110; // Magic Number
int xSampleEASlippage = 10; // Slippgae
//
double xSampleEAVolume = 0.01;
//
// Vars ...
string xSampleEASymbol;
ENUM_TIMEFRAMES xSampleEAPeriod;
//
int maxBuys = 1;
int maxSells = 1;
int buyCount = 0;
int sellCount = 0;
//
double _tp = 0;
double _sl = 0;
double _entry = 0;
ENUM_POSITION_TYPE _type = NULL;
//
MqlTick xSampleEATick;
XSCTrade *xSampleEATrader;
// //
// // XCHE ...
// X121CHEInputs xSampleEACHEInputs;
// XSCX121CHEHelper xSampleEACHEHelper;
// //
// // XMC ...
// X121MCInputs xSampleEAMCInputs;
// XSCX121MCHelper xSampleEAMCHelper;
// //
// // XSTR ...
// X121STRInputs xSampleEASTRInputs;
// XSCX121STRHelper xSampleEASTRHelper;
// //
// // XOSC ...
// X121OSCInputs xSampleEAOSCInputs;
// XSCX121OSCHelper xSampleEAOSCHelper;
// //
// // XICH ...
// X121ICHInputs xSampleEAICHInputs;
// XSCX121ICHHelper xSampleEAICHHelper;
//
// X121MCycle ...
X121MCycleInputs xSampleEA121MCInputs;
XSC121Market xSampleEA121MC;
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
if (xSampleEASymbol == NULL || StringLen(xSampleEASymbol) <= 0)
{
xSampleEASymbol = _Symbol;
}
//
if (xSampleEAPeriod == NULL)
{
xSampleEAPeriod = _Period;
}
//
// Validate Inputs ...
if (!XSampleEAValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
logTag = ShortName;
drawPrefix = ShortName;
// //
// // XCHE ...
// //
// xSampleEACHEInputs.Default();
// if (!xSampleEACHEInputs.IsValid())
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// if (!xSampleEACHEHelper.Init(
// xSampleEASymbol,
// xSampleEAPeriod,
// xSampleEACHEInputs))
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// // XMC ...
// //
// xSampleEAMCInputs.Default();
// if (!xSampleEAMCInputs.IsValid())
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// if (!xSampleEAMCHelper.Init(
// xSampleEASymbol,
// xSampleEAPeriod,
// xSampleEAMCInputs))
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// // XSTR ...
// //
// xSampleEASTRInputs.Default();
// if (!xSampleEASTRInputs.IsValid())
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// if (!xSampleEASTRHelper.Init(
// xSampleEASymbol,
// xSampleEAPeriod,
// xSampleEASTRInputs))
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// // XOSC ...
// //
// xSampleEAOSCInputs.Default();
// if (!xSampleEAOSCInputs.IsValid())
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// if (!xSampleEAOSCHelper.Init(
// xSampleEASymbol,
// xSampleEAPeriod,
// xSampleEAOSCInputs))
// {
// return INIT_PARAMETERS_INCORRECT;
// }
//
// XICH ...
// //
// xSampleEAICHInputs.Default();
// if (!xSampleEAICHInputs.IsValid())
// {
// return INIT_PARAMETERS_INCORRECT;
// }
// //
// if (!xSampleEAICHHelper.Init(
// xSampleEASymbol,
// xSampleEAPeriod,
// xSampleEAICHInputs))
// {
// return INIT_PARAMETERS_INCORRECT;
// }
//
// X121Market Cycle ...
bool result = xSampleEA121MCInputs.Init(
xSampleEASymbol,
xSampleEAPeriod,
X_MARKET_CYCLE_SHORT,
PERIOD_H1,
X_PERIOD_MANUALLY //
);
//
// after Inputs Initialize Successfully we must prepare Styling for Draw ...
ApplyMCDrawStyles();
//
result = xSampleEA121MC.Init(
xSampleEA121MCInputs
//
);
if (!result)
{
return INIT_PARAMETERS_INCORRECT;
}
//
// Initialize XTrader ...
xSampleEATrader = new XSCTrade(
xSampleEASlippage,
xSampleEAMagicNumber);
//
// 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
//
// De Initialize XSampleEA Providers ...
delete xSampleEATrader;
}
//
// On Tick Handler ...
void OnTick()
{
//
if (!IsNewCandle(
xSampleEASymbol,
xSampleEAPeriod))
{
return;
}
//
// Reading Tick ...
if (!SymbolInfoTick(xSampleEASymbol, xSampleEATick))
{
return;
}
//
// Counting Currently Open Positions ...
buyCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_BUY);
sellCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_SELL);
//
// TestMC();
// TestCHE();
// TestSTR();
// TestOSC();
// TestICH();
//
// TestMCycle();
//
// Draw Market Cycle Bars On Chart ...
int offset = 0;
xSampleEA121MC.Draw(
ChartID(),
0,
offset
//
);
//
if (buyCount < maxBuys)
{
//
// Check For Buy Signals ...
}
//
if (sellCount < maxSells)
{
//
// Check for Sell Signals ...
}
}
//
// Custom Functions ...
//
// Validate Variables nd Inputs ...
bool XSampleEAValidateInputs()
{
//
bool result = false;
//
result =
//
xSampleEASlippage > 0 &&
xSampleEAMagicNumber > 0
//
;
//
return result;
}
//
// Tools ...
// //
// void TestCHE()
// {
// //
// double longExit1 = xSampleEACHEHelper.GetLongExit1(0);
// if (NotEmpty(longExit1))
// {
// Print("LE1: " + ToString(longExit1));
// }
// //
// double lEs[];
// int lEsCount = xSampleEACHEHelper.CopyLongExit1(
// 0,
// 2,
// lEs);
// if (lEsCount > 0)
// {
// //
// for (int i = 0; i < lEsCount; i++)
// {
// //
// double iVal = lEs[i];
// //
// if (NotEmpty(iVal))
// {
// //
// Print("LE " + ToString(i) + ": " + ToString(iVal));
// }
// }
// //
// Print(" ");
// }
// }
// //
// void TestMC()
// {
// //
// double fast = xSampleEAMCHelper.GetFast(0);
// if (NotEmpty(fast))
// {
// Print("Fast: " + ToString(fast));
// }
// //
// double slow = xSampleEAMCHelper.GetSlow(0);
// if (NotEmpty(slow))
// {
// Print("Slow: " + ToString(slow));
// }
// }
// //
// void TestSTR()
// {
// //
// double trend = xSampleEASTRHelper.GetTrend(0);
// if (NotEmpty(trend))
// {
// Print("Trend: " + ToString(trend));
// }
// //
// double state = xSampleEASTRHelper.GetState(0);
// if (NotEmpty(state))
// {
// Print("State: " + EnumToString(xSampleEASTRHelper.ToState(state)));
// }
// }
// //
// void TestOSC()
// {
// //
// double rsi = xSampleEAOSCHelper.GetRSI(0);
// if (NotEmpty(rsi))
// {
// Print("RSI: " + ToString(rsi));
// }
// //
// double cci = xSampleEAOSCHelper.GetCCI(0);
// if (NotEmpty(cci))
// {
// Print("CCI: " + ToString(cci));
// }
// }
// //
// void TestICH()
// {
// //
// double tenkanSen = xSampleEAICHHelper.GetTenkanSen(1);
// double tenkanSenLast = xSampleEAICHHelper.GetTenkanSen(2);
// //
// double kijunSen = xSampleEAICHHelper.GetKijunSen(1);
// double kijunSenLast = xSampleEAICHHelper.GetKijunSen(2);
// //
// double chikouSpan = xSampleEAICHHelper.GetChikouSpan(1);
// //
// double senkouSpanA = xSampleEAICHHelper.GetSenkouSpanA(1);
// double senkouSpanALast = xSampleEAICHHelper.GetSenkouSpanA(2);
// //
// double senkouSpanB = xSampleEAICHHelper.GetSenkouSpanB(1);
// double senkouSpanBLast = xSampleEAICHHelper.GetSenkouSpanB(2);
// //
// double futureSenkouSpanA = xSampleEAICHHelper.GetFutureSenkouSpanA(1);
// double futureSenkouSpanALast = xSampleEAICHHelper.GetFutureSenkouSpanA(2);
// //
// double futureSenkouSpanB = xSampleEAICHHelper.GetFutureSenkouSpanB(1);
// double futureSenkouSpanBLast = xSampleEAICHHelper.GetFutureSenkouSpanB(2);
// //
// bool isTenkanSenCrossedOverKijunSen =
// //
// tenkanSen > kijunSen &&
// tenkanSenLast <= kijunSenLast
// //
// ;
// if (isTenkanSenCrossedOverKijunSen)
// {
// Print("isTenkanSenCrossedOverKijunSen");
// }
// //
// bool isTenkanSenCrossedUnderKijunSen =
// //
// tenkanSen < kijunSen &&
// tenkanSenLast >= kijunSenLast
// //
// ;
// if (isTenkanSenCrossedUnderKijunSen)
// {
// Print("isTenkanSenCrossedUnderKijunSen");
// }
// //
// bool isKumoSwitchedToBullish =
// //
// senkouSpanA > senkouSpanB &&
// senkouSpanALast <= senkouSpanBLast
// //
// ;
// if (isKumoSwitchedToBullish)
// {
// Print("isKumoSwitchedToBullish");
// }
// //
// bool isKumoSwitchedToBearish =
// //
// senkouSpanA < senkouSpanB &&
// senkouSpanALast >= senkouSpanBLast
// //
// ;
// if (isKumoSwitchedToBearish)
// {
// Print("isKumoSwitchedToBearish");
// }
// //
// bool isFutureKumoSwitchedToBullish =
// //
// futureSenkouSpanA > futureSenkouSpanB &&
// futureSenkouSpanALast <= futureSenkouSpanBLast
// //
// ;
// if (isFutureKumoSwitchedToBullish)
// {
// Print("isFutureKumoSwitchedToBullish");
// }
// //
// bool isFutureKumoSwitchedToBearish =
// //
// futureSenkouSpanA < futureSenkouSpanB &&
// futureSenkouSpanALast >= futureSenkouSpanBLast
// //
// ;
// if (isFutureKumoSwitchedToBearish)
// {
// Print("isFutureKumoSwitchedToBearish");
// }
// }
// //
// void TestMCycle()
// {
// //
// // double fast0 = xSampleEA121MC.mc.GetFast(0);
// // double fast1 = xSampleEA121MC.mc.GetFast(1);
// // //
// // double slow0 = xSampleEA121MC.mc.GetSlow(0);
// // double slow1 = xSampleEA121MC.mc.GetSlow(1);
// // //
// // double tenkanSen = xSampleEA121MC.ich.GetTenkanSen(0);
// // //
// // Print("Fast0: " + ToString(fast0));
// // Print("Slow0: " + ToString(slow0));
// // //
// // Print("Fast1: " + ToString(fast1));
// // Print("Slow1: " + ToString(slow1));
// // //
// // Print("TenkanSen: " + ToString(tenkanSen));
// // //
// // bool isFastCrossedOverSlow =
// // //
// // fast0 > slow0 &&
// // fast1 <= slow1
// // //
// // ;
// // if (isFastCrossedOverSlow)
// // {
// // //
// // Print("Fast Crossed Over Slow");
// // }
// //
// X121MCycleConditions conditions = xSampleEA121MC.GetMarketConditions(0);
// string mcSummary = conditions.GenerateSummary();
// Print(mcSummary);
// //
// Print(" ");
// }
void ApplyMCDrawStyles()
{
//
// Here we Apply All Draw Styles on Input of Market Cycle ...
xSampleEA121MCInputs.drawCBar = true;
xSampleEA121MCInputs.drawPBar = true;
xSampleEA121MCInputs.drawLabels = true;
xSampleEA121MCInputs.drawCBarMid = true;
xSampleEA121MCInputs.drawPBarMid = true;
//
// Current ...
//
// MidLine ...
xSampleEA121MCInputs.cBarMidDrawSpecs.width = 1;
xSampleEA121MCInputs.cBarMidDrawSpecs.style = STYLE_DOT;
xSampleEA121MCInputs.cBarMidDrawSpecs.clr = clrSpringGreen;
xSampleEA121MCInputs.cBarMidDrawSpecs.Label(
xSampleEA121MCInputs.cycle.prefix + "_C MID",
xSampleEA121MCInputs.cBarMidDrawSpecs.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
//
// XOHCL ...
xSampleEA121MCInputs.cBarDrawSpecs.Default();
xSampleEA121MCInputs.cBarDrawSpecs.Width(1);
xSampleEA121MCInputs.cBarDrawSpecs.Style(STYLE_DOT);
//
xSampleEA121MCInputs.cBarDrawSpecs.openStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C O",
xSampleEA121MCInputs.cBarDrawSpecs.openStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.cBarDrawSpecs.highStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C H",
xSampleEA121MCInputs.cBarDrawSpecs.highStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.cBarDrawSpecs.closeStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C C",
xSampleEA121MCInputs.cBarDrawSpecs.closeStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.cBarDrawSpecs.lowStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C L",
xSampleEA121MCInputs.cBarDrawSpecs.lowStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
//
// Prev ...
//
// MidLine ...
xSampleEA121MCInputs.pBarMidDrawSpecs.width = 2;
xSampleEA121MCInputs.pBarMidDrawSpecs.style = STYLE_SOLID;
xSampleEA121MCInputs.pBarMidDrawSpecs.clr = clrLimeGreen;
xSampleEA121MCInputs.pBarMidDrawSpecs.Label(
xSampleEA121MCInputs.cycle.prefix + "_P MID",
xSampleEA121MCInputs.pBarMidDrawSpecs.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
//
// XOHCL ...
xSampleEA121MCInputs.pBarDrawSpecs.Default();
xSampleEA121MCInputs.pBarDrawSpecs.Width(2);
//
xSampleEA121MCInputs.pBarDrawSpecs.openStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P O",
xSampleEA121MCInputs.pBarDrawSpecs.openStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.pBarDrawSpecs.highStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P H",
xSampleEA121MCInputs.pBarDrawSpecs.highStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.pBarDrawSpecs.closeStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P C",
xSampleEA121MCInputs.pBarDrawSpecs.closeStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.pBarDrawSpecs.lowStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P L",
xSampleEA121MCInputs.pBarDrawSpecs.lowStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
}
@@ -0,0 +1,180 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XSAMPLE MQL5 Expert Advisor
// -------------------------------------------------
// Name: XSAMPLE
// Description: an Exper Advisor which used RSI and MA
// to Analyse Market ...
//
// 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 XSAMPLE"
#property strict
//
#define ShortName "XSAMPLE"
//
#include "../Libraries/x-saherelm.log.lib.mq5"
#include "../Libraries/x-saherelm.draw.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
#include "../Classes/x-saherelm.xtrade.class.mq5"
//
// Inputs ...
long xSampleEAMagicNumber = 78692110; // Magic Number
int xSampleEASlippage = 10; // Slippgae
//
double xSampleEAVolume = 0.01;
//
// Vars ...
string xSampleEASymbol;
ENUM_TIMEFRAMES xSampleEAPeriod;
//
int maxBuys = 1;
int maxSells = 1;
int buyCount = 0;
int sellCount = 0;
//
double _tp = 0;
double _sl = 0;
double _entry = 0;
ENUM_POSITION_TYPE _type = NULL;
//
MqlTick xSampleEATick;
XSCTrade *xSampleEATrader;
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
if (xSampleEASymbol == NULL || StringLen(xSampleEASymbol) <= 0)
{
xSampleEASymbol = _Symbol;
}
//
if (xSampleEAPeriod == NULL)
{
xSampleEAPeriod = _Period;
}
//
// Validate Inputs ...
if (!XSampleEAValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
logTag = ShortName;
drawPrefix = ShortName;
//
// Initialize XTrader ...
xSampleEATrader = new XSCTrade(
xSampleEASlippage,
xSampleEAMagicNumber);
//
// 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
//
// De Initialize XSampleEA Providers ...
delete xSampleEATrader;
}
//
// On Tick Handler ...
void OnTick()
{
//
if (!IsNewCandle(
xSampleEASymbol,
xSampleEAPeriod))
{
return;
}
//
// Reading Tick ...
if (!SymbolInfoTick(xSampleEASymbol, xSampleEATick))
{
return;
}
//
// Counting Currently Open Positions ...
buyCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_BUY);
sellCount = xSampleEATrader.CountPositions(xSampleEASymbol, POSITION_TYPE_SELL);
//
if (buyCount < maxBuys)
{
//
// Check For Buy Signals ...
}
//
if (sellCount < maxSells)
{
//
// Check for Sell Signals ...
}
}
//
// Custom Functions ...
//
// Validate Variables nd Inputs ...
bool XSampleEAValidateInputs()
{
//
bool result = false;
//
result =
//
xSampleEASlippage > 0 &&
xSampleEAMagicNumber > 0
//
;
//
return result;
}
@@ -0,0 +1,297 @@
//+------------------------------------------------------------------+
//| ZigZag.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 1
//---- plot Zigzag
#property indicator_label1 "Zigzag"
#property indicator_type1 DRAW_SECTION
#property indicator_color1 Red
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int ExtDepth=12;
input int ExtDeviation=5;
input int ExtBackstep=3;
//--- indicator buffers
double ZigzagBuffer[]; // main buffer
double HighMapBuffer[]; // highs
double LowMapBuffer[]; // lows
int level=3; // recounting depth
double deviation; // deviation in points
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA);
SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
//--- set short name and digits
PlotIndexSetString(0,PLOT_LABEL,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")");
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//--- to use in cycle
deviation=ExtDeviation*_Point;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| searching index of the highest bar |
//+------------------------------------------------------------------+
int iHighest(const double &array[],
int depth,
int startPos)
{
int index=startPos;
//--- start index validation
if(startPos<0)
{
Print("Invalid parameter in the function iHighest, startPos =",startPos);
return 0;
}
int size=ArraySize(array);
//--- depth correction if need
if(startPos-depth<0) depth=startPos;
double max=array[startPos];
//--- start searching
for(int i=startPos;i>startPos-depth;i--)
{
if(array[i]>max)
{
index=i;
max=array[i];
}
}
//--- return index of the highest bar
return(index);
}
//+------------------------------------------------------------------+
//| searching index of the lowest bar |
//+------------------------------------------------------------------+
int iLowest(const double &array[],
int depth,
int startPos)
{
int index=startPos;
//--- start index validation
if(startPos<0)
{
Print("Invalid parameter in the function iLowest, startPos =",startPos);
return 0;
}
int size=ArraySize(array);
//--- depth correction if need
if(startPos-depth<0) depth=startPos;
double min=array[startPos];
//--- start searching
for(int i=startPos;i>startPos-depth;i--)
{
if(array[i]<min)
{
index=i;
min=array[i];
}
}
//--- return index of the lowest bar
return(index);
}
//+------------------------------------------------------------------+
//| 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[])
{
int i=0;
int limit=0,counterZ=0,whatlookfor=0;
int shift=0,back=0,lasthighpos=0,lastlowpos=0;
double val=0,res=0;
double curlow=0,curhigh=0,lasthigh=0,lastlow=0;
//--- auxiliary enumeration
enum looling_for
{
Pike=1, // searching for next high
Sill=-1 // searching for next low
};
//--- initializing
if(prev_calculated==0)
{
ArrayInitialize(ZigzagBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
}
//---
if(rates_total<100) return(0);
//--- set start position for calculations
if(prev_calculated==0) limit=ExtDepth;
//--- ZigZag was already counted before
if(prev_calculated>0)
{
i=rates_total-1;
//--- searching third extremum from the last uncompleted bar
while(counterZ<level && i>rates_total-100)
{
res=ZigzagBuffer[i];
if(res!=0) counterZ++;
i--;
}
i++;
limit=i;
//--- what type of exremum we are going to find
if(LowMapBuffer[i]!=0)
{
curlow=LowMapBuffer[i];
whatlookfor=Pike;
}
else
{
curhigh=HighMapBuffer[i];
whatlookfor=Sill;
}
//--- chipping
for(i=limit+1;i<rates_total && !IsStopped();i++)
{
ZigzagBuffer[i]=0.0;
LowMapBuffer[i]=0.0;
HighMapBuffer[i]=0.0;
}
}
//--- searching High and Low
for(shift=limit;shift<rates_total && !IsStopped();shift++)
{
val=low[iLowest(low,ExtDepth,shift)];
if(val==lastlow) val=0.0;
else
{
lastlow=val;
if((low[shift]-val)>deviation) val=0.0;
else
{
for(back=1;back<=ExtBackstep;back++)
{
res=LowMapBuffer[shift-back];
if((res!=0) && (res>val)) LowMapBuffer[shift-back]=0.0;
}
}
}
if(low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0;
//--- high
val=high[iHighest(high,ExtDepth,shift)];
if(val==lasthigh) val=0.0;
else
{
lasthigh=val;
if((val-high[shift])>deviation) val=0.0;
else
{
for(back=1;back<=ExtBackstep;back++)
{
res=HighMapBuffer[shift-back];
if((res!=0) && (res<val)) HighMapBuffer[shift-back]=0.0;
}
}
}
if(high[shift]==val) HighMapBuffer[shift]=val; else HighMapBuffer[shift]=0.0;
}
//--- last preparation
if(whatlookfor==0)// uncertain quantity
{
lastlow=0;
lasthigh=0;
}
else
{
lastlow=curlow;
lasthigh=curhigh;
}
//--- final rejection
for(shift=limit;shift<rates_total && !IsStopped();shift++)
{
res=0.0;
switch(whatlookfor)
{
case 0: // search for peak or lawn
if(lastlow==0 && lasthigh==0)
{
if(HighMapBuffer[shift]!=0)
{
lasthigh=high[shift];
lasthighpos=shift;
whatlookfor=Sill;
ZigzagBuffer[shift]=lasthigh;
res=1;
}
if(LowMapBuffer[shift]!=0)
{
lastlow=low[shift];
lastlowpos=shift;
whatlookfor=Pike;
ZigzagBuffer[shift]=lastlow;
res=1;
}
}
break;
case Pike: // search for peak
if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<lastlow && HighMapBuffer[shift]==0.0)
{
ZigzagBuffer[lastlowpos]=0.0;
lastlowpos=shift;
lastlow=LowMapBuffer[shift];
ZigzagBuffer[shift]=lastlow;
res=1;
}
if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
{
lasthigh=HighMapBuffer[shift];
lasthighpos=shift;
ZigzagBuffer[shift]=lasthigh;
whatlookfor=Sill;
res=1;
}
break;
case Sill: // search for lawn
if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>lasthigh && LowMapBuffer[shift]==0.0)
{
ZigzagBuffer[lasthighpos]=0.0;
lasthighpos=shift;
lasthigh=HighMapBuffer[shift];
ZigzagBuffer[shift]=lasthigh;
}
if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
{
lastlow=LowMapBuffer[shift];
lastlowpos=shift;
ZigzagBuffer[shift]=lastlow;
whatlookfor=Pike;
}
break;
default: return(rates_total);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
@@ -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,830 @@
/**
* 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;
}
//#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,
//
copyFolder,
createDirectory,
removeDirectory,
createDirectory,
removeDirectory,
isDirectoryExists,
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 @@
EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true
@@ -0,0 +1,22 @@
const int rates_total, // total calculated Candles on charts ...
const int prev_calculated, // total calculated Candles on charts ...
const datetime &time[], // history of Candles Open Time ...
const double &open[], // history of Candles Open Price ...
const double &high[], // history of Candles High Price ...
const double &low[], // history of Candles Low Price ...
const double &close[], // history of Candles Close Price ...
const long &tick_volume[], // history of Tick Volumes on Candle ...
const long &volume[], // history of Trade Volumes ...
const int &spread[] // history of Candles Spread Price ...
// //
// // XICH ...
// string ich =
// //
// "" + "\n" +
// "-------------" + "\n" +
// (( || !ignoreFalseConditions) ? ": " + ToString() + "\n" : "") +
// "\n"
// //
// ;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,398 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center XSAMPLE MQL5 Expert Advisor
// -------------------------------------------------
// Name: XSAMPLE
// Description: an Exper Advisor which used RSI and MA
// to Analyse Market ...
//
// 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 XSAMPLE"
#property strict
//
#define ShortName "XSAMPLE"
//
#include "../Libraries/x-saherelm.log.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
#include "../Helpers/x-saherelm.x121.xmc.helper.mq5"
#include "../Helpers/x-saherelm.x121.xstr.helper.mq5"
#include "../Helpers/x-saherelm.x121.xche.helper.mq5"
#include "../Helpers/x-saherelm.x121.xosc.helper.mq5"
//
#include "../Classes/x-saherelm.xtrade.class.mq5"
#include "../Classes/x-saherelm.x121.xmcycle.class.mq5"
//
// Inputs ...
long xSampleEAMagicNumber = 78692110; // Magic Number
int xSampleEASlippage = 10; // Slippgae
//
double xSampleEAVolume = 0.01;
//
// Vars ...
string xSampleEASymbol;
ENUM_TIMEFRAMES xSampleEAPeriod;
//
int maxBuys = 1;
int maxSells = 1;
int buyCount = 0;
int sellCount = 0;
//
double _tp = 0;
double _sl = 0;
double _entry = 0;
ENUM_POSITION_TYPE _type = NULL;
//
MqlTick xSampleEATick;
//
XBarTracker xSamplEABarTracker;
//
// X121MCycle ...
X121MCycleInputs xSampleEA121MCInputs;
XSC121Market xSampleEA121MC;
//
XSCSignalCollector signalCollector;
//
// Event Handlers ...
//
// Initialization ...
int OnInit()
{
//
if (xSampleEASymbol == NULL || StringLen(xSampleEASymbol) <= 0)
{
xSampleEASymbol = _Symbol;
}
//
if (xSampleEAPeriod == NULL)
{
xSampleEAPeriod = _Period;
}
//
// Validate Inputs ...
if (!XSampleEAValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
logTag = ShortName;
drawPrefix = ShortName;
//
bool result = xSamplEABarTracker.Init(
xSampleEASymbol,
xSampleEAPeriod);
if (!result)
{
return INIT_PARAMETERS_INCORRECT;
}
//
// X121Market Cycle ...
result = xSampleEA121MCInputs.Init(
xSampleEASymbol,
xSampleEAPeriod,
X_MARKET_CYCLE_SHORT,
PERIOD_H1,
X_PERIOD_MANUALLY //
);
if (!result)
{
return INIT_PARAMETERS_INCORRECT;
}
//
// after Inputs Initialize Successfully we must prepare Styling for Draw ...
ApplyMCDrawStyles();
//
result = xSampleEA121MC.Init(
xSampleEA121MCInputs
//
);
if (!result)
{
return INIT_PARAMETERS_INCORRECT;
}
//
// 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
//
// De Initialize XSampleEA Providers ...
}
//
// On Tick Handler ...
void OnTick()
{
//
if (!xSamplEABarTracker.IsNewBar())
{
return;
}
//
// Reading Tick ...
if (!SymbolInfoTick(xSampleEASymbol, xSampleEATick))
{
return;
}
//
// Draw Market Cycle Bars On Chart ...
int offset = 0;
xSampleEA121MC.Draw(
ChartID(),
0,
offset
//
);
//
// TestXSignalCollector();
}
//
// Custom Functions ...
//
// Validate Variables nd Inputs ...
bool XSampleEAValidateInputs()
{
//
bool result = false;
//
result =
//
xSampleEASlippage > 0 &&
xSampleEAMagicNumber > 0
//
;
//
return result;
}
//
// Tools ...
//
void TestXSignalCollector()
{
//
XSignal signal;
bool isPrepared = signal.Prepare(
xSampleEASymbol,
"XTest",
xSampleEAPeriod,
POSITION_TYPE_BUY,
X_ORDER_MODE_MARKET,
GetEntry(
xSampleEASymbol,
POSITION_TYPE_BUY),
0.01,
0,
0
//
);
if (isPrepared)
{
//
bool isAdded = signalCollector
.Add(signal);
//
if (isAdded)
{
LogMessage("Signal Added Successfully ...");
}
}
//
// Try to Reading Collection ...
XSignal collectedSignals[];
int collectedSignalsCount = signalCollector.Collect(collectedSignals);
if (collectedSignalsCount > 0)
{
LogMessage("Number of Loaded Signals: " + ToString(collectedSignalsCount));
}
}
//
void ApplyMCDrawStyles()
{
//
// Here we Apply All Draw Styles on Input of Market Cycle ...
xSampleEA121MCInputs.drawCBar = true;
xSampleEA121MCInputs.drawPBar = true;
xSampleEA121MCInputs.drawLabels = true;
xSampleEA121MCInputs.drawCBarMid = true;
xSampleEA121MCInputs.drawPBarMid = true;
//
// Current ...
//
// MidLine ...
xSampleEA121MCInputs.cBarMidDrawSpecs.width = 1;
xSampleEA121MCInputs.cBarMidDrawSpecs.style = STYLE_DOT;
xSampleEA121MCInputs.cBarMidDrawSpecs.clr = clrSpringGreen;
xSampleEA121MCInputs.cBarMidDrawSpecs.Label(
xSampleEA121MCInputs.cycle.prefix + "_C MID",
xSampleEA121MCInputs.cBarMidDrawSpecs.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
//
// XOHCL ...
xSampleEA121MCInputs.cBarDrawSpecs.Default();
xSampleEA121MCInputs.cBarDrawSpecs.Width(1);
xSampleEA121MCInputs.cBarDrawSpecs.Style(STYLE_DOT);
//
xSampleEA121MCInputs.cBarDrawSpecs.openStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C O",
xSampleEA121MCInputs.cBarDrawSpecs.openStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.cBarDrawSpecs.highStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C H",
xSampleEA121MCInputs.cBarDrawSpecs.highStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.cBarDrawSpecs.closeStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C C",
xSampleEA121MCInputs.cBarDrawSpecs.closeStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.cBarDrawSpecs.lowStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_C L",
xSampleEA121MCInputs.cBarDrawSpecs.lowStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
//
// Prev ...
//
// MidLine ...
xSampleEA121MCInputs.pBarMidDrawSpecs.width = 2;
xSampleEA121MCInputs.pBarMidDrawSpecs.style = STYLE_SOLID;
xSampleEA121MCInputs.pBarMidDrawSpecs.clr = clrLimeGreen;
xSampleEA121MCInputs.pBarMidDrawSpecs.Label(
xSampleEA121MCInputs.cycle.prefix + "_P MID",
xSampleEA121MCInputs.pBarMidDrawSpecs.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
//
// XOHCL ...
xSampleEA121MCInputs.pBarDrawSpecs.Default();
xSampleEA121MCInputs.pBarDrawSpecs.Width(2);
//
xSampleEA121MCInputs.pBarDrawSpecs.openStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P O",
xSampleEA121MCInputs.pBarDrawSpecs.openStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.pBarDrawSpecs.highStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P H",
xSampleEA121MCInputs.pBarDrawSpecs.highStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.pBarDrawSpecs.closeStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P C",
xSampleEA121MCInputs.pBarDrawSpecs.closeStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
xSampleEA121MCInputs.pBarDrawSpecs.lowStyle.Label(
xSampleEA121MCInputs.cycle.prefix + "_P L",
xSampleEA121MCInputs.pBarDrawSpecs.lowStyle.clr,
"Arial",
8,
ANCHOR_LEFT_UPPER,
90
//
);
}
@@ -0,0 +1,492 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Helper Class Library
// ----------------------------------------------
// Name: XSCX121CHEHelper
// 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
//
#include "../Classes/x-saherelm.xhelper.class.mq5"
//
// Definitions ...
//
enum ENUM_XCHE_BUFFERS
{
X_CHE_LONG_EXIT_1_LINE = 0,
X_CHE_SHORT_EXIT_1_LINE = 1,
X_CHE_LONG_EXIT_2_LINE = 2,
X_CHE_SHORT_EXIT_2_LINE = 3,
};
//
// Input Models ...
struct X121CHEInputs
{
//
// Props ...
//
// Market ...
int length; // Length
int loopback; // Loopback
double multiplier1; // 1st Multiplier
double multiplier2; // 2nd Multiplier
//
// Calculation ...
ENUM_APPLIED_PRICE upAppliedTo; // Up Zone Applied To
ENUM_APPLIED_PRICE downAppliedTo; // Down Zone Applied To
//
// Constructor(s) ...
X121CHEInputs()
{
//
Clean();
}
//
// Tools ...
//
// Clean ...
void Clean()
{
//
length = 0;
loopback = 0;
multiplier1 = 0;
multiplier2 = 0;
//
upAppliedTo = PRICE_HIGH;
downAppliedTo = PRICE_LOW;
}
//
// Default ...
void Default()
{
//
length = 35;
loopback = 26;
multiplier1 = 3.0;
multiplier2 = 3.5;
//
upAppliedTo = PRICE_HIGH;
downAppliedTo = PRICE_LOW;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
length > 0 &&
loopback < length &&
multiplier1 > 0 &&
multiplier2 > multiplier1
//
;
//
return result;
}
//
// Retrieve MAx Length ...
int Max()
{
//
int result = 0;
//
result = MathMax(length, loopback);
//
return result;
}
};
//
// Class ...
class XSCX121CHEHelper : public XSCBaseHelper
{
//
// Public ...
public:
//
// Props ...
//
// Constructors ...
XSCX121CHEHelper() : XSCBaseHelper(_Symbol, _Period)
{
}
//
// Deconstructor ...
~XSCX121CHEHelper() {}
//
// Tools ...
bool Init(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period, // Trading Period
X121CHEInputs &inputs // Inputs
)
{
//
bool result = false;
//
mSymbol = symbol;
mPeriod = period;
//
result = inputs.IsValid();
if (!result)
{
return result;
}
//
mInputs = inputs;
//
ArraySetAsSeries(longExit1Buffer, true);
ArraySetAsSeries(longExit2Buffer, true);
ArraySetAsSeries(shortExit1Buffer, true);
ArraySetAsSeries(shortExit2Buffer, true);
mHandler = iCustom(
mSymbol,
mPeriod,
"x-saherelm.x121.xche",
//
// Inputs ...
//
// Market ...
"",
mInputs.length,
mInputs.loopback,
mInputs.multiplier1,
mInputs.multiplier2,
//
// Calculations ...
"",
mInputs.upAppliedTo,
mInputs.downAppliedTo,
//
// Presentation ...
"",
false,
false,
false,
false
//
);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
return result;
}
//
// Inputs ...
//
X121CHEInputs GetInputs() {
return mInputs;
}
//
bool SetInputs(
X121CHEInputs &inputs // Configs
) {
//
return Init(
mSymbol,
mPeriod,
inputs
);
}
//
// Buffers ...
//
double GetLongExit1(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return longExit1Buffer[barIndex];
}
//
// Copy Required Long Exits 1 ...
int CopyLongExit1(
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,
longExit1Buffer,
buffer,
forceClean
//
);
}
//
double GetLongExit2(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return longExit2Buffer[barIndex];
}
//
// Copy Required Long Exits 2 ...
int CopyLongExit2(
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,
longExit2Buffer,
buffer,
forceClean
//
);
}
//
double GetShortExit1(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return shortExit1Buffer[barIndex];
}
//
// Copy Required Short Exits 1 ...
int CopyShortExit1(
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,
shortExit1Buffer,
buffer,
forceClean
//
);
}
//
double GetShortExit2(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return shortExit2Buffer[barIndex];
}
//
// Copy Required Short Exits 2 ...
int CopyShortExit2(
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,
shortExit2Buffer,
buffer,
forceClean
//
);
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
X121CHEInputs mInputs; // Inputs ...
//
// Buffers ...
//
double longExit1Buffer[];
double longExit2Buffer[];
double shortExit1Buffer[];
double shortExit2Buffer[];
//
// Tools ...
//
// Calculate Values Until Now ...
void Calculate()
{
//
int totalBars = CountBars();
int calculatedBars = CountCalculatedBars();
//
// Long Exit 1 ...
CopyBuffer(
mHandler,
X_CHE_LONG_EXIT_1_LINE,
0,
totalBars,
longExit1Buffer
//
);
//
// Long Exit 2 ...
CopyBuffer(
mHandler,
X_CHE_LONG_EXIT_2_LINE,
0,
totalBars,
longExit2Buffer
//
);
//
// Short Exit 1 ...
CopyBuffer(
mHandler,
X_CHE_SHORT_EXIT_1_LINE,
0,
totalBars,
shortExit1Buffer
//
);
//
// Short Exit 2 ...
CopyBuffer(
mHandler,
X_CHE_SHORT_EXIT_2_LINE,
0,
totalBars,
shortExit2Buffer
//
);
}
};
//
// Tools ...
@@ -0,0 +1,717 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Helper Class Library
// ----------------------------------------------
// Name: XSCX121ICHHelper
// 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
//
#include "../Classes/x-saherelm.xhelper.class.mq5"
//
// Definitions ...
//
// Ichimoku Lines Calculator Mode ...
enum ENUM_XICH_CALCULATION_MODE
{
//
X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low
X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close
};
//
enum ENUM_XICH_BUFFERS
{
X_ICH_TEANKANSEN_LINE = 0,
X_ICH_KIJUNSEN_LINE = 1,
X_ICH_CHIKOUSPAN_LINE = 4,
X_ICH_SENKOUSPANA_LINE = 5,
X_ICH_SENKOUSPANB_LINE = 6,
};
//
// Input Models ...
struct X121ICHInputs
{
//
// Props ...
//
// Market ...
//
// Tenkan Sen ...
int tenkanSenLength; // Length
ENUM_XICH_CALCULATION_MODE tenkanSenMode; // Calculation Mode
//
// Kijun Sen ...
int kijunSenLength; // Length
ENUM_XICH_CALCULATION_MODE kijunSenMode; // Calculation Mode
//
// Senkou Span B ...
int senkouSpanBLength; // Length
ENUM_XICH_CALCULATION_MODE senkouSpanBMode; // Calculation Mode
//
// Chikou Span ...
ENUM_APPLIED_PRICE chikuoSpanAppliedTo; // Price Type
//
// Constructor(s) ...
X121ICHInputs()
{
//
Clean();
}
//
// Tools ...
//
// Clean ...
void Clean()
{
//
kijunSenLength = 0;
tenkanSenLength = 0;
senkouSpanBLength = 0;
//
kijunSenMode = X_XICH_HH_LL_MODE;
tenkanSenMode = X_XICH_HH_LL_MODE;
senkouSpanBMode = X_XICH_HH_LL_MODE;
//
chikuoSpanAppliedTo = PRICE_CLOSE;
}
//
// Default ...
void Default()
{
//
kijunSenLength = 26;
tenkanSenLength = 9;
senkouSpanBLength = 52;
//
kijunSenMode = X_XICH_HH_LL_MODE;
tenkanSenMode = X_XICH_HH_LL_MODE;
senkouSpanBMode = X_XICH_HH_LL_MODE;
//
chikuoSpanAppliedTo = PRICE_CLOSE;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
tenkanSenLength > 2 &&
kijunSenLength > tenkanSenLength &&
senkouSpanBLength > kijunSenLength
//
;
//
return result;
}
//
// Retrieve MAx Length ...
int Max()
{
//
int result = 0;
//
result = MathMax(result, tenkanSenLength);
result = MathMax(result, kijunSenLength);
result = MathMax(result, senkouSpanBLength);
//
return result;
}
};
//
// Class ...
class XSCX121ICHHelper : public XSCBaseHelper
{
//
// Public ...
public:
//
// Props ...
//
// Constructors ...
XSCX121ICHHelper() : XSCBaseHelper(_Symbol, _Period)
{
}
//
// Deconstructor ...
~XSCX121ICHHelper() {}
//
// Tools ...
bool Init(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period, // Trading Period
X121ICHInputs &inputs // Inputs
)
{
//
bool result = false;
//
mSymbol = symbol;
mPeriod = period;
//
result = inputs.IsValid();
if (!result)
{
return result;
}
//
mInputs = inputs;
//
ArraySetAsSeries(tenkanSenBuffer, true);
ArraySetAsSeries(kijunSenBuffer, true);
ArraySetAsSeries(chikouSpanBuffer, true);
ArraySetAsSeries(senkouSpanABuffer, true);
ArraySetAsSeries(senkouSpanBBuffer, true);
mHandler = iCustom(
mSymbol,
mPeriod,
"x-saherelm.x121.xich",
//
// Inputs ...
//
// TenkanSen ...
"",
mInputs.tenkanSenLength,
mInputs.tenkanSenMode,
//
// KijunSen ...
"",
mInputs.kijunSenLength,
mInputs.kijunSenMode,
//
// SenkouSpan B ...
"",
mInputs.senkouSpanBLength,
mInputs.senkouSpanBMode,
//
// ChikouSpan ...
"",
mInputs.chikuoSpanAppliedTo,
//
// Presentation ...
"",
false,
false,
false,
false,
false,
false,
false,
false,
false,
true // Push Kumo to Future ...
//
);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
return result;
}
//
// Inputs ...
//
X121ICHInputs GetInputs()
{
return mInputs;
}
//
bool SetInputs(
X121ICHInputs &inputs // Configs
)
{
//
return Init(
mSymbol,
mPeriod,
inputs);
}
//
// Buffers ...
//
// TenkanSen ...
//
double GetTenkanSen(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return tenkanSenBuffer[barIndex];
}
//
// Copy Required Items ...
int CopyTenkanSen(
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,
tenkanSenBuffer,
buffer,
forceClean
//
);
}
//
// KijunSen ...
//
double GetKijunSen(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return kijunSenBuffer[barIndex];
}
//
// Copy Required Items ...
int CopyKijunSen(
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,
kijunSenBuffer,
buffer,
forceClean
//
);
}
//
// ChikouSpan ...
//
double GetChikouSpan(
int barIndex // Bar Index
)
{
//
barIndex -= mInputs.kijunSenLength;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex > ArraySize(chikouSpanBuffer)) {
barIndex = ArraySize(chikouSpanBuffer) - 1;
}
//
Calculate();
//
return chikouSpanBuffer[barIndex];
}
//
// Copy Required Items ...
int CopyChikouSpan(
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 - mInputs.kijunSenLength,
count,
chikouSpanBuffer,
buffer,
forceClean
//
);
}
//
// SenkouSpanA ...
//
double GetSenkouSpanA(
int barIndex // Bar Index
)
{
//
barIndex += mInputs.kijunSenLength;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex > ArraySize(senkouSpanABuffer)) {
barIndex = ArraySize(senkouSpanABuffer) - 1;
}
//
Calculate();
//
return senkouSpanABuffer[barIndex];
}
//
// Copy Required Items ...
int CopySenkouSpanA(
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 + mInputs.kijunSenLength,
count,
senkouSpanABuffer,
buffer,
forceClean
//
);
}
//
// SenkouSpanB ...
//
double GetSenkouSpanB(
int barIndex // Bar Index
)
{
//
barIndex += mInputs.kijunSenLength;
//
if (barIndex < 0)
{
barIndex = 0;
}
//
if (barIndex > ArraySize(senkouSpanBBuffer)) {
barIndex = ArraySize(senkouSpanBBuffer) - 1;
}
//
Calculate();
//
return senkouSpanBBuffer[barIndex + mInputs.kijunSenLength];
}
//
// Copy Required Items ...
int CopySenkouSpanB(
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 + mInputs.kijunSenLength,
count,
senkouSpanBBuffer,
buffer,
forceClean
//
);
}
//
// Future SenkouSpanA ...
//
double GetFutureSenkouSpanA(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return senkouSpanABuffer[barIndex];
}
//
// Copy Required Items ...
int CopyFutureSenkouSpanA(
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,
senkouSpanABuffer,
buffer,
forceClean
//
);
}
//
// SenkouSpanB ...
//
double GetFutureSenkouSpanB(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return senkouSpanBBuffer[barIndex];
}
//
// Copy Required Items ...
int CopyFutureSenkouSpanB(
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,
senkouSpanBBuffer,
buffer,
forceClean
//
);
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
X121ICHInputs mInputs; // Inputs ...
//
// Buffers ...
double tenkanSenBuffer[];
double kijunSenBuffer[];
double chikouSpanBuffer[];
double senkouSpanABuffer[];
double senkouSpanBBuffer[];
//
// Tools ...
//
// Calculate Values Until Now ...
void Calculate()
{
//
int totalBars = CountBars();
int calculatedBars = CountCalculatedBars();
//
// TenkanSen ...
CopyBuffer(
mHandler,
X_ICH_TEANKANSEN_LINE,
0,
totalBars,
tenkanSenBuffer
//
);
//
// KijunSen ...
CopyBuffer(
mHandler,
X_ICH_KIJUNSEN_LINE,
0,
totalBars,
kijunSenBuffer
//
);
//
// ChikouSpan ...
CopyBuffer(
mHandler,
X_ICH_CHIKOUSPAN_LINE,
0,
totalBars,
chikouSpanBuffer
//
);
//
// SenkouSpan A ...
CopyBuffer(
mHandler,
X_ICH_SENKOUSPANA_LINE,
0,
totalBars,
senkouSpanABuffer
//
);
//
// SenkouSpan B ...
CopyBuffer(
mHandler,
X_ICH_SENKOUSPANB_LINE,
0,
totalBars,
senkouSpanBBuffer
//
);
}
};
//
// Tools ...
@@ -0,0 +1,481 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Helper Class Library
// ----------------------------------------------
// Name: XSCX121MCHelper
// 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
//
#include "../Classes/x-saherelm.xhelper.class.mq5"
//
// Definitions ...
//
enum ENUM_XMC_BUFFERS
{
X_MC_FAST_LINE = 0,
X_MC_SLOW_LINE = 1,
X_MC_VERIFIER_LINE = 2,
};
//
// Input Models ...
struct X121MCInputs
{
//
// Props ...
//
// Market ...
//
// Fast ...
int fastLength; // Length
int fastShift; // Shift
ENUM_MA_METHOD fastMethod; // Method
ENUM_APPLIED_PRICE fastAppliedTo; // Applied To
//
// Slow ...
int slowLength; // Length
int slowShift; // Shift
ENUM_MA_METHOD slowMethod; // Method
ENUM_APPLIED_PRICE slowAppliedTo; // Applied To
//
// Verifier ...
int verifierLength; // Length
int verifierShift; // Shift
ENUM_MA_METHOD verifierMethod; // Method
ENUM_APPLIED_PRICE verifierAppliedTo; // Applied To
//
// Constructor(s) ...
X121MCInputs()
{
//
Clean();
}
//
// Tools ...
//
// Clean ...
void Clean()
{
//
fastLength = 0;
fastShift = 0;
fastMethod = 0;
fastAppliedTo = PRICE_CLOSE;
//
slowLength = 0;
slowShift = 0;
slowMethod = 0;
slowAppliedTo = PRICE_CLOSE;
//
verifierLength = 0;
verifierShift = 0;
verifierMethod = 0;
verifierAppliedTo = PRICE_CLOSE;
}
//
// Default ...
void Default()
{
//
fastLength = 9;
fastShift = 0;
fastMethod = MODE_EMA;
fastAppliedTo = PRICE_CLOSE;
//
slowLength = 18;
slowShift = 0;
slowMethod = MODE_EMA;
slowAppliedTo = PRICE_CLOSE;
//
verifierLength = 200;
verifierShift = 0;
verifierMethod = MODE_EMA;
verifierAppliedTo = PRICE_CLOSE;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
fastLength > 1 &&
slowLength > fastLength &&
verifierLength > slowLength
//
;
//
return result;
}
//
// Retrieve MAx Length ...
int Max()
{
//
int result = 0;
//
result = MathMax(fastLength, slowLength);
result = MathMax(result, verifierLength);
//
return result;
}
};
//
// Class ...
class XSCX121MCHelper : public XSCBaseHelper
{
//
// Public ...
public:
//
// Props ...
//
// Constructors ...
XSCX121MCHelper() : XSCBaseHelper(_Symbol, _Period)
{
}
//
// Deconstructor ...
~XSCX121MCHelper() {}
//
// Tools ...
bool Init(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period, // Trading Period
X121MCInputs &inputs // Inputs
)
{
//
bool result = false;
//
mSymbol = symbol;
mPeriod = period;
//
result = inputs.IsValid();
if (!result)
{
return result;
}
//
mInputs = inputs;
//
ArraySetAsSeries(fastBuffer, true);
ArraySetAsSeries(slowBuffer, true);
ArraySetAsSeries(verifierBuffer, true);
mHandler = iCustom(
mSymbol,
mPeriod,
"x-saherelm.x121.xmc",
//
// Inputs ...
//
// Fast ...
"",
mInputs.fastLength,
mInputs.fastShift,
mInputs.fastMethod,
mInputs.fastAppliedTo,
//
// Slow ...
"",
mInputs.slowLength,
mInputs.slowShift,
mInputs.slowMethod,
mInputs.slowAppliedTo,
//
// Verifier ...
"",
mInputs.verifierLength,
mInputs.verifierShift,
mInputs.verifierMethod,
mInputs.verifierAppliedTo,
//
// Presentation ...
"",
false,
false,
false
//
);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
return result;
}
//
// Inputs ...
//
X121MCInputs GetInputs()
{
return mInputs;
}
//
bool SetInputs(
X121MCInputs &inputs // Configs
)
{
//
return Init(
mSymbol,
mPeriod,
inputs);
}
//
// Buffers ...
//
// Fast ...
//
double GetFast(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return fastBuffer[barIndex];
}
//
// Copy Required Buffer ...
int CopyFast(
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,
fastBuffer,
buffer,
forceClean
//
);
}
//
// Slow ...
//
double GetSlow(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return slowBuffer[barIndex];
}
//
// Copy Required Buffer ...
int CopySlow(
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,
slowBuffer,
buffer,
forceClean
//
);
}
//
// Verifier ...
//
double GetVerifier(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return verifierBuffer[barIndex];
}
//
// Copy Required Buffer ...
int CopyVerifier(
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,
verifierBuffer,
buffer,
forceClean
//
);
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
X121MCInputs mInputs; // Inputs ...
//
// Buffers ...
//
double fastBuffer[];
double slowBuffer[];
double verifierBuffer[];
//
// Tools ...
//
// Calculate Values Until Now ...
void Calculate()
{
//
int totalBars = CountBars();
int calculatedBars = CountCalculatedBars();
//
// Fast ...
CopyBuffer(
mHandler,
X_MC_FAST_LINE,
0,
totalBars,
fastBuffer
//
);
//
// Slow ...
CopyBuffer(
mHandler,
X_MC_SLOW_LINE,
0,
totalBars,
slowBuffer
//
);
//
// Verifier ...
CopyBuffer(
mHandler,
X_MC_VERIFIER_LINE,
0,
totalBars,
verifierBuffer
//
);
}
};
//
// Tools ...
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,408 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Helper Class Library
// ----------------------------------------------
// Name: XSCX121STRHelper
// 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
//
#include "../Classes/x-saherelm.xhelper.class.mq5"
//
// Definitions ...
//
enum ENUM_XSTR_BUFFERS
{
X_STR_TREND_LINE = 0,
X_STR_STATE_LINE = 5,
};
//
enum ENUM_XSTR_TREND_STATES
{
X_STR_BULLISH = 1, // Bullish
X_STR_BEARISH = -1, // Bearish
};
//
// Input Models ...
struct X121STRInputs
{
//
// Props ...
//
// ATR ...
int length; // Length
double multiplier; // Multiplier
ENUM_APPLIED_PRICE appliedTo; // Applied To
//
// Constructor(s) ...
X121STRInputs()
{
//
Clean();
}
//
// Tools ...
//
// Clean ...
void Clean()
{
//
length = 0;
multiplier = 0;
appliedTo = PRICE_CLOSE;
}
//
// Default ...
void Default()
{
//
length = 14;
multiplier = 3.5;
appliedTo = PRICE_MEDIAN;
}
//
// Validate ...
bool IsValid()
{
//
bool result = false;
//
result =
//
length > 0 &&
multiplier > 0
//
;
//
return result;
}
//
// Retrieve MAx Length ...
int Max()
{
//
int result = 0;
//
result = length;
//
return result;
}
};
//
// Class ...
class XSCX121STRHelper : public XSCBaseHelper
{
//
// Public ...
public:
//
// Props ...
//
// Constructors ...
XSCX121STRHelper() : XSCBaseHelper(_Symbol, _Period)
{
}
//
// Deconstructor ...
~XSCX121STRHelper() {}
//
// Tools ...
bool Init(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period, // Trading Period
X121STRInputs &inputs // Inputs
)
{
//
bool result = false;
//
mSymbol = symbol;
mPeriod = period;
//
result = inputs.IsValid();
if (!result)
{
return result;
}
//
mInputs = inputs;
//
ArraySetAsSeries(trendBuffer, true);
ArraySetAsSeries(stateBuffer, true);
mHandler = iCustom(
mSymbol,
mPeriod,
"x-saherelm.x121.xstr",
//
// Inputs ...
//
// ATR ...
"",
mInputs.length,
mInputs.multiplier,
mInputs.appliedTo,
//
// Presentation ...
"",
false,
false
//
);
result = mHandler != INVALID_HANDLE;
if (!result)
{
return result;
}
//
return result;
}
//
// Inputs ...
//
X121STRInputs GetInputs()
{
return mInputs;
}
//
bool SetInputs(
X121STRInputs &inputs // Configs
)
{
//
return Init(
mSymbol,
mPeriod,
inputs);
}
//
// Buffers ...
//
// Trend ...
//
double GetTrend(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return trendBuffer[barIndex];
}
//
// Copy Required Buffer ...
int CopyTrend(
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,
trendBuffer,
buffer,
forceClean
//
);
}
//
// State ...
//
ENUM_XSTR_TREND_STATES GetState(
int barIndex // Bar Index
)
{
//
if (barIndex < 0)
{
barIndex = 0;
}
//
Calculate();
//
return (ENUM_XSTR_TREND_STATES)((int)stateBuffer[barIndex]);
}
//
// Copy Required Buffer ...
int CopyState(
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,
stateBuffer,
buffer,
forceClean
//
);
}
//
// Tools ...
//
ENUM_XSTR_TREND_STATES ToState(double state)
{
return (ENUM_XSTR_TREND_STATES)((int)state);
}
//
bool IsBullish(double state)
{
//
bool result = false;
//
result =
//
ToState(state) == X_STR_BULLISH;
//
;
//
return result;
}
//
bool IsBearish(double state)
{
//
bool result = false;
//
result =
//
ToState(state) == X_STR_BEARISH;
//
;
//
return result;
}
//
// Protected ...
protected:
//
// Private ...
private:
//
// Props ...
X121STRInputs mInputs; // Inputs ...
//
// Buffers ...
double trendBuffer[];
double stateBuffer[];
//
// Tools ...
//
// Calculate Values Until Now ...
void Calculate()
{
//
int totalBars = CountBars();
int calculatedBars = CountCalculatedBars();
//
// Trend ...
CopyBuffer(
mHandler,
X_STR_TREND_LINE,
0,
totalBars,
trendBuffer
//
);
//
// State ...
CopyBuffer(
mHandler,
X_STR_STATE_LINE,
0,
totalBars,
stateBuffer
//
);
}
};
//
// Tools ...
@@ -0,0 +1,631 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// ---------------------------------------------
// Name: X121_XCHE
// Description: Chandelier Exit 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_XCHE Indicator"
#property strict
//
// START Constants ...
//
//
#define ShortName "X121_XCHE"
//
// END Constants ...
//
//
// START Inputs ...
//
//
input group "Market";
input int length = 35; // Length
input int loopback = 26; // Loopback
input double multiplier1 = 3.0; // 1st Multiplier
input double multiplier2 = 3.5; // 2nd Multiplier
//
input group "Calculation";
input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to
input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to
//
input group "Presentation";
input bool showLongExit1Line = true; // Show 1st Long Exit
input bool showShortExit1Line = true; // Show 1st Short Exit
input bool showLongExit2Line = true; // Show 2st Long Exit
input bool showShortExit2Line = true; // Show 2st Short Exit
//
// END Inputs ...
//
//
// START Includes and Imports ...
//
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Includes and Imports ...
//
//
// START Buffers ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 8
#property indicator_plots 8
//
// Long Exit 1 ...
#define longExit1BufferIndex 0
double longExit1Buffer[];
//
#property indicator_label1 "X121_XCHE LE 1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLime
#property indicator_style1 STYLE_DOT
//
// Short Exit 1 ...
#define shortExit1BufferIndex 1
double shortExit1Buffer[];
//
#property indicator_label2 "X121_XCHE SE 1"
#property indicator_type2 DRAW_LINE
#property indicator_style2 STYLE_DOT
#property indicator_color2 clrRed
//
// Long Exit 2 ...
#define longExit2BufferIndex 2
double longExit2Buffer[];
//
#property indicator_label3 "X121_XCHE LE 2"
#property indicator_type3 DRAW_LINE
#property indicator_style2 STYLE_DOT
#property indicator_color3 clrAqua
//
// Short Exit 2 ...
#define shortExit2BufferIndex 3
double shortExit2Buffer[];
//
#property indicator_label4 "X121_XCHE SE 2"
#property indicator_type4 DRAW_LINE
#property indicator_style2 STYLE_DOT
#property indicator_color4 clrMagenta
//
// START Arrows ...
//
// Long Exit 1 Start ...
#define longExit1StartBufferIndex 4
double longExit1StartBuffer[];
//
#property indicator_label5 "X121_XCHE LES 1"
#property indicator_type5 DRAW_ARROW
#property indicator_color5 clrLime
//
// Short Exit 1 Start ...
#define shortExit1StartBufferIndex 5
double shortExit1StartBuffer[];
//
#property indicator_label6 "X121_XCHE SES 1"
#property indicator_type6 DRAW_ARROW
#property indicator_color6 clrRed
//
// Long Exit 2 Start ...
#define longExit2StartBufferIndex 6
double longExit2StartBuffer[];
//
#property indicator_label7 "X121_XCHE LES 2"
#property indicator_type7 DRAW_ARROW
#property indicator_color7 clrAqua
//
// Short Exit 2 Start ...
#define shortExit2StartBufferIndex 7
double shortExit2StartBuffer[];
//
#property indicator_label8 "X121_XCHE SES 2"
#property indicator_type8 DRAW_ARROW
#property indicator_color8 clrMagenta
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
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
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
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 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;
}
//
// 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 mPeriod 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(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
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 ...
int limit;
//
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;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = true;
//
result =
length >= 9 &&
loopback >= 0;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(length, loopback);
//
return result;
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
uint arrowCode = 159;
//
// LEVEL 1 ...
//
// Long Exit 1 ...
//
// Draw Type ...
ENUM_DRAW_TYPE longExit1DrawType = showLongExit1Line ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE longExit1StartDrawType = showLongExit1Line ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(longExit1BufferIndex, longExit1Buffer, INDICATOR_DATA);
PlotIndexSetInteger(longExit1BufferIndex, PLOT_SHOW_DATA, showLongExit1Line);
PlotIndexSetInteger(longExit1BufferIndex, PLOT_DRAW_TYPE, longExit1DrawType);
//
// Start Buffer ...
SetIndexBuffer(longExit1StartBufferIndex, longExit1StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_ARROW, arrowCode);
PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(longExit1StartBufferIndex, PLOT_DRAW_TYPE, longExit1StartDrawType);
//
// Short Exit 1 ...
//
// Draw Type ...
ENUM_DRAW_TYPE shortExit1DrawType = showShortExit1Line ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE shortExit1StartDrawType = showShortExit1Line ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(shortExit1BufferIndex, shortExit1Buffer, INDICATOR_DATA);
PlotIndexSetInteger(shortExit1BufferIndex, PLOT_SHOW_DATA, showShortExit1Line);
PlotIndexSetInteger(shortExit1BufferIndex, PLOT_DRAW_TYPE, shortExit1DrawType);
//
// Start Buffer ...
SetIndexBuffer(shortExit1StartBufferIndex, shortExit1StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_ARROW, arrowCode);
PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(shortExit1StartBufferIndex, PLOT_DRAW_TYPE, shortExit1StartDrawType);
//
// LEVEL 2 ...
//
// Long Exit 2 ...
//
// Draw Type ...
ENUM_DRAW_TYPE longExit2DrawType = showLongExit2Line ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE longExit2StartDrawType = showLongExit2Line ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(longExit2BufferIndex, longExit2Buffer, INDICATOR_DATA);
PlotIndexSetInteger(longExit2BufferIndex, PLOT_SHOW_DATA, showLongExit2Line);
PlotIndexSetInteger(longExit2BufferIndex, PLOT_DRAW_TYPE, longExit2DrawType);
//
// Start Buffer ...
SetIndexBuffer(longExit2StartBufferIndex, longExit2StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_ARROW, arrowCode);
PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(longExit2StartBufferIndex, PLOT_DRAW_TYPE, longExit2StartDrawType);
//
// Short Exit 2 ...
//
// Draw Type ...
ENUM_DRAW_TYPE shortExit2DrawType = showShortExit2Line ? DRAW_LINE : DRAW_NONE;
ENUM_DRAW_TYPE shortExit2StartDrawType = showShortExit2Line ? DRAW_ARROW : DRAW_NONE;
//
// Buffer ...
SetIndexBuffer(shortExit2BufferIndex, shortExit2Buffer, INDICATOR_DATA);
PlotIndexSetInteger(shortExit2BufferIndex, PLOT_SHOW_DATA, showShortExit2Line);
PlotIndexSetInteger(shortExit2BufferIndex, PLOT_DRAW_TYPE, shortExit2DrawType);
//
// Start Buffer ...
SetIndexBuffer(shortExit2StartBufferIndex, shortExit2StartBuffer, INDICATOR_DATA);
PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_ARROW, arrowCode);
PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(shortExit2StartBufferIndex, PLOT_DRAW_TYPE, shortExit2StartDrawType);
}
//
// 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 ...
longExit1Buffer[bar_index] = longExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index] = shortExit1StartBuffer[bar_index] = EMPTY_VALUE;
longExit2Buffer[bar_index] = longExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index] = shortExit2StartBuffer[bar_index] = EMPTY_VALUE;
//
int start = MathMax(bar_index - loopback, 0);
//
// Calculate ATR Value ...
double atrValue = 0;
for (int k = 1; k <= length && (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)length;
//
// Retrieve Highest High and Lowest Lows ...
double loopbackMax = high[ArrayMaximum(high, start, loopback)];
double loopbackMin = low[ArrayMinimum(low, start, loopback)];
//
// Fill Multi Dimesional Working Array ...
work[bar_index][hi1Idx] = loopbackMax - multiplier1 * atrValue;
work[bar_index][lo1Idx] = loopbackMin + multiplier1 * atrValue;
work[bar_index][hi2Idx] = loopbackMax - multiplier2 * atrValue;
work[bar_index][lo2Idx] = loopbackMin + multiplier2 * 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 (multiplier1 > 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];
}
//
longExit1Buffer[bar_index] = work[bar_index][hi1Idx];
//
if (longExit1Buffer[bar_index - 1] == EMPTY_VALUE)
{
longExit1StartBuffer[bar_index] = longExit1Buffer[bar_index];
}
}
//
// Short ...
if (multiplier1 > 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];
}
//
shortExit1Buffer[bar_index] = work[bar_index][lo1Idx];
//
if (shortExit1Buffer[bar_index - 1] == EMPTY_VALUE)
{
shortExit1StartBuffer[bar_index] = shortExit1Buffer[bar_index];
}
}
//
// Exit 2 ...
//
// Long ...
if (multiplier2 > 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];
}
//
longExit2Buffer[bar_index] = work[bar_index][hi2Idx];
//
if (longExit2Buffer[bar_index - 1] == EMPTY_VALUE)
{
longExit2StartBuffer[bar_index] = longExit2Buffer[bar_index];
}
}
//
// Short ...
if (multiplier2 > 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];
}
//
shortExit2Buffer[bar_index] = work[bar_index][lo2Idx];
//
if (shortExit2Buffer[bar_index - 1] == EMPTY_VALUE)
{
shortExit2StartBuffer[bar_index] = shortExit2Buffer[bar_index];
}
}
}
}
//
// END Functions ...
//
@@ -0,0 +1,836 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// -------------------------------------------------
// Name: X121_XICH
// Description: Ichimoku Kinko Hyo ...
//
//
// 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_XICH Indicator"
#property strict
//
// START Constants ...
//
//
// Indicator Short Name ...
#define ShortName "X121_XICH"
//
// Ichimoku Golden Numbers ...
enum ENUM_X_ICHIMOKU_GOLDEN_NUMBERS
{
X_ICH_BASE = 9,
X_ICH_GOLDEN = 17,
X_ICH_CYCLE = 26,
X_ICH_PERIOD = 35,
X_ICH_STAR = 45,
X_ICH_MED = 52,
X_ICH_LONG = 63,
X_ICH_FULL = 72
};
//
// Ichimoku Lines Calculator Mode ...
enum ENUM_X_ICHIMOKU_CALCULATION_MODE
{
//
X_XICH_HH_LL_MODE = 1, // Highest High and Lowest Low
X_XICH_HO_LC_MODE = 2, // Highest Open and Lowest Close
};
//
// END Constants ...
//
//
// START Inputs ...
//
//
// ICHIMOKU Kinko Hyo ...
//
// TENKANSEN ...
input group "Tenkan Sen";
input int tenkanSenLength = 9; // Length
input ENUM_X_ICHIMOKU_CALCULATION_MODE tenkanSenMode = X_XICH_HH_LL_MODE; // Calculation Mode
//
// KIJUNSEN ...
input group "Kijun Sen";
input int kijunSenLength = 26; // Length
input ENUM_X_ICHIMOKU_CALCULATION_MODE kijunSenMode = X_XICH_HH_LL_MODE; // Calculation Mode
//
// SENKOUSPANB ...
input group "Senkou Span B";
input int senkouSpanBLength = 52; // Length
input ENUM_X_ICHIMOKU_CALCULATION_MODE senkouSpanBMode = X_XICH_HH_LL_MODE; // Calculation Mode
//
// CHIKOUSPAN ...
input group "Chikou Span";
input ENUM_APPLIED_PRICE chikuoSpanAppliedTo = PRICE_CLOSE; // Price Type
//
input group "Presentation";
input bool showTenkanSen = true; // Show Tenkan Sen
input bool showKijunSen = true; // Show Kijun Sen
input bool showKijunSenPlus = false; // Show Kijun Sen +
input bool showKijunSenNegative = false; // Show Kijun Sen -
input bool showChikouSpan = true; // Show Chikou Span
input bool showSenkouSpanA = true; // Show Senkou Span A
input bool showSenkouSpanB = true; // Show Senkou Span B
input bool showKumo = true; // Show Kumo
input bool shiftKumo = true; // Shift Kumo to Future
//
// END Inputs ...
//
//
// START Includes and Imports ...
//
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Includes and Imports ...
//
//
// START Buffers ...
//
#property indicator_chart_window
//
#property indicator_buffers 15
#property indicator_plots 8
//
// PLOTTED Buffers ...
//
// ICHIMOKU ...
//
// TENKANSEN ...
//
#define tenkanSenBufferIndex 0
double tenkanSenBuffer[];
//
#property indicator_label1 "X121_XICH TK"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBrown
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//
// KIJUNSEN ...
//
#define kijunSenBufferIndex 1
double kijunSenBuffer[];
//
#property indicator_label2 "X121_XICH KJ"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDodgerBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//
#define kijunSenPlusBufferIndex 2
double kijunSenPlusBuffer[];
//
#property indicator_label3 "X121_XICH KJ+"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrMediumTurquoise
#property indicator_style3 STYLE_DOT
#property indicator_width3 1
//
#define kijunSenNegativeBufferIndex 3
double kijunSenNegativeBuffer[];
//
#property indicator_label4 "X121_XICH KJ-"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrDarkSeaGreen
#property indicator_style4 STYLE_DOT
#property indicator_width4 1
//
// CHIKOUSPAN ...
//
#define chikouSpanBufferIndex 4
double chikouSpanBuffer[];
//
#property indicator_label5 "X121_XICH CS"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrDarkGreen
#property indicator_style5 STYLE_SOLID
#property indicator_width5 1
//
#define senkouABufferIndex 5
double senkouABuffer[];
//
#property indicator_label6 "X121_XICH SSA"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrLightGray
#property indicator_style6 STYLE_DASHDOTDOT
#property indicator_width6 1
//
#define senkouBBufferIndex 6
double senkouBBuffer[];
//
#property indicator_label7 "X121_XICH SSB"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrLightGray
#property indicator_style7 STYLE_DASHDOTDOT
#property indicator_width7 1
//
// KUMO ...
//
// SENKOUSPANA ...
//
#define senkouSpanABufferIndex 7
double senkouSpanABuffer[];
//
// SENKOUSPANB ...
//
#define senkouSpanBBufferIndex 8
double senkouSpanBBuffer[];
//
// KUMOCLOUD ...
//
#define kumoBufferIndex 7
//
#property indicator_label8 "X121_XICH Kumo"
#property indicator_type8 DRAW_FILLING
#property indicator_color8 clrAqua, clrMagenta
#property indicator_style8 STYLE_SOLID
#property indicator_width8 1
//
// DATA Buffers ...
//
#define dTenkanBufferIndex 9
double dTenkanBuffer[];
//
#define dKijunBufferIndex 10
double dKijunBuffer[];
//
#define dChikouBufferIndex 11
double dChikouBuffer[];
//
#define dSSABufferIndex 12
double dSSABuffer[];
//
#define dSSBBufferIndex 13
double dSSBBuffer[];
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
int maxLength;
int mHandler;
//
ENUM_SERIESMODE mTenkanSenTopMode = NULL;
ENUM_SERIESMODE mTenkanSenBottomMode = NULL;
//
ENUM_SERIESMODE mKijunSenTopMode = NULL;
ENUM_SERIESMODE mKijunSenBottomMode = NULL;
//
ENUM_SERIESMODE mSenkouSpanBTopMode = NULL;
ENUM_SERIESMODE mSenkouSpanBBottomMode = NULL;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
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 length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Define Index Buffers ...
DefineBuffers();
//
// Init Handler ...
mHandler = iIchimoku(
_Symbol,
_Period,
tenkanSenLength,
kijunSenLength,
senkouSpanBLength);
if (mHandler == INVALID_HANDLE)
{
return INIT_FAILED;
}
//
// 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
//
IndicatorRelease(mHandler);
}
//
// Calculating what we want ...
int OnCalculate(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
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);
//
// this counts Available Bars ...
int limit;
//
// Check Calculated Bars ...
int ichCalculatedBars = BarsCalculated(mHandler);
if (ichCalculatedBars < maxLength)
{
return prev_calculated;
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
int copiedTenkans = CopyBuffer(mHandler, TENKANSEN_LINE, 0, limit, dTenkanBuffer);
int copiedKijuns = CopyBuffer(mHandler, KIJUNSEN_LINE, 0, limit, dKijunBuffer);
int copiedChikous = CopyBuffer(mHandler, CHIKOUSPAN_LINE, 0, limit, dChikouBuffer);
int copiedSSAs = CopyBuffer(mHandler, SENKOUSPANA_LINE, 0, limit, dSSABuffer);
int copiedSSBs = CopyBuffer(mHandler, SENKOUSPANB_LINE, 0, limit, dSSBBuffer);
if (
copiedSSAs < 0 ||
copiedSSBs < 0 ||
copiedKijuns < 0 ||
copiedTenkans < 0 ||
copiedChikous < 0)
{
return prev_calculated;
}
//
// 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 =
//
(tenkanSenLength > 2 &&
kijunSenLength > tenkanSenLength &&
senkouSpanBLength > kijunSenLength)
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
// Ichimoku ...
result = MathMax(result, tenkanSenLength);
result = MathMax(result, kijunSenLength);
result = MathMax(result, senkouSpanBLength);
//
return result;
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// ICHIMOKU ...
//
// TENKANSEN ...
//
ENUM_DRAW_TYPE tenkanSenDrawType = showTenkanSen ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(tenkanSenBuffer, true);
SetIndexBuffer(tenkanSenBufferIndex, tenkanSenBuffer, INDICATOR_DATA);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_SHOW_DATA, showTenkanSen);
PlotIndexSetInteger(tenkanSenBufferIndex, PLOT_DRAW_TYPE, tenkanSenDrawType);
//
// KIJUNSEN ...
//
ENUM_DRAW_TYPE kijunSenDrawType = showKijunSen ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(kijunSenBuffer, true);
SetIndexBuffer(kijunSenBufferIndex, kijunSenBuffer, INDICATOR_DATA);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_SHOW_DATA, showKijunSen);
PlotIndexSetInteger(kijunSenBufferIndex, PLOT_DRAW_TYPE, kijunSenDrawType);
//
// KIJUNSEN Plus ...
//
ENUM_DRAW_TYPE kijunSenPlusDrawType = showKijunSenPlus ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(kijunSenPlusBuffer, true);
SetIndexBuffer(kijunSenPlusBufferIndex, kijunSenPlusBuffer, INDICATOR_DATA);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHIFT, kijunSenLength);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(kijunSenPlusBufferIndex, PLOT_DRAW_TYPE, kijunSenPlusDrawType);
//
// KIJUNSEN Negative ...
//
ENUM_DRAW_TYPE kijunSenNegativeDrawType = showKijunSenNegative ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(kijunSenNegativeBuffer, true);
SetIndexBuffer(kijunSenNegativeBufferIndex, kijunSenNegativeBuffer, INDICATOR_DATA);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHIFT, -kijunSenLength);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(kijunSenNegativeBufferIndex, PLOT_DRAW_TYPE, kijunSenNegativeDrawType);
//
// CHIKOUSPAN ...
//
ENUM_DRAW_TYPE chikouSpanDrawType = showChikouSpan ? DRAW_LINE : DRAW_NONE;
//
ArraySetAsSeries(chikouSpanBuffer, true);
SetIndexBuffer(chikouSpanBufferIndex, chikouSpanBuffer, INDICATOR_DATA);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHIFT, -kijunSenLength);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_SHOW_DATA, showChikouSpan);
PlotIndexSetInteger(chikouSpanBufferIndex, PLOT_DRAW_TYPE, chikouSpanDrawType);
//
// SENKOUSPAN A and B ...
int shiftSize = shiftKumo ? kijunSenLength : 0;
//
// SENKOUSPANA ...
ENUM_DRAW_TYPE senkouSpanADrawType = showSenkouSpanA ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(senkouABuffer, true);
SetIndexBuffer(senkouABufferIndex, senkouABuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouABufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(senkouABufferIndex, PLOT_SHOW_DATA, showSenkouSpanA);
PlotIndexSetInteger(senkouABufferIndex, PLOT_DRAW_TYPE, senkouSpanADrawType);
//
// SENKOUSPANB ...
ENUM_DRAW_TYPE senkouSpanBDrawType = showSenkouSpanB ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(senkouBBuffer, true);
SetIndexBuffer(senkouBBufferIndex, senkouBBuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(senkouBBufferIndex, PLOT_SHOW_DATA, showSenkouSpanB);
PlotIndexSetInteger(senkouBBufferIndex, PLOT_DRAW_TYPE, senkouSpanBDrawType);
//
// KUMO ...
//
// SENKOUSPANA ...
ArraySetAsSeries(senkouSpanABuffer, true);
SetIndexBuffer(senkouSpanABufferIndex, senkouSpanABuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouSpanABufferIndex, PLOT_DRAW_BEGIN, maxLength);
//
// SENKOUSPANB ...
ArraySetAsSeries(senkouSpanBBuffer, true);
SetIndexBuffer(senkouSpanBBufferIndex, senkouSpanBBuffer, INDICATOR_DATA);
PlotIndexSetInteger(senkouSpanBBufferIndex, PLOT_DRAW_BEGIN, maxLength);
//
// KUMO ...
//
ENUM_DRAW_TYPE kumoDrawType = showKumo ? DRAW_FILLING : DRAW_NONE;
//
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHIFT, shiftSize);
PlotIndexSetInteger(kumoBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(kumoBufferIndex, PLOT_DRAW_TYPE, kumoDrawType);
//
// DATA Buffers ...
//
// D Tenkan ...
ArraySetAsSeries(dTenkanBuffer, true);
SetIndexBuffer(dTenkanBufferIndex, dTenkanBuffer, INDICATOR_CALCULATIONS);
//
// D Kijun ...
ArraySetAsSeries(dKijunBuffer, true);
SetIndexBuffer(dKijunBufferIndex, dKijunBuffer, INDICATOR_CALCULATIONS);
//
// D Chikou ...
ArraySetAsSeries(dChikouBuffer, true);
SetIndexBuffer(dChikouBufferIndex, dChikouBuffer, INDICATOR_CALCULATIONS);
//
// D SSA ...
ArraySetAsSeries(dSSABuffer, true);
SetIndexBuffer(dSSABufferIndex, dSSABuffer, INDICATOR_CALCULATIONS);
//
// D SSB ...
ArraySetAsSeries(dSSBBuffer, true);
SetIndexBuffer(dSSBBufferIndex, dSSBBuffer, INDICATOR_CALCULATIONS);
}
//
// 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
)
{
//
// ICHIMOKU ...
//
double topValue;
double bottomValue;
//
// TENKANSEN ...
//
// Extract Tenkan Sen Top/Bottom Calculation Mode based on User Input ...
if (mTenkanSenTopMode == NULL || mTenkanSenBottomMode == NULL)
{
//
switch (tenkanSenMode)
{
//
case X_XICH_HH_LL_MODE:
//
mTenkanSenTopMode = MODE_HIGH;
mTenkanSenBottomMode = MODE_LOW;
break;
//
case X_XICH_HO_LC_MODE:
//
mTenkanSenTopMode = MODE_OPEN;
mTenkanSenBottomMode = MODE_CLOSE;
break;
}
}
//
// Calculate Top ...
topValue = GetHighestHigh(
_Symbol,
_Period,
mTenkanSenTopMode,
tenkanSenLength,
bar_index);
//
// Calculate Bottom ...
bottomValue = GetLowestLow(
_Symbol,
_Period,
mTenkanSenBottomMode,
tenkanSenLength,
bar_index);
//
double tenkanSenValue = (topValue + bottomValue) / 2;
tenkanSenBuffer[bar_index] = tenkanSenValue;
//
// KIJUNSEN ...
//
// Extract Kijun Sen Top/Bottom Calculation Mode based on User Input ...
if (mKijunSenTopMode == NULL || mKijunSenBottomMode == NULL)
{
//
switch (kijunSenMode)
{
//
case X_XICH_HH_LL_MODE:
//
mKijunSenTopMode = MODE_HIGH;
mKijunSenBottomMode = MODE_LOW;
break;
//
case X_XICH_HO_LC_MODE:
//
mKijunSenTopMode = MODE_OPEN;
mKijunSenBottomMode = MODE_CLOSE;
break;
}
}
//
// Calculate Top ...
topValue = GetHighestHigh(
_Symbol,
_Period,
mKijunSenTopMode,
kijunSenLength,
bar_index);
//
// Calculate Bottom ...
bottomValue = GetLowestLow(
_Symbol,
_Period,
mKijunSenBottomMode,
kijunSenLength,
bar_index);
//
double kijunSenValue = (topValue + bottomValue) / 2;
kijunSenBuffer[bar_index] = kijunSenValue;
//
kijunSenPlusBuffer[bar_index] = kijunSenValue;
kijunSenNegativeBuffer[bar_index] = kijunSenValue;
//
// CHIKOUSPAN ...
double chikouSpanValue = GetAppliedPrice(
bar_index,
chikuoSpanAppliedTo);
chikouSpanBuffer[bar_index] = chikouSpanValue;
//
// KUMO ...
//
// SENKOUSPANA ...
double senkouSpanAValue = (tenkanSenValue + kijunSenValue) / 2;
senkouABuffer[bar_index] = senkouSpanAValue;
senkouSpanABuffer[bar_index] = senkouSpanAValue;
//
// SENKOUSPANB ...
//
// Extract Senkou Span B Top/Bottom Calculation Mode based on User Input ...
if (mSenkouSpanBTopMode == NULL || mSenkouSpanBBottomMode == NULL)
{
//
switch (senkouSpanBMode)
{
//
case X_XICH_HH_LL_MODE:
//
mSenkouSpanBTopMode = MODE_HIGH;
mSenkouSpanBBottomMode = MODE_LOW;
break;
//
case X_XICH_HO_LC_MODE:
//
mSenkouSpanBTopMode = MODE_OPEN;
mSenkouSpanBBottomMode = MODE_CLOSE;
break;
}
}
//
// Calculate Top ...
topValue = GetHighestHigh(
_Symbol,
_Period,
mSenkouSpanBTopMode,
senkouSpanBLength,
bar_index);
//
// Calculate Bottom ...
bottomValue = GetLowestLow(
_Symbol,
_Period,
mSenkouSpanBBottomMode,
senkouSpanBLength,
bar_index);
//
double senkouSpanBValue = (topValue + bottomValue) / 2;
senkouBBuffer[bar_index] = senkouSpanBValue;
senkouSpanBBuffer[bar_index] = senkouSpanBValue;
}
//
// END Functions ...
//
@@ -0,0 +1,469 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 X121_XMC MA Cross Indicator
// ---------------------------------------------------
// Name: X121_XMC
// Description: Moving Average Crosses
// Market Analysor ...
//
//
// 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_XMC Indicator"
#property strict
//
// START Constants ...
//
//
// Indicator Short Name ...
#define ShortName "X121_XMC"
//
// END Constants ...
//
//
// START Inputs ...
//
//
input group "Fast";
input int fastMaLength = 9; // Length
input int fastMaShift = 0; // Shift
input ENUM_MA_METHOD fastMaMethod = MODE_EMA; // Method
input ENUM_APPLIED_PRICE fastMaAppliedTo = PRICE_CLOSE; // Applied To
//
input group "Slow";
input int slowMaLength = 18; // Length
input int slowMaShift = 0; // Shift
input ENUM_MA_METHOD slowMaMethod = MODE_EMA; // Method
input ENUM_APPLIED_PRICE slowMaAppliedTo = PRICE_CLOSE; // Applied To
//
input group "Verifier";
input int verifierMaLength = 50; // Length
input int verifierMaShift = 0; // Shift
input ENUM_MA_METHOD verifierMaMethod = MODE_EMA; // Method
input ENUM_APPLIED_PRICE verifierMaAppliedTo = PRICE_CLOSE; // Applied To
//
input group "Presentation";
input bool showFastMa = true; // Show Fast
input bool showSlowMa = true; // Show Slow
input bool showVerifierMa = true; // Show Verifier
//
// END Inputs ...
//
//
// START Includes and Imports ...
//
//
// Includes Logging Library ...
#include "../Libraries/x-saherelm.log.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 3
#property indicator_plots 3
//
// PLOTTED Buffers ...
//
// MA ...
//
// FAST ...
#define fastMaBufferIndex 0
double fastMaBuffer[];
//
#property indicator_label1 "X121_XMC MA F"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//
// SLOW ...
#define slowMaBufferIndex 1
double slowMaBuffer[];
//
#property indicator_label2 "X121_XMC MA S"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrDarkOrange
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//
// VERIFIER ...
#define verifierMaBufferIndex 2
double verifierMaBuffer[];
//
#property indicator_label3 "X121_XMC MA V"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrDarkBlue
#property indicator_style3 STYLE_SOLID
#property indicator_width3 2
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
int maxLength;
//
int fastMaHandler = INVALID_HANDLE;
int slowMaHandler = INVALID_HANDLE;
int verifierMaHandler = INVALID_HANDLE;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
logTag = 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();
//
// MA Initialization ...
//
// FAST ...
fastMaHandler = iMA(
_Symbol,
_Period,
fastMaLength,
fastMaShift,
fastMaMethod,
fastMaAppliedTo);
if (fastMaHandler == INVALID_HANDLE)
{
//
string msg = "Error in Initilizing Indicator ...";
LogMessage(msg);
//
return INIT_FAILED;
}
//
// SLOW ...
slowMaHandler = iMA(
_Symbol,
_Period,
slowMaLength,
slowMaShift,
slowMaMethod,
slowMaAppliedTo);
if (slowMaHandler == INVALID_HANDLE)
{
//
string msg = "Error in Initilizing Indicator ...";
LogMessage(msg);
//
return INIT_FAILED;
}
//
// VERIFIER ...
verifierMaHandler = iMA(
_Symbol,
_Period,
verifierMaLength,
verifierMaShift,
verifierMaMethod,
verifierMaAppliedTo);
if (verifierMaHandler == INVALID_HANDLE)
{
//
string msg = "Error in Initilizing Indicator ...";
LogMessage(msg);
//
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
//
// Here we can handle De Initialization Reasons ...
IndicatorRelease(fastMaHandler);
IndicatorRelease(slowMaHandler);
IndicatorRelease(verifierMaHandler);
}
//
// Calculations ...
//
// Calculating what we want ...
int OnCalculate(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
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);
//
// this counts Available Bars ...
int limit;
//
// Check Calculated Bars ...
int fastMaCalculatedBars = BarsCalculated(fastMaHandler);
int slowMaCalculatedBars = BarsCalculated(slowMaHandler);
int verifierMaCalculatedBars = BarsCalculated(verifierMaHandler);
if (fastMaCalculatedBars < maxLength ||
slowMaCalculatedBars < maxLength ||
verifierMaCalculatedBars < maxLength)
{
return prev_calculated;
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
int copiedFastMas = CopyBuffer(fastMaHandler, 0, 0, limit, fastMaBuffer);
int copiedSlowMas = CopyBuffer(slowMaHandler, 0, 0, limit, slowMaBuffer);
int copiedVerifierMas = CopyBuffer(verifierMaHandler, 0, 0, limit, verifierMaBuffer);
if (copiedFastMas <= 0 ||
copiedSlowMas <= 0 ||
copiedVerifierMas <= 0
)
{
return prev_calculated;
}
//
// 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 =
//
// Validate Ma ...
(fastMaLength > 2 &&
slowMaLength > fastMaLength &&
verifierMaLength > slowMaLength)
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
// Ma ...
result = MathMax(result, fastMaLength);
result = MathMax(result, slowMaLength);
result = MathMax(result, verifierMaLength);
//
return result;
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// MA ...
//
// FAST ...
ENUM_DRAW_TYPE fastMaDrawType = showFastMa ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(fastMaBuffer, true);
SetIndexBuffer(fastMaBufferIndex, fastMaBuffer, INDICATOR_DATA);
PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(fastMaBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(fastMaBufferIndex, PLOT_DRAW_TYPE, fastMaDrawType);
//
// SLOW ...
ENUM_DRAW_TYPE slowMaDrawType = showSlowMa ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(slowMaBuffer, true);
SetIndexBuffer(slowMaBufferIndex, slowMaBuffer, INDICATOR_DATA);
PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(slowMaBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(slowMaBufferIndex, PLOT_DRAW_TYPE, slowMaDrawType);
//
// VERIFIER ...
ENUM_DRAW_TYPE verifierMaDrawType = showVerifierMa ? DRAW_LINE : DRAW_NONE;
ArraySetAsSeries(verifierMaBuffer, true);
SetIndexBuffer(verifierMaBufferIndex, verifierMaBuffer, INDICATOR_DATA);
PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_BEGIN, maxLength);
PlotIndexSetInteger(verifierMaBufferIndex, PLOT_SHOW_DATA, false);
PlotIndexSetInteger(verifierMaBufferIndex, PLOT_DRAW_TYPE, verifierMaDrawType);
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
//
string indicatorShortName = "";
StringConcatenate(indicatorShortName, ShortName, "");
//
IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
}
//
// Calculate Buffers ...
void CalculateBuffers(
int bar_index // Selected Bar Index
)
{
}
//
// END Functions ...
//
@@ -0,0 +1,721 @@
//////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// ---------------------------------------------
// Name: X121_XOSC
// Description: provides some oscillator values
// as empty 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_XAMA Indicator"
#property strict
//
// START Constants ...
//
#define ShortName "X121_XOSC"
//
// END Constants ...
//
//
// START Inputs ...
//
//
// ATR ...
input group "ATR";
input int atrLength = 14; // Length
//
// RVI ...
// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE.
input group "RVI";
input int rviLength = 10; // Length
//
// BULLPOWER ...
input group "Bulls Power";
input int bullpLength = 13; // Length
//
// BEARPOWER ...
input group "Bears Power";
input int bearpLength = 13; // Length
//
// VOLUME ...
input group "Volumes";
input ENUM_APPLIED_VOLUME volumeAppliedTo = VOLUME_TICK; // Applied To
//
// RSI ...
input group "RSI";
input int rsiLength = 14; // Length
input ENUM_APPLIED_PRICE rsiAppliedTo = PRICE_CLOSE; // Applied To
//
// CCI ...
input group "CCI";
input int cciLength = 14; // Length
input ENUM_APPLIED_PRICE cciAppliedTo = PRICE_TYPICAL; // Applied To
//
// STDDEV ...
input group "Standard Deviation";
input int stddevLength = 20; // Length
input int stddevShift = 0; // Shift
input ENUM_MA_METHOD stddevMethod = MODE_SMA; // Mode
input ENUM_APPLIED_PRICE stddevAppliedTo = PRICE_CLOSE; // AppliedTo
//
// MOMENTUM ...
input group "Momentum";
input int momentumLength = 14; // Length
input ENUM_APPLIED_PRICE momentumAppliedTo = PRICE_CLOSE; // Applied To
//
// SAR ...
input group "SAR";
input double sarStep = 0.02; // Step
input double sarMaximum = 0.2; // Maximum
//
// MACD ...
// The buffer numbers are the following: 0 - MAIN_LINE, 1 - SIGNAL_LINE.
input group "MACD";
input int macdFastLength = 12; // Fast Length
input int macdSlowLength = 26; // Slow Length
input int macdSignaLength = 9; // Signal Length
input ENUM_APPLIED_PRICE macdAppliedTo = PRICE_CLOSE; // Applied To
//
// STOCHASTIC ...
// The buffer numbers: 0 - MAIN_LINE, 1 - SIGNAL_LINE.
input group "Stochastic";
input int stochKLength = 5; // K Length
input int stochDLength = 3; // D Length
input int stochSlowing = 3; // Slowing
input ENUM_MA_METHOD stochMaMethod = MODE_SMA; // Ma Method
input ENUM_STO_PRICE stochMode = STO_LOWHIGH; // Calculation Mode
//
// END Inputs ...
//
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// START Buffers ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 15
#property indicator_plots 0
//
// ATR ...
#define atrBufferIndex 0
double atrBuffer[];
//
// RVI ...
#define rviMainBufferIndex 1
#define rviSignalBufferIndex 2
double rviMainBuffer[];
double rviSignalBuffer[];
//
// BULLPOWER ...
#define bullPBufferIndex 3
double bullPBuffer[];
//
// BEARPOWER ...
#define bearPBufferIndex 4
double bearPBuffer[];
//
// VOLUME ...
#define volumeBufferIndex 5
double volumeBuffer[];
//
// RSI ...
#define rsiBufferIndex 6
double rsiBuffer[];
//
// CCI ...
#define cciBufferIndex 7
double cciBuffer[];
//
// MOMENTUM ...
#define momentumBufferIndex 8
double momentumBuffer[];
//
// SAR ...
#define sarBufferIndex 9
double sarBuffer[];
//
// MACD ...
#define macdMainBufferIndex 10
#define macdSignalBufferIndex 11
double macdMainBuffer[];
double macdSignalBuffer[];
//
// STOCHASTIC ...
#define stochMainBufferIndex 12
#define stochSignalBufferIndex 13
double stochMainBuffer[];
double stochSignalBuffer[];
//
// STANDARDDEVIATION ...
#define stddevBufferIndex 14
double stddevBuffer[];
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
int maxLength;
//
int atrHandler = INVALID_HANDLE;
int rviHandler = INVALID_HANDLE;
int bullPHandler = INVALID_HANDLE;
int bearPHandler = INVALID_HANDLE;
int volumeHandler = INVALID_HANDLE;
int rsiHandler = INVALID_HANDLE;
int cciHandler = INVALID_HANDLE;
int momentumHandler = INVALID_HANDLE;
int sarHandler = INVALID_HANDLE;
int macdHandler = INVALID_HANDLE;
int stochHandler = INVALID_HANDLE;
int stddevHandler = INVALID_HANDLE;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
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 length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
// Initializing Handlers ...
//
// ATR ...
atrHandler = iATR(
_Symbol,
_Period,
atrLength);
//
// RVI ...
rviHandler = iRVI(
_Symbol,
_Period,
rviLength);
//
// BULLSPOWER ...
bullPHandler = iBullsPower(
_Symbol,
_Period,
bullpLength);
//
// BEARSPOWER ...
bearPHandler = iBearsPower(
_Symbol,
_Period,
bullpLength);
//
// VOLUMES ...
volumeHandler = iVolumes(
_Symbol,
_Period,
volumeAppliedTo);
//
// RSI ...
rsiHandler = iRSI(
_Symbol,
_Period,
rsiLength,
rsiAppliedTo);
//
// CCI ...
cciHandler = iCCI(
_Symbol,
_Period,
cciLength,
cciAppliedTo);
//
// MOMENTUM ...
momentumHandler = iMomentum(
_Symbol,
_Period,
momentumLength,
momentumAppliedTo);
//
// SAR ...
sarHandler = iSAR(
_Symbol,
_Period,
sarStep,
sarMaximum);
//
// MACD ...
macdHandler = iMACD(
_Symbol,
_Period,
macdFastLength,
macdSlowLength,
macdSignaLength,
macdAppliedTo);
//
// STOCHASTIC ...
stochHandler = iStochastic(
_Symbol,
_Period,
stochKLength,
stochDLength,
stochSlowing,
stochMaMethod,
stochMode);
//
// STANDARDDEVIATION ...
stddevHandler = iStdDev(
_Symbol,
_Period,
stddevLength,
stddevShift,
stddevMethod,
stddevAppliedTo);
//
bool isAllHandlersInit =
//
atrHandler != INVALID_HANDLE &&
rviHandler != INVALID_HANDLE &&
bullPHandler != INVALID_HANDLE &&
bearPHandler != INVALID_HANDLE &&
volumeHandler != INVALID_HANDLE &&
rsiHandler != INVALID_HANDLE &&
cciHandler != INVALID_HANDLE &&
momentumHandler != INVALID_HANDLE &&
sarHandler != INVALID_HANDLE &&
macdHandler != INVALID_HANDLE &&
stochHandler != INVALID_HANDLE &&
stddevHandler != INVALID_HANDLE
//
;
if (!isAllHandlersInit)
{
return INIT_FAILED;
}
//
// Define Index Buffers ...
DefineBuffers();
//
// 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
//
// Here we can handle De Initialization Reasons ...
IndicatorRelease(atrHandler);
IndicatorRelease(rviHandler);
IndicatorRelease(bullPHandler);
IndicatorRelease(bearPHandler);
IndicatorRelease(volumeHandler);
IndicatorRelease(rsiHandler);
IndicatorRelease(cciHandler);
IndicatorRelease(momentumHandler);
IndicatorRelease(sarHandler);
IndicatorRelease(macdHandler);
IndicatorRelease(stochHandler);
IndicatorRelease(stddevHandler);
}
//
// Calculating what we want ...
int OnCalculate(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
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);
//
// this counts Available Bars ...
int limit;
//
// Check Calculated Bars ...
int atrCalculatedBars = BarsCalculated(atrHandler);
int rviCalculatedBars = BarsCalculated(rviHandler);
int bullPCalculatedBars = BarsCalculated(bullPHandler);
int bearPCalculatedBars = BarsCalculated(bearPHandler);
int volumeCalculatedBars = BarsCalculated(volumeHandler);
int rsiCalculatedBars = BarsCalculated(rsiHandler);
int cciCalculatedBars = BarsCalculated(cciHandler);
int momentumCalculatedBars = BarsCalculated(momentumHandler);
int sarCalculatedBars = BarsCalculated(sarHandler);
int macdCalculatedBars = BarsCalculated(macdHandler);
int stochCalculatedBars = BarsCalculated(stochHandler);
int stddevCalculatedBars = BarsCalculated(stddevHandler);
//
bool isCalculatedBarsPassed =
//
atrCalculatedBars >= maxLength &&
rviCalculatedBars >= maxLength &&
bullPCalculatedBars >= maxLength &&
bearPCalculatedBars >= maxLength &&
volumeCalculatedBars >= maxLength &&
rsiCalculatedBars >= maxLength &&
cciCalculatedBars >= maxLength &&
momentumCalculatedBars >= maxLength &&
sarCalculatedBars >= maxLength &&
macdCalculatedBars >= maxLength &&
stochCalculatedBars >= maxLength &&
stddevCalculatedBars >= maxLength
//
;
if (!isCalculatedBarsPassed)
{
return prev_calculated;
}
//
limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1;
//
// Buffers Copy ...
int atrCopiedItems = CopyBuffer(atrHandler, 0, 0, limit, atrBuffer);
int rviMainCopiedItems = CopyBuffer(rviHandler, MAIN_LINE, 0, limit, rviMainBuffer);
int rviSignalCopiedItems = CopyBuffer(rviHandler, SIGNAL_LINE, 0, limit, rviSignalBuffer);
int bullPCopiedItems = CopyBuffer(bullPHandler, 0, 0, limit, bullPBuffer);
int bearPCopiedItems = CopyBuffer(bearPHandler, 0, 0, limit, bearPBuffer);
int volumeCopiedItems = CopyBuffer(volumeHandler, 0, 0, limit, volumeBuffer);
int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer);
int cciCopiedItems = CopyBuffer(cciHandler, 0, 0, limit, cciBuffer);
int momentumCopiedItems = CopyBuffer(momentumHandler, 0, 0, limit, momentumBuffer);
int sarCopiedItems = CopyBuffer(sarHandler, 0, 0, limit, sarBuffer);
int macdMainCopiedItems = CopyBuffer(macdHandler, MAIN_LINE, 0, limit, macdMainBuffer);
int macdSignalCopiedItems = CopyBuffer(macdHandler, SIGNAL_LINE, 0, limit, macdSignalBuffer);
int stochMainCopiedItems = CopyBuffer(stochHandler, MAIN_LINE, 0, limit, stochMainBuffer);
int stocSignalhCopiedItems = CopyBuffer(stochHandler, SIGNAL_LINE, 0, limit, stochSignalBuffer);
int stddevCopiedItems = CopyBuffer(stddevHandler, 0, 0, limit, stddevBuffer);
//
bool isCopiedBarsPassed =
//
atrCopiedItems > 0 &&
rviMainCopiedItems > 0 &&
rviSignalCopiedItems > 0 &&
bullPCopiedItems > 0 &&
bearPCopiedItems > 0 &&
volumeCopiedItems > 0 &&
rsiCopiedItems > 0 &&
cciCopiedItems > 0 &&
momentumCopiedItems > 0 &&
sarCopiedItems > 0 &&
macdMainCopiedItems > 0 &&
macdSignalCopiedItems > 0 &&
stochMainCopiedItems > 0 &&
stocSignalhCopiedItems > 0 &&
stddevCopiedItems > 0
//
;
if (!isCopiedBarsPassed)
{
return prev_calculated;
}
//
// Main Loop ...
for (int i = limit - 1; i >= 0 && !IsStopped(); i--)
{
//
// Do Buffers Calculation ...
// HERE We Do Not anything ...
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = false;
//
// Validate Args ...
result =
//
atrLength >= 2 &&
rviLength >= 2 &&
bullpLength >= 2 &&
bearpLength >= 2 &&
rsiLength >= 2 &&
cciLength >= 2 &&
momentumLength >= 2 &&
sarStep > 0 &&
sarStep < sarMaximum &&
macdFastLength >= 2 &&
macdSlowLength > macdFastLength &&
macdSignaLength >= 2 &&
stochKLength >= 2 &&
stochDLength >= 2 &&
stochSlowing >= 2 &&
stddevLength >= 2 &&
stddevShift >= 0
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = MathMax(atrLength, rviLength);
result = MathMax(result, bullpLength);
result = MathMax(result, bearpLength);
result = MathMax(result, rsiLength);
result = MathMax(result, cciLength);
result = MathMax(result, momentumLength);
result = MathMax(result, macdFastLength);
result = MathMax(result, macdSlowLength);
result = MathMax(result, macdSignaLength);
result = MathMax(result, stochKLength);
result = MathMax(result, stochDLength);
result = MathMax(result, stochSlowing);
result = MathMax(result, stddevLength);
//
return result;
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// DATA Buffers ...
//
// ATR ...
ArraySetAsSeries(atrBuffer, true);
SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS);
//
// RVI ...
//
// Main ...
ArraySetAsSeries(rviMainBuffer, true);
SetIndexBuffer(rviMainBufferIndex, rviMainBuffer, INDICATOR_CALCULATIONS);
//
// Signal ...
ArraySetAsSeries(rviSignalBuffer, true);
SetIndexBuffer(rviSignalBufferIndex, rviSignalBuffer, INDICATOR_CALCULATIONS);
//
// BULLPOWER ...
ArraySetAsSeries(bullPBuffer, true);
SetIndexBuffer(bullPBufferIndex, bullPBuffer, INDICATOR_CALCULATIONS);
//
// BEARPOWER ...
ArraySetAsSeries(bearPBuffer, true);
SetIndexBuffer(bearPBufferIndex, bearPBuffer, INDICATOR_CALCULATIONS);
//
// VOLUME ...
ArraySetAsSeries(volumeBuffer, true);
SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS);
//
// RSI ...
ArraySetAsSeries(rsiBuffer, true);
SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_CALCULATIONS);
//
// CCI ...
ArraySetAsSeries(cciBuffer, true);
SetIndexBuffer(cciBufferIndex, cciBuffer, INDICATOR_CALCULATIONS);
//
// MOMENTUM ...
ArraySetAsSeries(momentumBuffer, true);
SetIndexBuffer(momentumBufferIndex, momentumBuffer, INDICATOR_CALCULATIONS);
//
// SAR ...
ArraySetAsSeries(sarBuffer, true);
SetIndexBuffer(sarBufferIndex, sarBuffer, INDICATOR_CALCULATIONS);
//
// STANDARDDEVIATION ...
ArraySetAsSeries(stddevBuffer, true);
SetIndexBuffer(stddevBufferIndex, stddevBuffer, INDICATOR_CALCULATIONS);
//
// MACD ...
//
// Main ...
ArraySetAsSeries(macdMainBuffer, true);
SetIndexBuffer(macdMainBufferIndex, macdMainBuffer, INDICATOR_CALCULATIONS);
//
// Signal ...
ArraySetAsSeries(macdSignalBuffer, true);
SetIndexBuffer(macdSignalBufferIndex, macdSignalBuffer, INDICATOR_CALCULATIONS);
}
//
// END Functions ...
//
@@ -0,0 +1,580 @@
//////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// ---------------------------------------------
// Name: X121_XSTR
// Description: Super Trend 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_XAMA Indicator"
#property strict
//
// START Constants ...
//
#define ShortName "X121_XSTR"
//
// END Constants ...
//
//
// START Inputs ...
//
//
// Market ...
input group "ATR";
input int atrLength = 14; // Length
input double atrMultiplier = 3.0; // Multiplier
input ENUM_APPLIED_PRICE atrAppliedTo = PRICE_MEDIAN; // Applied To
//
// Presentation ...
input group "Presentation";
input bool showTrends = true; // Show Trends
input bool fillTrends = true; // Fill Trends
//
// END Inputs ...
//
//
// Includes Common Library ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// START Buffers ...
//
//
#property indicator_chart_window
//
#property indicator_buffers 9
#property indicator_plots 2
//
#define fillUpBufferIndex 0
double fillUpBuffer[];
#define fillDownBufferIndex 1
double fillDownBuffer[];
//
#define fillingPlotBufferIndex 0
//
#property indicator_label1 "X121_XSTR Filling"
#property indicator_type1 DRAW_FILLING
#property indicator_color1 clrBisque, clrPaleGreen
//
#define mainBufferIndex 2
#define mainPlotBufferIndex 1
double mainBuffer[];
//
#define mainColorBufferIndex 3
double mainColorBuffer[];
//
#property indicator_label2 "X121_XSTR"
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed
#property indicator_style2 STYLE_DOT
//
// DATA Buffers ...
//
#define atrBufferIndex 4
double atrBuffer[];
//
#define trendBufferIndex 5
double trendBuffer[];
//
#define upBufferIndex 6
double upBuffer[];
//
#define downBufferIndex 7
double downBuffer[];
//
#define priceBufferIndex 8
double priceBuffer[];
//
// END Buffers ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
int maxLength;
//
int atrHandler = INVALID_HANDLE;
//
int changeOfTrend;
int startBearishTrend;
int startBullishTrend;
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Event Handlers ...
//
//
// Initialization ...
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 length, here we get max Input length
// and then wait until pass it ...
maxLength = ExtractMaxLengthOfInputs();
//
atrHandler = iATR(
_Symbol,
_Period,
atrLength);
if (atrHandler == INVALID_HANDLE)
{
return INIT_FAILED;
}
//
// Define Index Buffers ...
DefineBuffers();
//
// 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
//
// Here we can handle De Initialization Reasons ...
IndicatorRelease(atrHandler);
}
//
// Calculating what we want ...
int OnCalculate(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
const int &spread[])
{
//
int numOfRequiredAtrs;
if (prev_calculated > rates_total || prev_calculated < 0)
{
numOfRequiredAtrs = rates_total;
}
else
{
//
numOfRequiredAtrs = rates_total - prev_calculated;
if (prev_calculated > 0)
{
numOfRequiredAtrs++;
}
}
//
// Checking for stop ...
if (IsStopped())
{
return 0;
}
//
// Check Number of items Copy or not ...
int copiedATRs = CopyBuffer(atrHandler, 0, 0, numOfRequiredAtrs, atrBuffer);
if (copiedATRs <= 0)
{
return 0;
}
//
int limit;
//
// checking for the limit start of calculation of an indicator ...
if (prev_calculated > rates_total || prev_calculated <= 0)
{
//
// starting index for calculation of all bars ...
limit = maxLength;
}
else
{
//
// starting number for calculation of new bars
limit = prev_calculated - 1;
}
//
// Main Loop ...
for (int i = limit; i < rates_total && !IsStopped(); i++)
{
//
// Calculated Price ...
double price = getPrice(
atrAppliedTo,
open,
high,
low,
close,
i);
// price = (high[i] + low[i]) / 2;
priceBuffer[i] = price;
//
double atr = atrBuffer[i];
//
// Up ...
upBuffer[i] = price + (atrMultiplier * atr);
//
// Down ...
downBuffer[i] = price - (atrMultiplier * atr);
//
if (close[i] > upBuffer[i - 1])
{
//
trendBuffer[i] = 1;
if (trendBuffer[i - 1] == -1)
{
changeOfTrend = 1;
}
}
else if (close[i] < downBuffer[i - 1])
{
//
trendBuffer[i] = -1;
if (trendBuffer[i - 1] == 1)
{
changeOfTrend = 1;
}
}
else if (trendBuffer[i - 1] == 1)
{
//
trendBuffer[i] = 1;
changeOfTrend = 0;
}
else if (trendBuffer[i - 1] == -1)
{
//
trendBuffer[i] = -1;
changeOfTrend = 0;
}
//
// Down Trend Starting ...
if (trendBuffer[i] < 0 && trendBuffer[i - 1] > 0)
{
startBearishTrend = 1;
}
else
{
startBearishTrend = 0;
}
//
// Up Trend Starting ...
if (trendBuffer[i] > 0 && trendBuffer[i - 1] < 0)
{
startBullishTrend = 1;
}
else
{
startBullishTrend = 0;
}
//
if (trendBuffer[i] > 0 && downBuffer[i] < downBuffer[i - 1])
{
downBuffer[i] = downBuffer[i - 1];
}
//
if (trendBuffer[i] < 0 && upBuffer[i] > upBuffer[i - 1])
{
upBuffer[i] = upBuffer[i - 1];
}
//
if (startBearishTrend == 1)
{
upBuffer[i] = priceBuffer[i] + (atrMultiplier * atr);
}
//
if (startBullishTrend == 1)
{
downBuffer[i] = priceBuffer[i] - (atrMultiplier * atr);
}
//
// Draw the indicator ...
//
double colorIDX = 0;
mainColorBuffer[i] = colorIDX;
//
if (trendBuffer[i] == 1)
{
//
mainBuffer[i] = downBuffer[i];
if (changeOfTrend == 1)
{
mainBuffer[i - 1] = mainBuffer[i - 2];
changeOfTrend = 0;
}
//
colorIDX = 1;
}
else if (trendBuffer[i] == -1)
{
//
mainBuffer[i] = upBuffer[i];
if (changeOfTrend == 1)
{
//
mainBuffer[i - 1] = mainBuffer[i - 2];
changeOfTrend = 0;
}
//
colorIDX = 2;
}
//
if (showTrends)
{
mainColorBuffer[i] = colorIDX;
}
//
// Filling ...
if (fillTrends)
{
//
fillUpBuffer[i] = mainBuffer[i];
fillDownBuffer[i] = close[i];
}
else
{
//
fillUpBuffer[i] = EMPTY_VALUE;
fillDownBuffer[i] = EMPTY_VALUE;
}
}
//
return rates_total;
}
//
// END Event Handlers ...
//
//
// START Functions ...
//
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = false;
//
// Validate Args ...
result =
//
atrLength >= 2
//
;
//
return result;
}
//
// Retrieve all Exists Input Max Length ...
// use for Start Of Drawing ...
int ExtractMaxLengthOfInputs()
{
//
int result = 0;
//
result = atrLength;
//
return result;
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// PLOT Buffers ...
//
// FILLINGS ...
SetIndexBuffer(fillUpBufferIndex, fillUpBuffer, INDICATOR_DATA);
SetIndexBuffer(fillDownBufferIndex, fillDownBuffer, INDICATOR_DATA);
PlotIndexSetInteger(fillingPlotBufferIndex, PLOT_SHOW_DATA, false);
//
// MAIN ...
SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA);
PlotIndexSetInteger(mainPlotBufferIndex, PLOT_SHOW_DATA, showTrends);
SetIndexBuffer(mainColorBufferIndex, mainColorBuffer, INDICATOR_COLOR_INDEX);
//
// DATA Buffers ...
//
// ATR ...
SetIndexBuffer(atrBufferIndex, atrBuffer, INDICATOR_CALCULATIONS);
//
// TREND ...
SetIndexBuffer(trendBufferIndex, trendBuffer, INDICATOR_CALCULATIONS);
//
// UP ...
SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS);
//
// DOWN ...
SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS);
//
// PRICE ...
SetIndexBuffer(priceBufferIndex, priceBuffer, INDICATOR_CALCULATIONS);
}
//
// END Functions ...
//
//
// TEMPLATE Function ...
template <typename T>
double getPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i)
{
switch (tprice)
{
case PRICE_CLOSE:
return (close[i]);
case PRICE_OPEN:
return (open[i]);
case PRICE_HIGH:
return (high[i]);
case PRICE_LOW:
return (low[i]);
case PRICE_MEDIAN:
return ((high[i] + low[i]) / 2.0);
case PRICE_TYPICAL:
return ((high[i] + low[i] + close[i]) / 3.0);
case PRICE_WEIGHTED:
return ((high[i] + low[i] + close[i] + close[i]) / 4.0);
}
return (0);
}
@@ -0,0 +1,757 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Indicator
// ---------------------------------------------
// Name: X121_XZG
// Description: Zogzag Implementation ...
//
//
// 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_XZG Indicator"
#property strict
//
#define ShortName "X121_XZG"
//
// DEFINITIONS ...
enum ENUM_X_ZG_SEARCH_MODE
{
X_ZG_SEARCH_EXTREMUM = 0, // searching for the first extremum
X_ZG_SEARCH_PEAK = 1, // searching for the next ZigZag peak
X_ZG_SEARCH_VALE = -1 // searching for the next ZigZag vale
};
//
// How to Calculate Up and Down Price ...
enum ENUM_X_ZG_PRICE_MODE
{
//
X_ZG_PRICE_HIGH_LOW_MODE = 1,
X_ZG_PRICE_OPEN_CLOSE_MODE = 2,
};
//
// INPUT ...
//
input int depth = 12; // Depth
input int deviation = 5; // Deviation
input int backStep = 3; // Back Step
input ENUM_X_ZG_PRICE_MODE mode = X_ZG_PRICE_HIGH_LOW_MODE; // Mode
//
// BUFFERS ...
//
#property indicator_chart_window
//
#property indicator_buffers 5
#property indicator_plots 3
//
// ZigZag ...
//
#define mainBufferIndex 0
#define mainBufferPlotIndex 0
double mainBuffer[];
//
#property indicator_label1 "X121_XZG Main"
#property indicator_type1 DRAW_SECTION
#property indicator_color1 clrYellow
#property indicator_width1 2
//
// Highs ...
//
// ZigZag Pointer or Line Indicator ...
#define arrowBufferIndex 1
#define arrowBufferPlotIndex 1
double arrowBuffer[];
//
#define arrowColorBufferIndex 2
double arrowColorBuffer[];
//
#property indicator_label2 "X121_XZG PV"
#property indicator_type2 DRAW_COLOR_ARROW
#property indicator_color2 clrAqua, clrMagenta
#property indicator_width2 1
//
#define highsBufferIndex 3
double highsBuffer[];
//
// Lows ...
//
#define lowsBufferIndex 4
double lowsBuffer[];
//
// VARIABLES ...
//
int mRecalc = 3; // Number of last extremes for recalculation
//
// EVENT Handlers ...
//
// Initialization ...
int OnInit()
{
//
// Validate Inputs ...
if (!ValidateInputs())
{
return INIT_PARAMETERS_INCORRECT;
}
//
// logTag = ShortName;
//
// Define Index Buffers ...
DefineBuffers();
//
// 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
}
//
// Calculating what we want ...
int OnCalculate(
//
// total Candles on chart ...
const int rates_total,
//
// total calculated Candles on charts ...
const int prev_calculated,
//
// history of Candles Open Time ...
const datetime &time[],
//
// history of Candles Open Price ...
const double &open[],
//
// history of Candles High Price ...
const double &high[],
//
// history of Candles Low Price ...
const double &low[],
//
// history of Candles Close Price ...
const double &close[],
//
// history of Tick Volumes on Candle ...
const long &tick_volume[],
//
// history of Trade Volumes ...
const long &volume[],
//
// history of Candles Spread Price ...
const int &spread[] //
)
{
//
double mZGHigh[];
double mZGLow[];
if (mode == X_ZG_PRICE_OPEN_CLOSE_MODE)
{
//
ArrayCopy(
mZGHigh,
open
//
);
//
ArrayCopy(
mZGLow,
close
//
);
}
else
{
//
ArrayCopy(
mZGHigh,
high
//
);
//
ArrayCopy(
mZGLow,
low
//
);
}
//
int zigZagResult = CalcukateZigZag(
prev_calculated,
rates_total,
mZGHigh,
mZGLow
//
);
//
if (zigZagResult != rates_total)
{
return zigZagResult;
}
//
return rates_total;
}
//
// CUSTOM Functions ...
//
// Validate Input Args for Initialization ...
bool ValidateInputs()
{
//
bool result = false;
//
result =
//
depth > 0 &&
deviation > 0 &&
backStep > 0
//
;
//
return result;
}
//
// Define Indexes and Styles ...
void DefineBuffers()
{
//
// Main ...
//
SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(mainBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(mainBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetDouble(mainBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Arrow ...
//
SetIndexBuffer(arrowBufferIndex, arrowBuffer, INDICATOR_DATA);
//
PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_SHOW_DATA, true);
PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_DRAW_BEGIN, 0);
PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW, 159);
PlotIndexSetInteger(arrowBufferPlotIndex, PLOT_ARROW_SHIFT, 0);
PlotIndexSetDouble(arrowBufferPlotIndex, PLOT_EMPTY_VALUE, 0);
//
// Arrow Color ...
SetIndexBuffer(arrowColorBufferIndex, arrowColorBuffer, INDICATOR_COLOR_INDEX);
//
// Highs ...
SetIndexBuffer(highsBufferIndex, highsBuffer, INDICATOR_CALCULATIONS);
//
// Lows ...
SetIndexBuffer(lowsBufferIndex, lowsBuffer, INDICATOR_CALCULATIONS);
}
//
// Set Indicator Short Name and also we can define Buffers Labels ...
void SetIndicatorName()
{
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
}
//
// Calculating Zig Zag ...
int CalcukateZigZag(
const int prev_calculated,
const int rates_total,
double &high[],
double &low[]
//
)
{
//
if (rates_total < 100)
{
return 0;
}
//
// Define Variables ...
int i = 0;
//
int start = 0;
int extreme_counter = 0;
int extreme_search = X_ZG_SEARCH_EXTREMUM;
int shift = 0;
int back = 0;
int last_high_pos = 0;
int last_low_pos = 0;
//
double val = 0;
double res = 0;
double curlow = 0;
double curhigh = 0;
double last_high = 0;
double last_low = 0;
//
double colorIDX = 0;
double lastZigZagValue = 0;
//
// Initializing ...
if (prev_calculated == 0)
{
//
ArrayInitialize(mainBuffer, 0);
ArrayInitialize(highsBuffer, 0);
ArrayInitialize(lowsBuffer, 0);
//
start = depth;
}
//
// Already Calculated Before ...
if (prev_calculated > 0)
{
//
i = rates_total - 1;
//
// Searching for the third X_ZG_SEARCH_EXTREMUM from the last UnComplete Bar ...
while (extreme_counter < mRecalc && i > rates_total - 100)
{
//
res = mainBuffer[i];
if (res != 0)
{
extreme_counter++;
}
//
i--;
}
//
i++;
start = i;
//
// What type of X_ZG_SEARCH_EXTREMUM we Search for ...
if (lowsBuffer[i] != 0)
{
//
curlow = lowsBuffer[i];
extreme_search = X_ZG_SEARCH_PEAK;
}
else
{
//
curhigh = highsBuffer[i];
extreme_search = X_ZG_SEARCH_VALE;
}
//
// Clear Values ...
for (i = start + 1; i < rates_total && !IsStopped(); i++)
{
//
mainBuffer[i] = 0;
lowsBuffer[i] = 0;
highsBuffer[i] = 0;
}
}
//
// Search for High and Low Extremes ...
for (shift = start; shift < rates_total && !IsStopped(); shift++)
{
//
// Low ...
val = low[Lowest(low, depth, shift)];
if (val == last_low)
{
val = 0;
}
else
{
//
last_low = val;
//
if ((low[shift] - val) > deviation * _Point)
{
val = 0;
}
else
{
//
for (back = 1; back <= backStep; back++)
{
//
res = lowsBuffer[shift - back];
if ((res != 0) && (res > val))
{
lowsBuffer[shift - back] = 0;
}
}
}
}
//
if (low[shift] == val)
{
lowsBuffer[shift] = val;
}
else
{
lowsBuffer[shift] = 0;
}
//
// High ...
val = high[Highest(high, depth, shift)];
if (val == last_high)
{
val = 0;
}
else
{
//
last_high = val;
//
if ((val - high[shift]) > deviation * _Point)
{
val = 0;
}
else
{
//
for (back = 1; back <= backStep; back++)
{
//
res = highsBuffer[shift - back];
if ((res != 0) && (res < val))
{
highsBuffer[shift - back] = 0;
}
}
}
}
//
if (high[shift] == val)
{
highsBuffer[shift] = val;
}
else
{
highsBuffer[shift] = 0;
}
}
//
// Set Last Value ...
if (extreme_search == 0) // Undefined Values ...
{
//
last_low = 0;
last_high = 0;
}
else
{
//
last_low = curlow;
last_high = curhigh;
}
//
// Final Selection of Extreme Points for ZigZag ...
for (shift = start; shift < rates_total && !IsStopped(); shift++)
{
//
res = 0;
//
switch (extreme_search)
{
//
case X_ZG_SEARCH_EXTREMUM:
//
if (last_low == 0 && last_high == 0)
{
//
if (highsBuffer[shift] != 0)
{
//
last_high_pos = shift;
last_high = high[shift];
//
extreme_search = X_ZG_SEARCH_VALE;
//
mainBuffer[shift] = last_high;
//
res = 1;
}
//
if (lowsBuffer[shift] != 0)
{
//
last_low_pos = shift;
last_low = low[shift];
//
extreme_search = X_ZG_SEARCH_PEAK;
//
mainBuffer[shift] = last_low;
//
res = 1;
}
}
break;
//
case X_ZG_SEARCH_PEAK:
//
if (lowsBuffer[shift] != 0 && lowsBuffer[shift] < last_low && highsBuffer[shift] == 0)
{
//
mainBuffer[last_low_pos] = 0;
//
last_low_pos = shift;
last_low = lowsBuffer[shift];
//
mainBuffer[shift] = last_low;
//
res = 1;
}
//
if (highsBuffer[shift] != 0 && lowsBuffer[shift] == 0)
{
//
last_high_pos = shift;
last_high = highsBuffer[shift];
//
mainBuffer[shift] = last_high;
//
extreme_search = X_ZG_SEARCH_VALE;
//
res = 1;
}
break;
//
case X_ZG_SEARCH_VALE:
//
if (highsBuffer[shift] != 0 && highsBuffer[shift] > last_high && lowsBuffer[shift] == 0)
{
//
mainBuffer[last_high_pos] = 0;
//
last_high_pos = shift;
last_high = highsBuffer[shift];
//
mainBuffer[shift] = last_high;
}
//
if (lowsBuffer[shift] != 0 && highsBuffer[shift] == 0)
{
//
last_low_pos = shift;
last_low = lowsBuffer[shift];
//
mainBuffer[shift] = last_low;
//
extreme_search = X_ZG_SEARCH_PEAK;
}
break;
}
//
double iZigZagForColor = lastZigZagValue;
double iZigZag = mainBuffer[shift];
if (iZigZag == 0 && lastZigZagValue != 0)
{
arrowBuffer[shift] = lastZigZagValue;
}
else if (iZigZag != 0)
{
//
lastZigZagValue = iZigZag;
arrowBuffer[shift] = lastZigZagValue;
}
//
colorIDX =
lastZigZagValue > iZigZagForColor
? 0
: lastZigZagValue < iZigZagForColor
? 1
: colorIDX;
arrowColorBuffer[shift] = colorIDX;
}
//
return rates_total;
}
//
// TOOLS ...
//
// Search for the index of the highest bar ...
int Highest(
const double &mArray[],
const int mDepth,
const int mStart //
)
{
//
int result = 0;
//
if (mStart < 0)
{
return result;
}
//
double max = mArray[mStart];
result = mStart;
//
// Start searching ...
for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--)
{
//
if (mArray[i] > max)
{
//
result = i;
max = mArray[i];
}
}
//
// Return index of the highest bar
return result;
}
//
// Search for the index of the lowest bar ...
int Lowest(
const double &mArray[],
const int mDepth,
const int mStart //
)
{
//
int result = 0;
//
if (mStart < 0)
{
return result;
}
//
double min = mArray[mStart];
result = mStart;
//
// Start searching ...
for (int i = mStart - 1; i > mStart - mDepth && i >= 0; i--)
{
//
if (mArray[i] < min)
{
//
result = i;
min = mArray[i];
}
}
//
// Return index of the lowest bar
return result;
}
@@ -0,0 +1,187 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Alert Library
// --------------------------------------
// Name: XAlert
// Description: provides Alerts abilities ...
//
//
// 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 Inputs ...
//
input group "Alerts";
input bool enableAlerts = true; // Enable Alerts
input bool logAlerts = true; // Log Alerts
input bool terminalAlerts = false; // Terminal Alerts
input bool mailAlerts = false; // Mail Alerts
input bool pushAlerts = false; // Push Alerts
//
// END Inputs ...
//
//
#include "x-saherelm.log.lib.mq5"
//
// START Global Definitions: Variables, Properties and etc ...
//
string alertPrefix = "X-Alert";
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool OnInInitAlertLibrary()
{
return false;
}
//
// DeInitial Library if required ...
void OnDeinitAlertLibrary()
{
}
//
// Attach Alert Prefix to Message ...
string PrepareAlertMessage(string message)
{
//
StringReplace(message, "\n", " | ");
//
StringConcatenate(message, alertPrefix, " > ", message);
//
return message;
}
//
// Logging an Alert ...
void LogAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !logAlerts)
{
return;
}
//
LogMessage(alertPrefix, message);
}
//
// Terminal Alert ...
void TerminalAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !terminalAlerts)
{
return;
}
//
// Prepare Message ...
message = PrepareAlertMessage(message);
// Send Terminal Alert ...
Alert(message);
}
//
// Mail Alert ...
void MailAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !mailAlerts)
{
return;
}
//
// Send Mail Alert ...
SendMail(alertPrefix, message);
}
//
// Send Push Notification ...
void PushAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts || !pushAlerts)
{
return;
}
//
// Prepare Message ...
message = PrepareAlertMessage(message);
//
// Send Push Notification Alert ...
SendNotification(message);
}
//
// Alert Sending ...
void SendAlert(string message)
{
//
// Validate Args ...
if (!enableAlerts)
{
return;
}
//
// Log ...
if (logAlerts)
{
LogAlert(message);
}
//
// Terminal ...
if (terminalAlerts)
{
TerminalAlert(message);
}
//
// Mail ...
if (mailAlerts)
{
MailAlert(message);
}
//
// Push ...
if (pushAlerts)
{
PushAlert(message);
}
}
//
// END Provided Functions ...
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,177 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Http Library
// ------------------------------------------
// Name: XHttp
// Description: provide http communication
// abilities ...
//
//
// 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 Model Definition ...
//
enum X_HTTP_METHOD
{
X_HTTP_GET,
X_HTTP_POST
};
//
// END Model Definition ...
//
//
// START Inputs ...
//
//
// END Inputs ...
//
//
// START Global Definitions: Variables, Properties and etc ...
//
//
// END Global Definitions: Variables, Properties and etc ...
//
//
// START Provided Functions ...
//
//
// Initial Library if required ...
bool OnInInitHttpLibrary()
{
return false;
}
//
// DeInitial Library if required ...
void OnDeinitHttpLibrary()
{
}
//
// 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;
}
//
// 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;
}
//
result = WebRequest(
strMethod,
url,
headers,
timeout,
payload,
response,
responseHeaders
);
//
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;
}
//
// END Provided Functions ...
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,385 @@
///////////////////////////////////////////////////////
//
// 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
//
// START Definitions ...
//
//
enum X_HTTP_METHOD
{
X_HTTP_GET,
X_HTTP_POST
};
//
// 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;
}
//
// END Definitions ...
//
//
// START Import and Inclused requirements ...
//
//
// Includes ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Import and Inclused requirements ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Class for Manage Account ...
class XSCHttp
{
//
// Public ...
public:
//
// Constructor ...
void XSCHttp()
{
XSCHttp("", 10000);
}
void XSCHttp(
string path, // Base Folder to Store Data
int timeout // base timeout for Requests
)
{
//
Path(path);
Timeout(timeout);
}
//
// Deconstructor ...
void ~XSCHttp()
{
}
//
// START Getter(s)/Setter(s) ...
//
//
// Path ...
void Path(string value)
{
mPath = value;
}
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;
}
//
// END Getter(s)/Setter(s) ...
//
//
// START Provided Functions ...
//
//
// 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;
}
};
//
// START Usefull Functions ...
//
//
// END Usefull Functions ...
//
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -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 <Trade/AccountInfo.mqh>
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Import and Inclused requirements ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Class for Manage Account ...
class XSCAccount
{
//
// Public ...
public:
//
// Constructor ...
void XSCAccount()
{
//
mAccountInfo = new CAccountInfo();
}
//
// Deconstructor ...
void ~XSCAccount()
{
}
//
// 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,209 @@
///////////////////////////////////////////////////////
//
// 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
//
// START Definitions ...
//
//
// END Definitions ...
//
//
// START Import and Inclused requirements ...
//
//
// Includes ...
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Import and Inclused requirements ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Class for Handle base requirements ...
// for indicators ...
class XSCBaseHelper
{
//
// Public ...
public:
//
// Constructor ...
void XSCBaseHelper(
string symbol, // Trading Symbol
ENUM_TIMEFRAMES period // Trading Time Frame
)
{
//
mSymbol = symbol;
mPeriod = period;
//
LoopBack(52);
}
//
// Deconstructor ...
void ~XSCBaseHelper()
{
IndicatorRelease(mHandler);
}
//
// START Properties ...
//
//
// Loopback Bars ...
void LoopBack(int value)
{
mLoopbackBars = value;
}
int Loopback()
{
return mLoopbackBars;
}
//
// Symbol ...
string GetSymbol()
{
return mSymbol;
}
//
// Period ...
ENUM_TIMEFRAMES GetPeriod()
{
return mPeriod;
}
//
// Tag ...
string GetTag()
{
return mTag;
}
//
// Retrieve Bars ...
int GetBars()
{
//
int result =
Bars(
mSymbol,
mPeriod);
//
return result;
}
//
int GetCalculatedBars()
{
return BarsCalculated(mHandler);
}
//
// END Properties ...
//
//
// START Provided Functions ...
//
//
// Prepare Tag ...
virtual void PrepareTag() {}
//
// Reading Buffers based on Given Bar Index ...
virtual void Calculate(
int barIndex // Given Bar Index
);
//
// Retrieve MAx Required Length for Calculations ...
virtual int GetMaxLength();
//
// END Provided Functions ...
//
//
// Protected ...
protected:
//
string GetTagPrefix()
{
//
string result = "(" + mSymbol + ")(" + ToString(mPeriod) + ")";
//
return result;
}
//
// Symbol ...
string mSymbol;
//
// Period ...
ENUM_TIMEFRAMES mPeriod;
//
// Indicator Handler ...
int mHandler;
//
// Number Of Items Read Per Tick ...
int mLoopbackBars;
//
// Tag Identifier ...
string mTag;
//
// Private ...
private:
//
};
//
// START Usefull Functions ...
//
//
// END Usefull Functions ...
//
@@ -0,0 +1,304 @@
///////////////////////////////////////////////////////
//
// SaherElm IT Center MQL5 Class Library
// ----------------------------------------------
// Name: XSCEABaseProvider
// Description: provides base requirements for
// Specific Sgnal Provider ...
//
//
// 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 Import and Inclused requirements ...
//
//
// Includes ...
#include "../Libraries/x-saherelm.log.lib.mq5"
#include "../Libraries/x-saherelm.draw.lib.mq5"
#include "../Libraries/x-saherelm.models.lib.mq5"
#include "../Libraries/x-saherelm.common.lib.mq5"
//
// END Import and Inclused requirements ...
//
//
// START Definitions ...
//
//
// Notified a Signal was Appears ...
typedef void (*OnSignal)(
XSignal &signal);
//
// Notified a Guard Appears ...
typedef void (*OnGuard)(XGuard &guard);
//
// END Definitions ...
//
//
// START Overrides ...
//
//
// END Overrides ...
//
//
// a Base Class for All of our EA's ...
class XSCEABaseProvider
{
//
// Public ...
public:
//
// Constructor ...
void XSCEABaseProvider()
{
mSymbol = _Symbol;
mPeriod = _Period;
}
void XSCEABaseProvider(
string symbol,
ENUM_TIMEFRAMES period)
{
//
mSymbol = symbol;
mPeriod = period;
//
mTag = mSymbol + "," + ToString(mPeriod);
//
mIsInTestMode = IsRunningOnTestMode();
}
//
// Deconstructor ...
void ~XSCEABaseProvider()
{
}
//
bool CanIgnoreTick() {
//
mIsNewCandle = IsNewCandle(
mSymbol,
mPeriod);
bool result = mIsInTestMode
? !mIsNewCandle
: !mIsNewCandle && mWaitUntilNewCandle;
//
return result;
}
//
// Prepare State ...
void OnTick()
{
//
mIsNewCandle = IsNewCandle(
mSymbol,
mPeriod);
mCanIgnoreTick = mIsInTestMode
? !mIsNewCandle
: !mIsNewCandle && mWaitUntilNewCandle;
//
ProcessBuffers();
//
if (mCanIgnoreTick)
{
return;
}
//
mWaitUntilNewCandle = false;
//
ProcessTick();
}
//
virtual void PrepareTag();
//
// Initialize Indicators and Requirements ...
virtual bool Init();
//
virtual int GetMaxLength();
//
virtual int GetCalculatedBars();
//
// Handle Update Buffers ...
virtual void ProcessBuffers()
{
return;
}
//
// Handle On Tick Event ...
virtual void ProcessTick()
{
return;
}
//
// Check for Guards ...
virtual bool GuardCheck(XGuard &guards[]);
//
// Add Specific On Signal Event Handler ...
int AddOnSignalEventHandler(OnSignal handler)
{
//
ArrayResize(
mSignalEventHandlers,
ArraySize(mSignalEventHandlers) + 1);
//
int result = ArraySize(mSignalEventHandlers) - 1;
mSignalEventHandlers[result] = handler;
//
return result;
}
//
// Remove All On Signal Event Handler ...
void ReoveOnSignalEventHandlers()
{
//
ArrayFree(mSignalEventHandlers);
}
//
// Notify a Signal Found on all Event Listeners ...
void NotifyOnSignalEvent(XSignal &info)
{
//
int listenerCount = ArraySize(mSignalEventHandlers);
if (listenerCount <= 0)
{
return;
}
//
// Loop Through Listeners ...
for (int i = 0; i < listenerCount; i++)
{
//
OnSignal listener = mSignalEventHandlers[i];
//
listener(info);
}
}
//
// Protected ...
protected:
//
string mSymbol;
//
ENUM_TIMEFRAMES mPeriod;
//
string mTag;
//
bool mIsNewCandle;
bool mIsInTestMode;
bool mCanIgnoreTick;
bool mWaitUntilNewCandle;
//
// Private ...
private:
//
// Signal Event Handlers ...
OnSignal mSignalEventHandlers[];
};
//
// START Definitions ...
//
//
// Model Signal Providers Definitions ...
struct XBaseSignalProvider
{
//
// Provider use Which Symbol ...
string symbol;
//
// Provider use Which Time Frame ...
ENUM_TIMEFRAMES period;
//
// Risk Amount Per Trades Related to Time Frames ...
// Percent of Available Balance ...
double riskAmount;
//
// Desired Magic Number ...
ulong magicNumber;
};
//
struct XLastSignal
{
datetime at;
string provider;
};
//
// END Definitions ...
//
//
// START Usefull Functions ...
//
//
// Add Specific Provider to List ...
void Add(
XBaseSignalProvider &item, // item want to add
XBaseSignalProvider &buffer[] // Destination buffer
)
{
//
ArrayResize(
buffer,
ArraySize(buffer) + 1);
//
buffer[ArraySize(buffer) - 1] = item;
}
//
// END Usefull Functions ...
//
File diff suppressed because it is too large Load Diff
@@ -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,830 @@
/**
* 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;
}
//#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,
//
copyFolder,
createDirectory,
removeDirectory,
createDirectory,
removeDirectory,
isDirectoryExists,
isDirectoryExists,
getDirectoryFiles,
getDirectoryFolders,
getDirectoryContents,
}
//#endregion

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