last ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -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
Binary file not shown.
@@ -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 ...
|
||||
//
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -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 ...
|
||||
//
|
||||
Binary file not shown.
@@ -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 &source[], // Specify Char Array to Hash
|
||||
int length = 0 // Specify Length of Char Array which required to hash
|
||||
)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
int sourceCount = ArraySize(source);
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
if (
|
||||
sourceCount <= 0 ||
|
||||
(sourceCount > 0 && length > sourceCount))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Normalize Args ...
|
||||
if (length == 0)
|
||||
{
|
||||
length = sourceCount;
|
||||
}
|
||||
|
||||
//
|
||||
// Init MD5 ...
|
||||
MD5Init();
|
||||
|
||||
//
|
||||
// Update Buffer ...
|
||||
MD5Update(source, length);
|
||||
|
||||
//
|
||||
// Calculate Result ...
|
||||
result = MD5Final();
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Hash Specified String ...
|
||||
string Hash(
|
||||
string source // Specified String
|
||||
)
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
// Converts String to Char Array ...
|
||||
uchar bytes[];
|
||||
StringToCharArray(
|
||||
source,
|
||||
bytes,
|
||||
0,
|
||||
StringLen(source));
|
||||
|
||||
//
|
||||
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;
|
||||
}
|
||||
};
|
||||
Binary file not shown.
@@ -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 ...
|
||||
//
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -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,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
|
||||
Binary file not shown.
@@ -0,0 +1,558 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center RSIMA MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XDONCHAINEA
|
||||
// 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 XDONCHAINEA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include <Trade/Trade.mqh>
|
||||
|
||||
//
|
||||
#define ShortName "XDONCHAINEA"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
long magicNumber = 78692110;
|
||||
double lotSize = 0.01;
|
||||
|
||||
//
|
||||
double stopLoss = 200;
|
||||
double takeProfit = 400;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
int xdonHandler;
|
||||
double xdonUpperBuffer[];
|
||||
double xdonLowerBuffer[];
|
||||
|
||||
//
|
||||
int ma20Handler;
|
||||
double ma20Buffer[];
|
||||
|
||||
//
|
||||
int ma50Handler;
|
||||
double ma50Buffer[];
|
||||
|
||||
//
|
||||
int ma100Handler;
|
||||
double ma100Buffer[];
|
||||
|
||||
//
|
||||
CTrade trade;
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES scPeriod = NULL;
|
||||
ENUM_TIMEFRAMES mcPeriod = NULL;
|
||||
ENUM_TIMEFRAMES lcPeriod = NULL;
|
||||
ENUM_TIMEFRAMES hcPeriod = NULL;
|
||||
|
||||
//
|
||||
MqlTick currentTick;
|
||||
MqlRates rates[];
|
||||
MqlRates scRates[];
|
||||
MqlRates mcRates[];
|
||||
MqlRates lcRates[];
|
||||
MqlRates hcRates[];
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
trade.SetExpertMagicNumber(magicNumber);
|
||||
|
||||
//
|
||||
xdonHandler = iCustom(
|
||||
//
|
||||
_Symbol,
|
||||
_Period,
|
||||
"x-saherelm.xdon",
|
||||
//
|
||||
// Inputs ...
|
||||
52,
|
||||
0
|
||||
//
|
||||
);
|
||||
|
||||
//
|
||||
ma20Handler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
20,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_OPEN);
|
||||
|
||||
//
|
||||
ma50Handler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
50,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_OPEN);
|
||||
|
||||
//
|
||||
ma100Handler = iMA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
100,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_OPEN);
|
||||
|
||||
//
|
||||
if (xdonHandler == INVALID_HANDLE ||
|
||||
ma20Handler == INVALID_HANDLE ||
|
||||
ma50Handler == INVALID_HANDLE ||
|
||||
ma100Handler == INVALID_HANDLE)
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
ArraySetAsSeries(rates, true);
|
||||
ArraySetAsSeries(ma20Buffer, true);
|
||||
ArraySetAsSeries(ma50Buffer, true);
|
||||
ArraySetAsSeries(ma100Buffer, true);
|
||||
ArraySetAsSeries(xdonUpperBuffer, true);
|
||||
ArraySetAsSeries(xdonLowerBuffer, true);
|
||||
|
||||
//
|
||||
// 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 XEA Providers ...
|
||||
IndicatorRelease(ma20Handler);
|
||||
IndicatorRelease(ma50Handler);
|
||||
IndicatorRelease(ma100Handler);
|
||||
IndicatorRelease(xdonHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!IsNewBar())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Tick ...
|
||||
if (!SymbolInfoTick(_Symbol, currentTick))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// if (scPeriod == NULL) {
|
||||
// scPeriod = GetNearest
|
||||
// }
|
||||
|
||||
//
|
||||
// Prepare Rates ...
|
||||
int ratesCopied = CopyRates(
|
||||
_Symbol,
|
||||
_Period,
|
||||
0,
|
||||
15,
|
||||
rates);
|
||||
|
||||
//
|
||||
int xdonUpperCopied = CopyBuffer(
|
||||
xdonHandler,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
xdonUpperBuffer);
|
||||
int xdonLowerCopied = CopyBuffer(
|
||||
xdonHandler,
|
||||
1,
|
||||
0,
|
||||
15,
|
||||
xdonLowerBuffer);
|
||||
if (xdonUpperCopied <= 0 || xdonLowerCopied <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int ma20Copied = CopyBuffer(
|
||||
ma20Handler,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
ma20Buffer);
|
||||
int ma50Copied = CopyBuffer(
|
||||
ma50Handler,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
ma50Buffer);
|
||||
int ma100Copied = CopyBuffer(
|
||||
ma100Handler,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
ma100Buffer);
|
||||
if (ma20Copied <= 0 || ma50Copied <= 0 || ma100Copied <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// BUY ...
|
||||
bool buyConditions =
|
||||
//
|
||||
// First Condition ...
|
||||
// ma20Buffer[1] < MathMin(ma50Buffer[1], ma100Buffer[1])
|
||||
// //
|
||||
// &&
|
||||
//
|
||||
// Donchain Condition ...
|
||||
// Candle Must Shadow Hunt ...
|
||||
(rates[1].low < xdonLowerBuffer[1] &&
|
||||
MathMin(rates[1].open, rates[1].close) > xdonLowerBuffer[1])
|
||||
//
|
||||
||
|
||||
//
|
||||
(rates[1].low < xdonLowerBuffer[1] &&
|
||||
rates[2].low < xdonLowerBuffer[2])
|
||||
//
|
||||
;
|
||||
if (buyConditions)
|
||||
{
|
||||
//
|
||||
|
||||
//
|
||||
double sl =
|
||||
stopLoss <= 0
|
||||
? 0
|
||||
: currentTick.bid - (stopLoss * _Point);
|
||||
if (!NormalizePrice(sl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double tp =
|
||||
takeProfit <= 0
|
||||
? 0
|
||||
: currentTick.bid + (takeProfit * _Point);
|
||||
if (!NormalizePrice(tp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
trade.PositionOpen(
|
||||
_Symbol,
|
||||
ORDER_TYPE_BUY,
|
||||
lotSize,
|
||||
currentTick.ask,
|
||||
sl,
|
||||
tp,
|
||||
ShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// SELL ...
|
||||
bool sellConditions =
|
||||
//
|
||||
// First Condition ...
|
||||
// ma20Buffer[1] > MathMax(ma50Buffer[1], ma100Buffer[1])
|
||||
// //
|
||||
// &&
|
||||
//
|
||||
// Donchain Condition ...
|
||||
// Candle Must Shadow Hunt ...
|
||||
(rates[1].high > xdonUpperBuffer[1] &&
|
||||
MathMax(rates[1].open, rates[1].close) < xdonUpperBuffer[1])
|
||||
//
|
||||
||
|
||||
//
|
||||
(rates[1].high > xdonUpperBuffer[1] &&
|
||||
rates[2].high > xdonUpperBuffer[2])
|
||||
//
|
||||
;
|
||||
if (sellConditions)
|
||||
{
|
||||
//
|
||||
double sl =
|
||||
stopLoss <= 0
|
||||
? 0
|
||||
: currentTick.ask - (stopLoss * _Point);
|
||||
if (!NormalizePrice(sl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double tp =
|
||||
takeProfit <= 0
|
||||
? 0
|
||||
: currentTick.ask + (takeProfit * _Point);
|
||||
if (!NormalizePrice(tp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
trade.PositionOpen(
|
||||
_Symbol,
|
||||
ORDER_TYPE_SELL,
|
||||
lotSize,
|
||||
currentTick.bid,
|
||||
sl,
|
||||
tp,
|
||||
ShortName);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TOOLS ...
|
||||
bool IsNewBar()
|
||||
{
|
||||
//
|
||||
static datetime prevTime = 0;
|
||||
datetime currentTime = iTime(_Symbol, _Period, 0);
|
||||
|
||||
//
|
||||
if (prevTime != currentTime)
|
||||
{
|
||||
//
|
||||
prevTime = currentTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool NormalizePrice(
|
||||
double &price // What to Normal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double tickSize = 0;
|
||||
result = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
price = NormalizeDouble(MathRound(price / tickSize) * tickSize, _Digits);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool CountOpenPositions(
|
||||
int &buyCount, // Buys
|
||||
int &sellCount // Sells
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
buyCount = 0;
|
||||
sellCount = 0;
|
||||
|
||||
//
|
||||
int total = PositionsTotal();
|
||||
if (total <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = total - 1; i >= 0; i--)
|
||||
{
|
||||
//
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isSelected = PositionSelectByTicket(ticket);
|
||||
if (!isSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long magic;
|
||||
bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic);
|
||||
if (!isMagicSelected || (isMagicSelected && magic != magicNumber))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long typeInt;
|
||||
ENUM_POSITION_TYPE type;
|
||||
bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt);
|
||||
if (!isTypeSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
type = (ENUM_POSITION_TYPE)typeInt;
|
||||
|
||||
//
|
||||
if (type == POSITION_TYPE_BUY)
|
||||
{
|
||||
buyCount++;
|
||||
}
|
||||
else if (type == POSITION_TYPE_SELL)
|
||||
{
|
||||
sellCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool ClosePositions(ENUM_POSITION_TYPE type)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int total = PositionsTotal();
|
||||
if (total <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = total - 1; i >= 0; i--)
|
||||
{
|
||||
//
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isSelected = PositionSelectByTicket(ticket);
|
||||
if (!isSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long magic;
|
||||
bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic);
|
||||
if (!isMagicSelected || (isMagicSelected && magic != magicNumber))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long typeInt;
|
||||
ENUM_POSITION_TYPE pType;
|
||||
bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt);
|
||||
if (!isTypeSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
pType = (ENUM_POSITION_TYPE)typeInt;
|
||||
|
||||
//
|
||||
if (type != pType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
trade.PositionClose(ticket);
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
template <typename T>
|
||||
string ToString(const T value)
|
||||
{
|
||||
//
|
||||
return (string)value;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,494 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center RSIMA MQL5 Expert Advisor
|
||||
// -------------------------------------------------
|
||||
// Name: XRSIMAEA
|
||||
// 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 XRSIMAEA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
#include <Trade/Trade.mqh>
|
||||
|
||||
//
|
||||
#define ShortName "XRSIMAEA"
|
||||
|
||||
//
|
||||
// Inputs ...
|
||||
long magicNumber = 78692110;
|
||||
double lotSize = 0.01;
|
||||
|
||||
//
|
||||
int rsiLength = 25;
|
||||
int rsiLevel = 70;
|
||||
|
||||
//
|
||||
int maLength = 25;
|
||||
|
||||
//
|
||||
double stopLoss = 200;
|
||||
double takeProfit = 100;
|
||||
|
||||
//
|
||||
bool closeSignal = false;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
int rsiHandler;
|
||||
double rsiBuffer[];
|
||||
|
||||
//
|
||||
int maHandler;
|
||||
double maBuffer[];
|
||||
|
||||
//
|
||||
CTrade trade;
|
||||
|
||||
//
|
||||
MqlTick currentTick;
|
||||
|
||||
//
|
||||
datetime openTimeBuy = 0;
|
||||
datetime openTimeSell = 0;
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
trade.SetExpertMagicNumber(magicNumber);
|
||||
|
||||
//
|
||||
rsiHandler = iRSI(
|
||||
_Symbol,
|
||||
_Period,
|
||||
rsiLength,
|
||||
PRICE_OPEN);
|
||||
|
||||
//
|
||||
maHandler = iMA(
|
||||
_Symbol,
|
||||
PERIOD_H1,
|
||||
maLength,
|
||||
0,
|
||||
MODE_SMA,
|
||||
PRICE_OPEN);
|
||||
|
||||
//
|
||||
if (rsiHandler == INVALID_HANDLE || maHandler == INVALID_HANDLE)
|
||||
{
|
||||
return INIT_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
ArraySetAsSeries(rsiBuffer, true);
|
||||
ArraySetAsSeries(maBuffer, true);
|
||||
|
||||
//
|
||||
// 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 XEA Providers ...
|
||||
IndicatorRelease(rsiHandler);
|
||||
IndicatorRelease(maHandler);
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
if (!IsNewBar())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Reading Tick ...
|
||||
if (!SymbolInfoTick(_Symbol, currentTick))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int rsiCopied = CopyBuffer(
|
||||
rsiHandler,
|
||||
0,
|
||||
0,
|
||||
2,
|
||||
rsiBuffer);
|
||||
if (rsiCopied < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
int maCopied = CopyBuffer(
|
||||
maHandler,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
maBuffer);
|
||||
if (maCopied < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
Comment(
|
||||
"rsi[0]: " + ToString(rsiBuffer[0]) + "\n" +
|
||||
"rsi[1]: " + ToString(rsiBuffer[1]) + "\n" +
|
||||
"ma[0]: " + ToString(maBuffer[0]));
|
||||
|
||||
//
|
||||
int buyCount;
|
||||
int sellCount;
|
||||
//
|
||||
if (!CountOpenPositions(buyCount, sellCount))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// BUY ...
|
||||
if (
|
||||
buyCount == 0 &&
|
||||
rsiBuffer[1] >= (100 - rsiLevel) &&
|
||||
rsiBuffer[0] < (100 - rsiLevel) &&
|
||||
currentTick.ask > maBuffer[0])
|
||||
{
|
||||
//
|
||||
if (closeSignal)
|
||||
{
|
||||
//
|
||||
bool isClose = ClosePositions(POSITION_TYPE_SELL);
|
||||
if (!isClose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
double sl =
|
||||
stopLoss <= 0
|
||||
? 0
|
||||
: currentTick.bid - (stopLoss * _Point);
|
||||
if (!NormalizePrice(sl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double tp =
|
||||
takeProfit <= 0
|
||||
? 0
|
||||
: currentTick.bid + (takeProfit * _Point);
|
||||
if (!NormalizePrice(tp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
trade.PositionOpen(
|
||||
_Symbol,
|
||||
ORDER_TYPE_BUY,
|
||||
lotSize,
|
||||
currentTick.ask,
|
||||
sl,
|
||||
tp,
|
||||
ShortName);
|
||||
}
|
||||
|
||||
//
|
||||
// SELL ...
|
||||
if (
|
||||
sellCount == 0 &&
|
||||
rsiBuffer[1] <= rsiLevel &&
|
||||
rsiBuffer[0] > rsiLevel &&
|
||||
currentTick.bid < maBuffer[0])
|
||||
{
|
||||
//
|
||||
if (closeSignal)
|
||||
{
|
||||
//
|
||||
bool isClose = ClosePositions(POSITION_TYPE_BUY);
|
||||
if (!isClose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
double sl =
|
||||
stopLoss <= 0
|
||||
? 0
|
||||
: currentTick.ask - (stopLoss * _Point);
|
||||
if (!NormalizePrice(sl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double tp =
|
||||
takeProfit <= 0
|
||||
? 0
|
||||
: currentTick.ask + (takeProfit * _Point);
|
||||
if (!NormalizePrice(tp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
trade.PositionOpen(
|
||||
_Symbol,
|
||||
ORDER_TYPE_SELL,
|
||||
lotSize,
|
||||
currentTick.bid,
|
||||
sl,
|
||||
tp,
|
||||
ShortName);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TOOLS ...
|
||||
bool IsNewBar()
|
||||
{
|
||||
//
|
||||
static datetime prevTime = 0;
|
||||
datetime currentTime = iTime(_Symbol, _Period, 0);
|
||||
|
||||
//
|
||||
if (prevTime != currentTime)
|
||||
{
|
||||
//
|
||||
prevTime = currentTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool NormalizePrice(
|
||||
double &price // What to Normal
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double tickSize = 0;
|
||||
result = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE, tickSize);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
price = NormalizeDouble(MathRound(price / tickSize) * tickSize, _Digits);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool CountOpenPositions(
|
||||
int &buyCount, // Buys
|
||||
int &sellCount // Sells
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
buyCount = 0;
|
||||
sellCount = 0;
|
||||
|
||||
//
|
||||
int total = PositionsTotal();
|
||||
if (total <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = total - 1; i >= 0; i--)
|
||||
{
|
||||
//
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isSelected = PositionSelectByTicket(ticket);
|
||||
if (!isSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long magic;
|
||||
bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic);
|
||||
if (!isMagicSelected || (isMagicSelected && magic != magicNumber))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long typeInt;
|
||||
ENUM_POSITION_TYPE type;
|
||||
bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt);
|
||||
if (!isTypeSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
type = (ENUM_POSITION_TYPE)typeInt;
|
||||
|
||||
//
|
||||
if (type == POSITION_TYPE_BUY)
|
||||
{
|
||||
buyCount++;
|
||||
}
|
||||
else if (type == POSITION_TYPE_SELL)
|
||||
{
|
||||
sellCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
bool ClosePositions(ENUM_POSITION_TYPE type)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
int total = PositionsTotal();
|
||||
if (total <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = total - 1; i >= 0; i--)
|
||||
{
|
||||
//
|
||||
ulong ticket = PositionGetTicket(i);
|
||||
if (ticket <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
bool isSelected = PositionSelectByTicket(ticket);
|
||||
if (!isSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long magic;
|
||||
bool isMagicSelected = PositionGetInteger(POSITION_MAGIC, magic);
|
||||
if (!isMagicSelected || (isMagicSelected && magic != magicNumber))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
long typeInt;
|
||||
ENUM_POSITION_TYPE pType;
|
||||
bool isTypeSelected = PositionGetInteger(POSITION_TYPE, typeInt);
|
||||
if (!isTypeSelected)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
pType = (ENUM_POSITION_TYPE)typeInt;
|
||||
|
||||
//
|
||||
if (type != pType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
trade.PositionClose(ticket);
|
||||
}
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
template <typename T>
|
||||
string ToString(const T value)
|
||||
{
|
||||
//
|
||||
return (string)value;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,377 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Expert Advisor
|
||||
// ----------------------------------------
|
||||
// Name: X121EA
|
||||
// Description: this is an expert controller
|
||||
// advisors which provides a mechanism for use them ...
|
||||
//
|
||||
// NOTE: about provider instancing in multi asset state:
|
||||
// you can provide configurations using this:
|
||||
//
|
||||
// EURUSDb,USDCHFb|M5|0.01|X786,X92|true
|
||||
// EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true
|
||||
// EURUSDb,GBPUSDb,USDJPYb,USDCHFb,XAUUSDb|M5,M15|0.01|X786|true
|
||||
//
|
||||
// or make the instance use this:
|
||||
//
|
||||
// XPV(EURUSDb|M15|0.01|X92|true)XPV(GBPUSDb|M5|0.02|X786|false)
|
||||
//
|
||||
// if leave Configuration string blank this will used default config
|
||||
// and One asset mode enabled ...
|
||||
//
|
||||
// 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 X121EA"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
#define ShortName "X121EA"
|
||||
|
||||
//
|
||||
// END Definitions ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// EA ...
|
||||
input group "Common";
|
||||
input bool xEAEnable = true; // Enable EA
|
||||
input int xEASlippage = 10; // Slippgae
|
||||
input ulong xEAMagicNumber = 1604056; // Magic Number
|
||||
|
||||
//
|
||||
// Providers ...
|
||||
input group "Providers";
|
||||
input string xEAProvidersConfiguration = ""; // Providers Configuration
|
||||
input string xEADefaultSignalProviders = "XTEST"; // Default Allowed Signal Providers
|
||||
|
||||
//
|
||||
// Signals ...
|
||||
input group "Signals";
|
||||
input bool xEAEnableLongs = true; // Enable Long Trades
|
||||
input bool xEAEnableShorts = true; // Enable Short Trades
|
||||
|
||||
//
|
||||
// Risk Management ...
|
||||
input group "Risk Management";
|
||||
input double xEAMaxAllowedSpread = 10; // Max Allowed Spread to Execute Signal
|
||||
input int xEAMaxOpenPositions = 15; // Max Allowed Open Trades
|
||||
input double xEAMinRiskAmountPerTrade = 0.001; // Min Risk Amount Per Trade
|
||||
input double xEAMaxAllowedDrawDownFactor = 0.01; // Max Allowed Drawdown Factor
|
||||
input double xEAMinProfitPerTrade = 0.5; // Min Acceptable Profit Per Trade
|
||||
input double xEAMinProfitPerVolumeFactor = 0.01; // Min Acceptable Profit Volume Factor Per Trade
|
||||
input bool xEAUseRiskAmountAsStaticVolume = true; // Use Provided Risk Amount as Static Volume
|
||||
|
||||
//
|
||||
input group "EQM";
|
||||
input int xEAMinAgeForDoSupport = 35; // Minimum Age For Supporting In Drawdown Positions when there isn't Equity
|
||||
input int xEAMinAgeForUpdateSupports = 35; // Minimum Age For Update Untriggered Support Orders
|
||||
|
||||
//
|
||||
// Alerts ...
|
||||
input group "Alerts";
|
||||
input bool xEAEnableAlerts = true; // Enable Events Alert
|
||||
input bool xEAEnableHourlyAlerts = false; // Send Alert on each new Hour
|
||||
input bool xEAEnableDailyAlerts = false; // Send Alert on each new Day
|
||||
input bool xEAEnableWeeklyAlerts = false; // Send Alert on each new Week
|
||||
input bool xEAEnableMonthlyAlerts = false; // Send Alert on each new Month
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Including Providers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Logger Library ...
|
||||
#include "../Libraries/x-saherelm.log.lib.mq5"
|
||||
#include "../Classes/x-saherelm.x121.xea.class.mq5"
|
||||
#include "../Libraries/x-saherelm.seriallizer.lib.mq5"
|
||||
|
||||
//
|
||||
// END Including Providers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
XSCX121EA *mX121EA;
|
||||
|
||||
//
|
||||
// END Global Definitions: Variables, Properties and etc ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
logTag = ShortName;
|
||||
drawPrefix = logTag;
|
||||
alertPrefix = logTag;
|
||||
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
bool isInit = InitEAInstance();
|
||||
if (!isInit)
|
||||
{
|
||||
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
|
||||
|
||||
//
|
||||
// De Initialize XEA Providers ...
|
||||
delete mX121EA;
|
||||
}
|
||||
|
||||
//
|
||||
// On Tick Handler ...
|
||||
void OnTick()
|
||||
{
|
||||
//
|
||||
// Prevent Going Forward if user Disable it ...
|
||||
if (xEAEnable)
|
||||
{
|
||||
mX121EA.OnTick();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Trade Events ...
|
||||
void OnTrade()
|
||||
{
|
||||
mX121EA.OnTrade();
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Signal Event ...
|
||||
void OnSignalConditionsRecieved(X121MarketConditions &info)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Handle StopLoss Event ...
|
||||
void OnStopLossTriggered(const XDeal &deal)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Handle TakeProfit Event ...
|
||||
void OnTakeProfitTriggered(const XDeal &deal)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Deals Changed Event ...
|
||||
void OnDealsChangedHandler(int count)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Order Changed Event ...
|
||||
void OnOrdersChangedHandler(int count)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Position Changed Event ...
|
||||
void OnPositionsChangedHandler(int count)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Handle Trade State Changed ...
|
||||
void OnTradeStateChangedHandler(const XOnTradeHandlerState &state)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
// Validate Args ...
|
||||
result =
|
||||
//
|
||||
xEASlippage > 0 &&
|
||||
xEAMagicNumber > 0 &&
|
||||
xEAMinRiskAmountPerTrade > 0 &&
|
||||
StringLen(xEADefaultSignalProviders) > 0
|
||||
//
|
||||
// TODO: add new validations here ...
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
// Validate Providers ...
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
string providers[];
|
||||
SplitContent(
|
||||
providers,
|
||||
xEADefaultSignalProviders);
|
||||
|
||||
//
|
||||
int providersCount = ArraySize(providers);
|
||||
if (providersCount <= 0)
|
||||
{
|
||||
//
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string allProviders[];
|
||||
GetAllProviders(allProviders);
|
||||
|
||||
//
|
||||
bool hasError = false;
|
||||
for (int i = 0; i < providersCount; i++)
|
||||
{
|
||||
//
|
||||
string iProvider = providers[i];
|
||||
if (!Contains(iProvider, allProviders))
|
||||
{
|
||||
//
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (hasError)
|
||||
{
|
||||
//
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Logging State ...
|
||||
string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ...";
|
||||
LogMessage(message);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize X121EA Class Instances ...
|
||||
bool InitEAInstance()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
X121SignalProvider providers[];
|
||||
|
||||
//
|
||||
// Try to Extract Configs ...
|
||||
int configsCount = ExtractProviderConfigurations(
|
||||
providers,
|
||||
xEAProvidersConfiguration,
|
||||
xEADefaultSignalProviders,
|
||||
xEAMinRiskAmountPerTrade,
|
||||
xEAUseRiskAmountAsStaticVolume);
|
||||
|
||||
//
|
||||
mX121EA = new XSCX121EA(
|
||||
_Symbol,
|
||||
_Period,
|
||||
xEAMagicNumber,
|
||||
xEASlippage,
|
||||
xEAMaxAllowedSpread,
|
||||
xEAMaxOpenPositions,
|
||||
xEAMinProfitPerTrade,
|
||||
xEAMinProfitPerVolumeFactor,
|
||||
xEAMaxAllowedDrawDownFactor,
|
||||
OnStopLossTriggered,
|
||||
OnTakeProfitTriggered,
|
||||
OnDealsChangedHandler,
|
||||
OnOrdersChangedHandler,
|
||||
OnPositionsChangedHandler,
|
||||
OnTradeStateChangedHandler,
|
||||
//
|
||||
xEAMinAgeForDoSupport,
|
||||
xEAMinAgeForUpdateSupports,
|
||||
OnSignalConditionsRecieved);
|
||||
|
||||
//
|
||||
mX121EA.EnableLongs(xEAEnableLongs);
|
||||
mX121EA.EnableShorts(xEAEnableShorts);
|
||||
|
||||
//
|
||||
// Attach Providers to EA Instance ...
|
||||
int providersCount = ArraySize(providers);
|
||||
int addedProviders = mX121EA.AddProviders(providers);
|
||||
result = addedProviders == providersCount;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// END Functions ...
|
||||
//
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -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 ...
|
||||
//
|
||||
Binary file not shown.
@@ -0,0 +1,240 @@
|
||||
///////////////////////////////////////////////////////
|
||||
// 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.draw.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include "../Classes/x-saherelm.xtrade.class.mq5"
|
||||
|
||||
//
|
||||
// INPUT ...
|
||||
|
||||
//
|
||||
// Short ...
|
||||
input ENUM_TIMEFRAMES scPeriod = PERIOD_H4; // Short Period
|
||||
input bool drawSCMidLine = true; // Draw MidLine
|
||||
//
|
||||
// Medium ...
|
||||
input ENUM_TIMEFRAMES mcPeriod = PERIOD_H12; // Mid Period
|
||||
input bool drawMCMidLine = true; // Draw MidLine
|
||||
|
||||
//
|
||||
// Long ...
|
||||
input ENUM_TIMEFRAMES lcPeriod = PERIOD_D1; // Long Period
|
||||
input bool drawLCMidLine = true; // Draw MidLine
|
||||
|
||||
//
|
||||
// Hind ...
|
||||
input ENUM_TIMEFRAMES hcPeriod = PERIOD_W1; // Hind Period
|
||||
input bool drawHCMidLine = true; // Draw MidLine
|
||||
|
||||
//
|
||||
// BUFFERS ...
|
||||
|
||||
//
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 5
|
||||
#property indicator_plots 5
|
||||
|
||||
//
|
||||
// Short ...
|
||||
|
||||
//
|
||||
// Open ...
|
||||
#define scOpenBufferIndex 0;
|
||||
double scOpenBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label1 "X121_XDSR SC O"
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrCornflowerBlue
|
||||
#property indicator_width1 1
|
||||
|
||||
//
|
||||
// High ,,,
|
||||
#define scHighBufferIndex 1;
|
||||
double scHighBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label2 "X121_XDSR SC H"
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrCornflowerBlue
|
||||
#property indicator_width2 1
|
||||
|
||||
//
|
||||
// Close ,,,
|
||||
#define scCloseBufferIndex 2;
|
||||
double scCloseBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label3 "X121_XDSR SC C"
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrCornflowerBlue
|
||||
#property indicator_width3 1
|
||||
|
||||
//
|
||||
// Low ,,,
|
||||
#define scLowBufferIndex 3;
|
||||
double scLowBuffer[];
|
||||
|
||||
//
|
||||
#property indicator_label4 "X121_XDSR SC L"
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrCornflowerBlue
|
||||
#property indicator_width4 1
|
||||
|
||||
//
|
||||
// EVENT Handlers ...
|
||||
|
||||
//
|
||||
// Initialization ...
|
||||
int OnInit()
|
||||
{
|
||||
//
|
||||
// Validate Inputs ...
|
||||
if (!ValidateInputs())
|
||||
{
|
||||
return INIT_PARAMETERS_INCORRECT;
|
||||
}
|
||||
|
||||
//
|
||||
logTag = ShortName;
|
||||
drawPrefix = 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[])
|
||||
{
|
||||
//
|
||||
if (rates_total < 50)
|
||||
{
|
||||
return prev_calculated;
|
||||
}
|
||||
|
||||
//
|
||||
int start = prev_calculated == 0
|
||||
? 50
|
||||
: prev_calculated - 1;
|
||||
|
||||
//
|
||||
// Main Loop ...
|
||||
for (int barIndex = start; barIndex < rates_total; barIndex++)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
|
||||
//
|
||||
// CUSTOM Functions ...
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
result = true;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Define Indexes and Styles ...
|
||||
void DefineBuffers()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Set Indicator Short Name and also we can define Buffers Labels ...
|
||||
void SetIndicatorName()
|
||||
{
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, ShortName);
|
||||
}
|
||||
Binary file not shown.
@@ -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 ...
|
||||
//
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,775 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Indicator
|
||||
// ---------------------------------------------
|
||||
// Name: X121_XCHNL
|
||||
// Description: XCHL Channel 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_XCHNL Indicator"
|
||||
#property strict
|
||||
|
||||
//
|
||||
// START Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
#define ShortName "X121_XCHNL"
|
||||
|
||||
//
|
||||
// END Constants ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Includes and Imports ...
|
||||
//
|
||||
|
||||
//
|
||||
// Includes Common Library ...
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
|
||||
//
|
||||
// Includes Draw Library ...
|
||||
#include "../Libraries/x-saherelm.draw.lib.mq5"
|
||||
|
||||
//
|
||||
// END Includes and Imports ...
|
||||
//
|
||||
|
||||
//
|
||||
// START XSCHULL Class Definition ...
|
||||
//
|
||||
|
||||
//
|
||||
// END XSCHULL Class Definition ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
input group "Makret Cycles";
|
||||
input int shortLength = 9; // Short Length
|
||||
input int mediumLength = 17; // Medium Length
|
||||
input int longLength = 26; // Long Length
|
||||
input int hindLength = 35; // Hind Length
|
||||
|
||||
//
|
||||
input group "Trend";
|
||||
input int numOfShoulder = 10; // Number of Shoulders for Swings
|
||||
|
||||
//
|
||||
input group "Detection Modes";
|
||||
input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method
|
||||
input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method
|
||||
|
||||
//
|
||||
input group "Presentation";
|
||||
input bool showTrend = false; // Show Trend
|
||||
input bool showSRs = false; // Show Support and Resistance
|
||||
|
||||
//
|
||||
// END Inputs ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Buffers ...
|
||||
//
|
||||
|
||||
//
|
||||
// PEKSANDVALES ...
|
||||
|
||||
#property indicator_chart_window
|
||||
|
||||
//
|
||||
#property indicator_buffers 8
|
||||
#property indicator_plots 0
|
||||
|
||||
#define sHHBufferIndex 0
|
||||
#define sLLBufferIndex 1
|
||||
#define mHHBufferIndex 2
|
||||
#define mLLBufferIndex 3
|
||||
#define lHHBufferIndex 4
|
||||
#define lLLBufferIndex 5
|
||||
#define hHHBufferIndex 6
|
||||
#define hLLBufferIndex 7
|
||||
|
||||
double sHHBuffer[];
|
||||
double sLLBuffer[];
|
||||
double mHHBuffer[];
|
||||
double mLLBuffer[];
|
||||
double lHHBuffer[];
|
||||
double lLLBuffer[];
|
||||
double hHHBuffer[];
|
||||
double hLLBuffer[];
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
//
|
||||
drawPrefix = ShortName;
|
||||
|
||||
//
|
||||
// because in some cases we may have more than one input for
|
||||
// calculation and we must prevent any calculation
|
||||
// untill we pass the biggest input length, here we get max Input length
|
||||
// and then wait until pass it ...
|
||||
maxLength = ExtractMaxLengthOfInputs();
|
||||
|
||||
//
|
||||
// Define Index Buffers ...
|
||||
DefineBuffers();
|
||||
|
||||
//
|
||||
// Set Indicator ShortName ...
|
||||
SetIndicatorName();
|
||||
|
||||
//
|
||||
// Make an Instance of Hull Class ...
|
||||
|
||||
//
|
||||
// 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
|
||||
|
||||
//
|
||||
RemoveDraws(drawPrefix);
|
||||
}
|
||||
|
||||
//
|
||||
// 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[])
|
||||
{
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
|
||||
//
|
||||
return rates_total;
|
||||
}
|
||||
//
|
||||
// END Event Handlers ...
|
||||
//
|
||||
|
||||
//
|
||||
// START Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Validate Input Args for Initialization ...
|
||||
bool ValidateInputs()
|
||||
{
|
||||
//
|
||||
bool result = true;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// Validate Peaks and Vales ...
|
||||
(shortLength > 2 &&
|
||||
mediumLength > shortLength &&
|
||||
longLength > mediumLength &&
|
||||
hindLength > longLength)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve all Exists Input Max Length ...
|
||||
// use for Start Of Drawing ...
|
||||
int ExtractMaxLengthOfInputs()
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Peaks and Vales ...
|
||||
result = MathMax(shortLength, mediumLength);
|
||||
result = MathMax(result, longLength);
|
||||
result = MathMax(result, hindLength);
|
||||
|
||||
//
|
||||
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()
|
||||
{
|
||||
//
|
||||
ArraySetAsSeries(sHHBuffer, true);
|
||||
SetIndexBuffer(sHHBufferIndex, sHHBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(sLLBuffer, true);
|
||||
SetIndexBuffer(sLLBufferIndex, sLLBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mHHBuffer, true);
|
||||
SetIndexBuffer(mHHBufferIndex, mHHBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(mLLBuffer, true);
|
||||
SetIndexBuffer(mLLBufferIndex, mLLBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lHHBuffer, true);
|
||||
SetIndexBuffer(lHHBufferIndex, lHHBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(lLLBuffer, true);
|
||||
SetIndexBuffer(lLLBufferIndex, lLLBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hHHBuffer, true);
|
||||
SetIndexBuffer(hHHBufferIndex, hHHBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//
|
||||
ArraySetAsSeries(hLLBuffer, true);
|
||||
SetIndexBuffer(hLLBufferIndex, hLLBuffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Buffers ...
|
||||
void CalculateBuffers(
|
||||
int bar_index // Selected Bar Index
|
||||
)
|
||||
{
|
||||
//
|
||||
// Calculate ...
|
||||
|
||||
//
|
||||
// SHORT ...
|
||||
|
||||
//
|
||||
// HIGH ...
|
||||
int sHHIndex = iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
hhMode,
|
||||
shortLength,
|
||||
bar_index);
|
||||
double sHHValue = GetAppliedPrice(
|
||||
sHHIndex,
|
||||
hhMode);
|
||||
|
||||
//
|
||||
sHHBuffer[bar_index] = sHHValue;
|
||||
|
||||
//
|
||||
// LOW ...
|
||||
int sLLIndex = iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
llMode,
|
||||
shortLength,
|
||||
bar_index);
|
||||
double sLLValue = GetAppliedPrice(
|
||||
sLLIndex,
|
||||
llMode);
|
||||
|
||||
//
|
||||
sLLBuffer[bar_index] = sLLValue;
|
||||
|
||||
//
|
||||
// MEDIUM ...
|
||||
|
||||
//
|
||||
// HIGH ...
|
||||
int mHHIndex = iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
hhMode,
|
||||
mediumLength,
|
||||
bar_index);
|
||||
double mHHValue = GetAppliedPrice(
|
||||
mHHIndex,
|
||||
hhMode);
|
||||
|
||||
//
|
||||
mHHBuffer[bar_index] = mHHValue;
|
||||
|
||||
//
|
||||
// LOW ...
|
||||
int mLLIndex = iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
llMode,
|
||||
mediumLength,
|
||||
bar_index);
|
||||
double mLLValue = GetAppliedPrice(
|
||||
mLLIndex,
|
||||
llMode);
|
||||
|
||||
//
|
||||
mLLBuffer[bar_index] = mLLValue;
|
||||
|
||||
//
|
||||
// LONG ...
|
||||
|
||||
//
|
||||
// HIGH ...
|
||||
int lHHIndex = iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
hhMode,
|
||||
longLength,
|
||||
bar_index);
|
||||
double lHHValue = GetAppliedPrice(
|
||||
lHHIndex,
|
||||
hhMode);
|
||||
|
||||
//
|
||||
lHHBuffer[bar_index] = lHHValue;
|
||||
|
||||
//
|
||||
// LOW ...
|
||||
int lLLIndex = iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
llMode,
|
||||
longLength,
|
||||
bar_index);
|
||||
double lLLValue = GetAppliedPrice(
|
||||
lLLIndex,
|
||||
llMode);
|
||||
|
||||
//
|
||||
lLLBuffer[bar_index] = lLLValue;
|
||||
|
||||
//
|
||||
// HIND ...
|
||||
|
||||
//
|
||||
// HIGH ...
|
||||
int hHHIndex = iHighest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
hhMode,
|
||||
hindLength,
|
||||
bar_index);
|
||||
double hHHValue = GetAppliedPrice(
|
||||
hHHIndex,
|
||||
hhMode);
|
||||
|
||||
//
|
||||
hHHBuffer[bar_index] = hHHValue;
|
||||
|
||||
//
|
||||
// LOW ...
|
||||
int hLLIndex = iLowest(
|
||||
_Symbol,
|
||||
_Period,
|
||||
llMode,
|
||||
hindLength,
|
||||
bar_index);
|
||||
double hLLValue = GetAppliedPrice(
|
||||
hLLIndex,
|
||||
llMode);
|
||||
|
||||
//
|
||||
hLLBuffer[bar_index] = hLLValue;
|
||||
|
||||
//
|
||||
// Find Swings ...
|
||||
|
||||
//
|
||||
// High ...
|
||||
int hSwing1 = FindSwing(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_HIGH,
|
||||
numOfShoulder,
|
||||
bar_index + 1);
|
||||
|
||||
int hSwing2 = FindSwing(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_HIGH,
|
||||
numOfShoulder,
|
||||
hSwing1 + 1);
|
||||
|
||||
//
|
||||
// High ...
|
||||
int hSwing3 = FindSwing(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_HIGH,
|
||||
numOfShoulder,
|
||||
hSwing2 + 1);
|
||||
|
||||
// int hSwing4 = FindSwing(
|
||||
// _Symbol,
|
||||
// _Period,
|
||||
// MODE_HIGH,
|
||||
// numOfShoulder,
|
||||
// hSwing3 + 1);
|
||||
|
||||
//
|
||||
// Low ...
|
||||
int lSwing1 = FindSwing(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_LOW,
|
||||
numOfShoulder,
|
||||
bar_index + 1);
|
||||
|
||||
int lSwing2 = FindSwing(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_LOW,
|
||||
numOfShoulder,
|
||||
lSwing1 + 1);
|
||||
|
||||
int lSwing3 = FindSwing(
|
||||
_Symbol,
|
||||
_Period,
|
||||
MODE_LOW,
|
||||
numOfShoulder,
|
||||
lSwing2 + 1);
|
||||
|
||||
// int lSwing4 = FindSwing(
|
||||
// _Symbol,
|
||||
// _Period,
|
||||
// MODE_LOW,
|
||||
// numOfShoulder,
|
||||
// lSwing3 + 1);
|
||||
|
||||
//
|
||||
if (bar_index < 50)
|
||||
{
|
||||
|
||||
//
|
||||
bool isStrongResistance =
|
||||
//
|
||||
hHHBuffer[bar_index + 1] == hHHBuffer[bar_index + 2] &&
|
||||
hHHBuffer[bar_index + 2] == hHHBuffer[bar_index + 3] &&
|
||||
//
|
||||
lHHBuffer[bar_index + 1] == lHHBuffer[bar_index + 2] &&
|
||||
lHHBuffer[bar_index + 2] == lHHBuffer[bar_index + 3] &&
|
||||
//
|
||||
mHHBuffer[bar_index + 1] == mHHBuffer[bar_index + 2] &&
|
||||
mHHBuffer[bar_index + 2] == mHHBuffer[bar_index + 3] &&
|
||||
//
|
||||
sHHBuffer[bar_index + 1] == sHHBuffer[bar_index + 2] &&
|
||||
sHHBuffer[bar_index + 2] == sHHBuffer[bar_index + 3]
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool isStrongSupport =
|
||||
//
|
||||
hLLBuffer[bar_index + 1] == hLLBuffer[bar_index + 2] &&
|
||||
hLLBuffer[bar_index + 2] == hLLBuffer[bar_index + 3] &&
|
||||
//
|
||||
lLLBuffer[bar_index + 1] == lLLBuffer[bar_index + 2] &&
|
||||
lLLBuffer[bar_index + 2] == lLLBuffer[bar_index + 3] &&
|
||||
//
|
||||
mLLBuffer[bar_index + 1] == mLLBuffer[bar_index + 2] &&
|
||||
mLLBuffer[bar_index + 2] == mLLBuffer[bar_index + 3] &&
|
||||
//
|
||||
sLLBuffer[bar_index + 1] == sLLBuffer[bar_index + 2] &&
|
||||
sLLBuffer[bar_index + 2] == sLLBuffer[bar_index + 3]
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (isStrongResistance && showSRs)
|
||||
{
|
||||
//
|
||||
DrawSupportResistance(
|
||||
"R",
|
||||
clrRed,
|
||||
sHHBuffer[bar_index + 3],
|
||||
bar_index + 3);
|
||||
}
|
||||
|
||||
//
|
||||
if (isStrongSupport && showSRs)
|
||||
{
|
||||
//
|
||||
DrawSupportResistance(
|
||||
"S",
|
||||
clrGreen,
|
||||
sLLBuffer[bar_index + 3],
|
||||
bar_index + 3);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (showTrend && bar_index < 20)
|
||||
{
|
||||
//
|
||||
DrawSwing(
|
||||
"High1",
|
||||
MODE_HIGH,
|
||||
clrAqua,
|
||||
hSwing1,
|
||||
hSwing2);
|
||||
|
||||
//
|
||||
DrawSwing(
|
||||
"Low1",
|
||||
MODE_LOW,
|
||||
clrAqua,
|
||||
lSwing1,
|
||||
lSwing2);
|
||||
|
||||
//
|
||||
DrawSwing(
|
||||
"High2",
|
||||
MODE_HIGH,
|
||||
clrMagenta,
|
||||
hSwing2,
|
||||
hSwing3);
|
||||
|
||||
//
|
||||
DrawSwing(
|
||||
"Low2",
|
||||
MODE_LOW,
|
||||
clrMagenta,
|
||||
lSwing2,
|
||||
lSwing3);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DrawSwing(
|
||||
string prefix, // Prefix ...
|
||||
ENUM_SERIESMODE mode, // Swing Mode ...
|
||||
color swingColor, // Color ...
|
||||
int index1, // Index 1 ...
|
||||
int index2 // Index 2 ...
|
||||
)
|
||||
{
|
||||
//
|
||||
if (mode != MODE_HIGH && mode != MODE_LOW)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XOHCL c1 = GetCandle(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index1);
|
||||
|
||||
//
|
||||
datetime time1 = GetCandleTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index1);
|
||||
|
||||
//
|
||||
XOHCL c2 = GetCandle(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index2);
|
||||
|
||||
//
|
||||
datetime time2 = GetCandleTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
index2);
|
||||
|
||||
//
|
||||
double value1 = -1;
|
||||
double value2 = -1;
|
||||
|
||||
//
|
||||
switch (mode)
|
||||
{
|
||||
//
|
||||
case MODE_HIGH:
|
||||
value1 = c1.high;
|
||||
value2 = c2.high;
|
||||
break;
|
||||
|
||||
//
|
||||
case MODE_LOW:
|
||||
value1 = c1.low;
|
||||
value2 = c2.low;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
if (value1 == -1 || value2 == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
long chartId = ChartID();
|
||||
string tlName = prefix + "_" + "TrendLine";
|
||||
|
||||
// //
|
||||
// if (IsDrawExists(tlName)) {
|
||||
// RemoveDraw(tlName);
|
||||
// }
|
||||
|
||||
//
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
tlName,
|
||||
0,
|
||||
time2,
|
||||
value2,
|
||||
time1,
|
||||
value1,
|
||||
swingColor,
|
||||
STYLE_DOT,
|
||||
3,
|
||||
false,
|
||||
false,
|
||||
true);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Support and Resistance ...
|
||||
void DrawSupportResistance(
|
||||
string prefix, // Prefix ...
|
||||
color lColor, // Color ...
|
||||
double price, // Support or Resistance price ...
|
||||
int bar_index // Start Bar Index ...
|
||||
)
|
||||
{
|
||||
//
|
||||
datetime time1 = GetCandleTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
datetime time2 = GetCandleTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index - 1);
|
||||
|
||||
//
|
||||
long chartId = ChartID();
|
||||
string tlName = prefix + "_" + "TL" + "_" + (string)(NormalizePrice(price, _Symbol));
|
||||
|
||||
//
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
tlName,
|
||||
0,
|
||||
time1,
|
||||
price,
|
||||
time2,
|
||||
price,
|
||||
lColor,
|
||||
STYLE_DOT,
|
||||
3,
|
||||
false,
|
||||
false,
|
||||
true);
|
||||
}
|
||||
Binary file not shown.
@@ -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,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 ...
|
||||
//
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -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
Binary file not shown.
@@ -0,0 +1,303 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 ...
|
||||
//
|
||||
//
|
||||
// OHCL Candel Model ...
|
||||
enum ENUM_X_PRICE
|
||||
{
|
||||
X_PRICE_HIGH,
|
||||
X_PRICE_OPEN,
|
||||
X_PRICE_CLOSE,
|
||||
X_PRICE_LOW
|
||||
};
|
||||
|
||||
//
|
||||
// Swing Types Enum ...
|
||||
enum ENUM_X_SWING_TYPE
|
||||
{
|
||||
X_NO_SWING = 0,
|
||||
X_SWING_HIGH = 1,
|
||||
X_SWING_LOW = -1,
|
||||
};
|
||||
|
||||
//
|
||||
// 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;
|
||||
};
|
||||
|
||||
//
|
||||
// Describe an Specific Candle ...
|
||||
struct XOHCL
|
||||
{
|
||||
//
|
||||
double high;
|
||||
double open;
|
||||
double close;
|
||||
double low;
|
||||
|
||||
//
|
||||
string ToString()
|
||||
{
|
||||
//
|
||||
string result = "";
|
||||
|
||||
//
|
||||
result = "XOHCL(O(" + (string)open + "),H(" + (string)high + "),C(" + (string)close + "),L(" + (string)low + "))";
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Model Support and Resistance
|
||||
// for Specific Bar ...
|
||||
struct XOHCLSupRes
|
||||
{
|
||||
//
|
||||
double res[];
|
||||
|
||||
//
|
||||
double sup[];
|
||||
};
|
||||
|
||||
//
|
||||
struct XValueChanged
|
||||
{
|
||||
datetime at;
|
||||
double from;
|
||||
double to;
|
||||
};
|
||||
|
||||
//
|
||||
// Available Order Modes ...
|
||||
enum ENUM_X_ORDER_MODES
|
||||
{
|
||||
X_ORDER_MODE_MARKET = 0, // Market Order
|
||||
X_ORDER_MODE_STOP = 1, // Pending Stop Order
|
||||
X_ORDER_MODE_LIMIT = 2, // Pending Limit Order
|
||||
X_ORDER_MODE_STOP_LIMIT = 3, // Pending Stop Limit Order
|
||||
};
|
||||
|
||||
//
|
||||
// Model a Signal ...
|
||||
struct XSignal
|
||||
{
|
||||
//
|
||||
string providers[];
|
||||
|
||||
//
|
||||
string symbol;
|
||||
|
||||
//
|
||||
ENUM_TIMEFRAMES period;
|
||||
|
||||
//
|
||||
ENUM_POSITION_TYPE type;
|
||||
|
||||
//
|
||||
ENUM_X_ORDER_MODES mode;
|
||||
|
||||
//
|
||||
double entry;
|
||||
|
||||
//
|
||||
double tp;
|
||||
|
||||
//
|
||||
double sl;
|
||||
|
||||
//
|
||||
double r2r;
|
||||
|
||||
//
|
||||
double volume;
|
||||
|
||||
//
|
||||
// Support Signals ...
|
||||
XSignal supports[];
|
||||
|
||||
//
|
||||
XOHCLSupRes supportResistances;
|
||||
};
|
||||
//
|
||||
// EXTENSION Methods ...
|
||||
|
||||
//
|
||||
// Clear an Specific Signal Item ...
|
||||
void Clean(XSignal &item)
|
||||
{
|
||||
//
|
||||
Clean(item.providers);
|
||||
|
||||
//
|
||||
Clean(item.supports);
|
||||
|
||||
//
|
||||
Clean(item.supportResistances);
|
||||
|
||||
//
|
||||
item.symbol = "";
|
||||
item.type = NULL;
|
||||
item.mode = NULL;
|
||||
item.period = NULL;
|
||||
|
||||
//
|
||||
item.tp = 0;
|
||||
item.sl = 0;
|
||||
item.r2r = 0;
|
||||
item.entry = 0;
|
||||
item.volume = 0;
|
||||
}
|
||||
|
||||
//
|
||||
void Clean(XOHCLSupRes &item)
|
||||
{
|
||||
Clean(item.sup);
|
||||
Clean(item.res);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Add(
|
||||
T &item,
|
||||
T &buffer[])
|
||||
{
|
||||
//
|
||||
ArrayResize(
|
||||
buffer,
|
||||
ArraySize(buffer) + 1);
|
||||
|
||||
//
|
||||
buffer[ArraySize(buffer) - 1] = item;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Clean(T &buffer[])
|
||||
{
|
||||
//
|
||||
ArrayFree(buffer);
|
||||
ArrayResize(buffer, 0);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Copy(
|
||||
T &source[], // Source Buffer ...
|
||||
T &dest[], // Dest Buffer ...
|
||||
bool cleanDest = true // Force Clen Dest Buffer ...
|
||||
)
|
||||
{
|
||||
//
|
||||
if (cleanDest)
|
||||
{
|
||||
Clean(dest);
|
||||
}
|
||||
|
||||
//
|
||||
int sourceCount = ArraySize(source);
|
||||
if (sourceCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < sourceCount; i++)
|
||||
{
|
||||
//
|
||||
T iSource = source[i];
|
||||
|
||||
//
|
||||
Add(
|
||||
iSource,
|
||||
dest);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Provided Functions ...
|
||||
//
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,284 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 X12 Draw Library
|
||||
// ------------------------------------------
|
||||
// Name: X121Draw
|
||||
// Description: provides Draw 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 "../Libraries/x-saherelm.draw.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.common.lib.mq5"
|
||||
#include "../Libraries/x-saherelm.models.lib.mq5"
|
||||
|
||||
//
|
||||
// START Draw Functions ...
|
||||
//
|
||||
|
||||
//
|
||||
// Draw Signal ...
|
||||
void DrawSignal(const ulong ticket, XSignal &signal)
|
||||
{
|
||||
//
|
||||
bool isLong = IsLong(signal.type);
|
||||
|
||||
//
|
||||
string prefix = (string)ticket + "_" + ToString(signal.period);
|
||||
|
||||
//
|
||||
// Retrieve Time ...
|
||||
datetime time = iTime(
|
||||
signal.symbol,
|
||||
signal.period,
|
||||
0);
|
||||
|
||||
//
|
||||
// Retrieve 3 Time ...
|
||||
datetime time3 = iTime(
|
||||
signal.symbol,
|
||||
signal.period,
|
||||
3);
|
||||
|
||||
//
|
||||
color posColor = isLong
|
||||
? clrSpringGreen
|
||||
: clrTomato;
|
||||
color tpColor = clrSpringGreen;
|
||||
color slColor = clrTomato;
|
||||
color entryColor = clrGold;
|
||||
|
||||
//
|
||||
ENUM_LINE_STYLE vLineStyle = STYLE_DOT;
|
||||
ENUM_LINE_STYLE tpLineStyle = STYLE_SOLID;
|
||||
ENUM_LINE_STYLE slLineStyle = STYLE_SOLID;
|
||||
ENUM_LINE_STYLE entryLineStyle = STYLE_SOLID;
|
||||
|
||||
//
|
||||
int lineWidth = 2;
|
||||
|
||||
//
|
||||
long chartID = ChartID();
|
||||
|
||||
//
|
||||
// Vertical Line ...
|
||||
string vlName = prefix + "_" + (string)time;
|
||||
|
||||
//
|
||||
// DrawVerticalLine(
|
||||
// chartID,
|
||||
// vlName,
|
||||
// 0,
|
||||
// time,
|
||||
// posColor,
|
||||
// vLineStyle,
|
||||
// lineWidth);
|
||||
|
||||
//
|
||||
// TP ...
|
||||
double profit = (MathAbs(signal.tp - signal.entry)) * signal.volume;
|
||||
string tpName = prefix + "_TP_" + (string)profit;
|
||||
|
||||
//
|
||||
DrawTrendLine(
|
||||
chartID,
|
||||
tpName,
|
||||
0,
|
||||
time3,
|
||||
signal.tp,
|
||||
time,
|
||||
signal.tp,
|
||||
tpColor,
|
||||
tpLineStyle,
|
||||
lineWidth);
|
||||
|
||||
//
|
||||
// SL ...
|
||||
double lost = (MathAbs(signal.sl - signal.entry)) * signal.volume;
|
||||
string slName = prefix + "_SL_" + (string)lost;
|
||||
|
||||
//
|
||||
DrawTrendLine(
|
||||
chartID,
|
||||
slName,
|
||||
0,
|
||||
time3,
|
||||
signal.sl,
|
||||
time,
|
||||
signal.sl,
|
||||
slColor,
|
||||
slLineStyle,
|
||||
lineWidth);
|
||||
|
||||
//
|
||||
// TODO: Fix this ...
|
||||
return;
|
||||
|
||||
//
|
||||
// ENTRY ...
|
||||
string entryName = prefix + "_ENTRY_" + (string)lost;
|
||||
|
||||
//
|
||||
DrawTrendLine(
|
||||
chartID,
|
||||
entryName,
|
||||
0,
|
||||
time3,
|
||||
signal.entry,
|
||||
time,
|
||||
signal.entry,
|
||||
entryColor,
|
||||
entryLineStyle,
|
||||
lineWidth);
|
||||
}
|
||||
|
||||
//
|
||||
void DrawSignals(
|
||||
XSignal &signals[], // Signals To Draw
|
||||
bool drawSupportAndResistances = false // Draw Signal Support and Resistance
|
||||
)
|
||||
{
|
||||
//
|
||||
int signalsCount = ArraySize(signals);
|
||||
if (signalsCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < signalsCount; i++)
|
||||
{
|
||||
//
|
||||
XSignal iSignal = signals[i];
|
||||
|
||||
//
|
||||
ulong iTicket = MathRand() * 10000;
|
||||
|
||||
//
|
||||
DrawSignal(iTicket, iSignal);
|
||||
|
||||
//
|
||||
// TODO: Remove this ...
|
||||
return;
|
||||
|
||||
//
|
||||
// Check For Draw Support and Resistances ...
|
||||
bool isValidSupRes = ArraySize(iSignal.supportResistances.sup) > 0 || ArraySize(iSignal.supportResistances.res) > 0;
|
||||
if (drawSupportAndResistances && isValidSupRes)
|
||||
{
|
||||
DrawSupportResistance(0, iSignal.supportResistances);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Support and Resistance ...
|
||||
void DrawSupportResistance(
|
||||
int bar_index,
|
||||
XOHCLSupRes &data,
|
||||
string prefix = "",
|
||||
color supportColor = clrOrange,
|
||||
color resistanceColor = clrOrange)
|
||||
{
|
||||
//
|
||||
datetime barTime = GetCandleTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index);
|
||||
|
||||
//
|
||||
datetime prevBarTime = GetCandleTime(
|
||||
_Symbol,
|
||||
_Period,
|
||||
bar_index + 5);
|
||||
|
||||
//
|
||||
long chID = ChartID();
|
||||
int subWindiw = 0;
|
||||
int lineWidth = 1;
|
||||
|
||||
//
|
||||
string mPrefix = prefix + "_" + (string)barTime + "_";
|
||||
|
||||
//
|
||||
// SUPPORTS ...
|
||||
|
||||
//
|
||||
int supCount = ArraySize(data.sup);
|
||||
if (supCount > 0)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < supCount; i++)
|
||||
{
|
||||
//
|
||||
double iSup = data.sup[i];
|
||||
|
||||
//
|
||||
string supTlName = mPrefix + "SUP[" + (string)(i + 1) + "]_(" + (string)iSup + ")";
|
||||
|
||||
//
|
||||
// Draw Support ...
|
||||
DrawTrendLine(
|
||||
chID,
|
||||
supTlName,
|
||||
subWindiw,
|
||||
prevBarTime,
|
||||
iSup,
|
||||
barTime,
|
||||
iSup,
|
||||
supportColor,
|
||||
STYLE_DOT,
|
||||
lineWidth,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// RESISTANCES ...
|
||||
|
||||
//
|
||||
int resCount = ArraySize(data.res);
|
||||
if (resCount > 0)
|
||||
{
|
||||
//
|
||||
for (int i = 0; i < resCount; i++)
|
||||
{
|
||||
//
|
||||
double iRes = data.res[i];
|
||||
|
||||
//
|
||||
string resTlName = mPrefix + "RES[" + (string)(i + 1) + "]_(" + (string)iRes + ")";
|
||||
|
||||
//
|
||||
// Draw Support ...
|
||||
DrawTrendLine(
|
||||
chID,
|
||||
resTlName,
|
||||
subWindiw,
|
||||
prevBarTime,
|
||||
iRes,
|
||||
barTime,
|
||||
iRes,
|
||||
resistanceColor,
|
||||
STYLE_DOT,
|
||||
lineWidth,
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// END Draw Functions ...
|
||||
//
|
||||
@@ -0,0 +1,436 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// ----------------------------------------------
|
||||
// Name: XSCX121X786
|
||||
// Description: X121 X786 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
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5"
|
||||
|
||||
//
|
||||
// CONDITIONS ...
|
||||
|
||||
//
|
||||
// Longs ...
|
||||
bool IsX786HasLongSignal(
|
||||
const X121MarketConditions &conditions, // Specified Conditions
|
||||
int index = 0 // Array Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool long1 =
|
||||
//
|
||||
IsHKBullish(conditions) &&
|
||||
IsSMHKBullish(conditions) &&
|
||||
IsHullBullish(conditions, index) &&
|
||||
IsSSLCBullish(conditions, index) &&
|
||||
IsTrendBullish(conditions, index) &&
|
||||
IsRibbonBullish(conditions, index) &&
|
||||
IsBullishCandle(conditions.candles[1])
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool long2 =
|
||||
//
|
||||
IsTrendBullish(conditions) &&
|
||||
IsNewPeakOverLast(conditions) &&
|
||||
//
|
||||
(
|
||||
//
|
||||
IsSCLowBullish(conditions) &&
|
||||
(
|
||||
//
|
||||
IsMCLowBullish(conditions) ||
|
||||
IsLCLowBullish(conditions) ||
|
||||
IsHCLowBullish(conditions)
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
long1
|
||||
//
|
||||
||
|
||||
//
|
||||
long2
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Shorts ...
|
||||
bool IsX786HasShortSignal(
|
||||
const X121MarketConditions &conditions, // Specified Conditions
|
||||
int index = 0 // Array Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool short1 =
|
||||
//
|
||||
IsHKBearish(conditions) &&
|
||||
IsSMHKBearish(conditions) &&
|
||||
IsHullBearish(conditions, index) &&
|
||||
IsSSLCBearish(conditions, index) &&
|
||||
IsTrendBearish(conditions, index) &&
|
||||
IsRibbonBearish(conditions, index) &&
|
||||
IsBearishCandle(conditions.candles[1])
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool short2 =
|
||||
//
|
||||
IsTrendBearish(conditions, index) &&
|
||||
IsNewValeUnderLast(conditions) &&
|
||||
//
|
||||
(
|
||||
//
|
||||
IsSCHighBearish(conditions) &&
|
||||
(
|
||||
//
|
||||
IsMCHighBearish(conditions) ||
|
||||
IsLCHighBearish(conditions) ||
|
||||
IsHCHighBearish(conditions)
|
||||
//
|
||||
)
|
||||
//
|
||||
)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
short1
|
||||
//
|
||||
||
|
||||
//
|
||||
short2
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// CALCULATIONS ...
|
||||
|
||||
//
|
||||
// Calculate Long Stop ...
|
||||
double CalculateX786LongStop(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
double vale = conditions.xmanInfo.vales[0];
|
||||
double med = (conditions.xmanInfo.sLLs[0] + conditions.xmanInfo.mLLs[0]) / 2;
|
||||
double fl1 = conditions.xmanInfo.fibLevel1s[0];
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
0
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Long Take Profits ...
|
||||
double CalculateX786LongTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (sl > 0 && entry > 0 && r2r > 0)
|
||||
{
|
||||
//
|
||||
double riskPrice = MathAbs(entry - sl);
|
||||
double rewardPrice = riskPrice * r2r;
|
||||
|
||||
//
|
||||
result = entry + rewardPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = entry + PointToPrice(conditions.symbol, 60);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Short Stop ...
|
||||
double CalculateX786ShortStop(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Short Take Profits ...
|
||||
double CalculateX786ShortTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (sl > 0 && entry > 0 && r2r > 0)
|
||||
{
|
||||
//
|
||||
double riskPrice = MathAbs(entry - sl);
|
||||
double rewardPrice = riskPrice * r2r;
|
||||
|
||||
//
|
||||
result = entry - rewardPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = entry - PointToPrice(conditions.symbol, 60);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SIGNALS ...
|
||||
|
||||
//
|
||||
// Generate Signal ...
|
||||
bool GenerateX786Signal(
|
||||
X121MarketConditions &conditions, // Specified Conditions which Holds Signal also ...
|
||||
const XOHCLSupRes &supportAndResistances, // Specified Support and Resistances ...
|
||||
ENUM_POSITION_TYPE type, // Specified Which Signal Type must be Generated ...
|
||||
bool generateSupports = false // Specified Support Signals also Generated and Attached or not ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isLong = IsLong(type);
|
||||
|
||||
//
|
||||
// Retrieve Entry Price ...
|
||||
double entry = GetEntry(
|
||||
conditions.symbol,
|
||||
type);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isLong
|
||||
? IsX786HasLongSignal(conditions)
|
||||
: IsX786HasShortSignal(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
ToString(X786),
|
||||
conditions.signal.providers);
|
||||
|
||||
//
|
||||
double sl =
|
||||
//
|
||||
isLong
|
||||
? CalculateX786LongStop(conditions)
|
||||
: CalculateX786ShortStop(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
double r2r = 3;
|
||||
|
||||
//
|
||||
double tp =
|
||||
//
|
||||
isLong
|
||||
? CalculateX786LongTarget(conditions, sl, entry, r2r)
|
||||
: CalculateX786ShortTarget(conditions, sl, entry, r2r)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
double volume = 0.01;
|
||||
|
||||
//
|
||||
conditions.hasSignal = true;
|
||||
|
||||
//
|
||||
conditions.signal.type = type;
|
||||
conditions.signal.symbol = conditions.symbol;
|
||||
conditions.signal.period = conditions.period;
|
||||
conditions.signal.supportResistances = supportAndResistances;
|
||||
|
||||
//
|
||||
conditions.signal.sl = sl;
|
||||
conditions.signal.tp = tp;
|
||||
conditions.signal.r2r = r2r;
|
||||
conditions.signal.entry = entry;
|
||||
conditions.signal.volume = volume;
|
||||
conditions.signal.mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
if (generateSupports)
|
||||
{
|
||||
//
|
||||
// Generate Required Support Signals ...
|
||||
GenerateX786SignalSupports(conditions);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SUPPORTS ...
|
||||
|
||||
//
|
||||
// Generate Required Support Signals and Attached Them into
|
||||
// Exists Signal of Conditions ...
|
||||
int GenerateX786SignalSupports(
|
||||
X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// GUARDS ...
|
||||
|
||||
//
|
||||
// Check Can Force Close All X786 Long Signals or not ...
|
||||
bool CanX786ForceCloseLongs(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// 1- HK Min above FL 1 ...
|
||||
// 2- Trend Changed From Bullish To Bearish ...
|
||||
|
||||
//
|
||||
double minHK = GetHKMin(conditions);
|
||||
bool isMinHKOverFL1 = minHK > conditions.xmanInfo.fibLevel1s[0];
|
||||
bool isTrendSwitchedToBearish = IsTrendSwitchedToBearish(conditions);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// isMinHKOverFL1 &&
|
||||
isTrendSwitchedToBearish
|
||||
//
|
||||
;
|
||||
// if (result) {
|
||||
// LogMessage("Test");
|
||||
// }
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for Trailing Long Positions Stops ...
|
||||
bool CanX786TrailLongsStop(
|
||||
const X121MarketConditions &conditions,
|
||||
double &newSL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double prev = GetRibbonMin(conditions, 1);
|
||||
double current = GetRibbonMin(conditions);
|
||||
|
||||
//
|
||||
result = current > prev;
|
||||
if (result)
|
||||
{
|
||||
newSL = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSL = -1;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check For Trailing Short Positions Stops ...
|
||||
bool CanX786TrailShortsStop(
|
||||
const X121MarketConditions &conditions,
|
||||
double &newSL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double prev = GetRibbonMax(conditions, 1);
|
||||
double current = GetRibbonMax(conditions);
|
||||
|
||||
//
|
||||
result = current < prev;
|
||||
if (result)
|
||||
{
|
||||
newSL = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSL = -1;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// ----------------------------------------------
|
||||
// Name: XSCX121X92
|
||||
// Description: X121 X92 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
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5"
|
||||
|
||||
//
|
||||
// CONDITIONS ...
|
||||
|
||||
//
|
||||
// Longs ...
|
||||
bool IsX92HasLongSignal(
|
||||
const X121MarketConditions &conditions, // Specified Conditions
|
||||
int index = 0 // Array Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool long1 =
|
||||
//
|
||||
IsNewPeak(conditions) &&
|
||||
IsValeSameAs(conditions) &&
|
||||
IsNewPeakUnderLast(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool long2 =
|
||||
//
|
||||
IsSMHKBullish(conditions, index) &&
|
||||
IsTrendBullish(conditions, index) &&
|
||||
IsBullishCandle(conditions.candles[index + 1])
|
||||
//
|
||||
&&
|
||||
//
|
||||
(conditions.candles[index + 1].low > GetSMHKMax(conditions, index) ||
|
||||
conditions.candles[index + 1].close > GetSMHKMax(conditions, index))
|
||||
//
|
||||
&&
|
||||
//
|
||||
conditions.xmanInfo.smhkHighs[index] == iSMHKHighest(conditions, index)
|
||||
//
|
||||
&&
|
||||
//
|
||||
IsSCLowBullish(conditions, index)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
long1
|
||||
//
|
||||
||
|
||||
//
|
||||
long2
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Shorts ...
|
||||
bool IsX92HasShortSignal(
|
||||
const X121MarketConditions &conditions, // Specified Conditions
|
||||
int index = 0 // Array Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool short1 =
|
||||
//
|
||||
IsNewVale(conditions) &&
|
||||
IsPeakSameAs(conditions) &&
|
||||
IsNewValeOverLast(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
bool short2 =
|
||||
//
|
||||
IsSMHKBearish(conditions, index) &&
|
||||
IsTrendBearish(conditions, index) &&
|
||||
IsBearishCandle(conditions.candles[index + 1])
|
||||
//
|
||||
&&
|
||||
//
|
||||
(conditions.candles[index + 1].high < GetSMHKMin(conditions, index) ||
|
||||
conditions.candles[index + 1].open < GetSMHKMin(conditions, index))
|
||||
//
|
||||
&&
|
||||
//
|
||||
conditions.xmanInfo.smhkHighs[index] == iSMHKLowest(conditions, index)
|
||||
//
|
||||
&&
|
||||
//
|
||||
IsSCHighBearish(conditions, index)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
short1
|
||||
//
|
||||
||
|
||||
//
|
||||
short2
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// CALCULATIONS ...
|
||||
|
||||
//
|
||||
// Calculate Long Stop ...
|
||||
double CalculateX92LongStop(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
double vale = conditions.xmanInfo.vales[0];
|
||||
double med = (conditions.xmanInfo.sLLs[0] + conditions.xmanInfo.mLLs[0]) / 2;
|
||||
double fl1 = conditions.xmanInfo.fibLevel1s[0];
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
0
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Long Take Profits ...
|
||||
double CalculateX92LongTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (sl > 0 && entry > 0 && r2r > 0)
|
||||
{
|
||||
//
|
||||
double riskPrice = MathAbs(entry - sl);
|
||||
double rewardPrice = riskPrice * r2r;
|
||||
|
||||
//
|
||||
result = entry + rewardPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = entry + PointToPrice(conditions.symbol, 60);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Short Stop ...
|
||||
double CalculateX92ShortStop(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Short Take Profits ...
|
||||
double CalculateX92ShortTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (sl > 0 && entry > 0 && r2r > 0)
|
||||
{
|
||||
//
|
||||
double riskPrice = MathAbs(entry - sl);
|
||||
double rewardPrice = riskPrice * r2r;
|
||||
|
||||
//
|
||||
result = entry - rewardPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = entry - PointToPrice(conditions.symbol, 60);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SIGNALS ...
|
||||
|
||||
//
|
||||
// Generate Signal ...
|
||||
bool GenerateX92Signal(
|
||||
X121MarketConditions &conditions, // Specified Conditions which Holds Signal also ...
|
||||
const XOHCLSupRes &supportAndResistances, // Specified Support and Resistances ...
|
||||
ENUM_POSITION_TYPE type, // Specified Which Signal Type must be Generated ...
|
||||
bool generateSupports = false // Specified Support Signals also Generated and Attached or not ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isLong = IsLong(type);
|
||||
|
||||
//
|
||||
// Retrieve Entry Price ...
|
||||
double entry = GetEntry(
|
||||
conditions.symbol,
|
||||
type);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isLong
|
||||
? IsX92HasLongSignal(conditions)
|
||||
: IsX92HasShortSignal(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
ToString(X92),
|
||||
conditions.signal.providers);
|
||||
|
||||
//
|
||||
double sl =
|
||||
//
|
||||
isLong
|
||||
? CalculateX92LongStop(conditions)
|
||||
: CalculateX92ShortStop(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
double r2r = 3;
|
||||
|
||||
//
|
||||
double tp =
|
||||
//
|
||||
isLong
|
||||
? CalculateX92LongTarget(conditions, sl, entry, r2r)
|
||||
: CalculateX92ShortTarget(conditions, sl, entry, r2r)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
double volume = 0.01;
|
||||
|
||||
//
|
||||
conditions.hasSignal = true;
|
||||
|
||||
//
|
||||
conditions.signal.type = type;
|
||||
conditions.signal.symbol = conditions.symbol;
|
||||
conditions.signal.period = conditions.period;
|
||||
conditions.signal.supportResistances = supportAndResistances;
|
||||
|
||||
//
|
||||
conditions.signal.sl = sl;
|
||||
conditions.signal.tp = tp;
|
||||
conditions.signal.r2r = r2r;
|
||||
conditions.signal.entry = entry;
|
||||
conditions.signal.volume = volume;
|
||||
conditions.signal.mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
if (generateSupports)
|
||||
{
|
||||
//
|
||||
// Generate Required Support Signals ...
|
||||
GenerateX92SignalSupports(conditions);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SUPPORTS ...
|
||||
|
||||
//
|
||||
// Generate Required Support Signals and Attached Them into
|
||||
// Exists Signal of Conditions ...
|
||||
int GenerateX92SignalSupports(
|
||||
X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// GUARDS ...
|
||||
|
||||
//
|
||||
// Check Can Force Close All X92 Long Signals or not ...
|
||||
bool CanX92ForceCloseLongs(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
// 1- HK Min above FL 1 ...
|
||||
// 2- Trend Changed From Bullish To Bearish ...
|
||||
|
||||
//
|
||||
double minHK = GetHKMin(conditions);
|
||||
bool isMinHKOverFL1 = minHK > conditions.xmanInfo.fibLevel1s[0];
|
||||
bool isTrendSwitchedToBearish = IsTrendSwitchedToBearish(conditions);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
// isMinHKOverFL1 &&
|
||||
isTrendSwitchedToBearish
|
||||
//
|
||||
;
|
||||
// if (result) {
|
||||
// LogMessage("Test");
|
||||
// }
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for Trailing Long Positions Stops ...
|
||||
bool CanX92TrailLongsStop(
|
||||
const X121MarketConditions &conditions,
|
||||
double &newSL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double prev = GetRibbonMin(conditions, 1);
|
||||
double current = GetRibbonMin(conditions);
|
||||
|
||||
//
|
||||
result = current > prev;
|
||||
if (result)
|
||||
{
|
||||
newSL = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSL = -1;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check For Trailing Short Positions Stops ...
|
||||
bool CanX92TrailShortsStop(
|
||||
const X121MarketConditions &conditions,
|
||||
double &newSL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
double prev = GetRibbonMax(conditions, 1);
|
||||
double current = GetRibbonMax(conditions);
|
||||
|
||||
//
|
||||
result = current < prev;
|
||||
if (result)
|
||||
{
|
||||
newSL = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSL = -1;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
///////////////////////////////////////////////////////
|
||||
//
|
||||
// SaherElm IT Center MQL5 Class Library
|
||||
// ----------------------------------------------
|
||||
// Name: XSCX121XTEST
|
||||
// Description: X121 XTEST 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
|
||||
|
||||
//
|
||||
#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5"
|
||||
|
||||
//
|
||||
// CONDITIONS ...
|
||||
|
||||
//
|
||||
// Longs ...
|
||||
bool IsXTESTHasLongSignal(
|
||||
const X121MarketConditions &conditions, // Specified Conditions
|
||||
int index = 0 // Array Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isTrendBullish = IsTrendBullish(conditions, index);
|
||||
bool isCandleBullish = IsBullishCandle(conditions.candles[1]);
|
||||
bool isValidTrend = ArraySize(conditions.xmanInfo.trendChanges) > 2 &&
|
||||
conditions.xmanInfo.trends[0] > conditions.xmanInfo.trends[1] &&
|
||||
conditions.xmanInfo.trends[0] > conditions.xmanInfo.trendChanges[0].from;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isValidTrend &&
|
||||
isTrendBullish &&
|
||||
isCandleBullish
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Shorts ...
|
||||
bool IsXTESTHasShortSignal(
|
||||
const X121MarketConditions &conditions, // Specified Conditions
|
||||
int index = 0 // Array Index
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isTrendBearish = IsTrendBearish(conditions, index);
|
||||
bool isCandleBearish = IsBearishCandle(conditions.candles[1]);
|
||||
bool isValidTrend = ArraySize(conditions.xmanInfo.trendChanges) > 2 &&
|
||||
conditions.xmanInfo.trends[0] < conditions.xmanInfo.trends[1] &&
|
||||
conditions.xmanInfo.trends[0] < conditions.xmanInfo.trendChanges[0].from;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isValidTrend &&
|
||||
isTrendBearish &&
|
||||
isCandleBearish
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// CALCULATIONS ...
|
||||
|
||||
//
|
||||
// Calculate Long Stop ...
|
||||
double CalculateXTESTLongStop(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
conditions.xmanInfo.vales[0]
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Long Take Profits ...
|
||||
double CalculateXTESTLongTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (sl > 0 && entry > 0 && r2r > 0)
|
||||
{
|
||||
//
|
||||
double riskPrice = MathAbs(entry - sl);
|
||||
double rewardPrice = riskPrice * r2r;
|
||||
|
||||
//
|
||||
result = entry + rewardPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = entry + PointToPrice(conditions.symbol, 60);
|
||||
}
|
||||
|
||||
//
|
||||
double peak = conditions.xmanInfo.peaks[1];
|
||||
result =
|
||||
entry >= peak
|
||||
? entry + PointToPrice(conditions.symbol, 60)
|
||||
: peak;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Short Stop ...
|
||||
double CalculateXTESTShortStop(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
conditions.xmanInfo.peaks[0]
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Short Take Profits ...
|
||||
double CalculateXTESTShortTarget(const X121MarketConditions &conditions, double sl, double entry, double r2r = 1)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
if (sl > 0 && entry > 0 && r2r > 0)
|
||||
{
|
||||
//
|
||||
double riskPrice = MathAbs(entry - sl);
|
||||
double rewardPrice = riskPrice * r2r;
|
||||
|
||||
//
|
||||
result = entry - rewardPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = entry - PointToPrice(conditions.symbol, 60);
|
||||
}
|
||||
|
||||
//
|
||||
double vale = conditions.xmanInfo.vales[1];
|
||||
result =
|
||||
entry <= vale
|
||||
? entry - PointToPrice(conditions.symbol, 60)
|
||||
: vale;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SIGNALS ...
|
||||
|
||||
//
|
||||
// Generate Signal ...
|
||||
bool GenerateXTESTSignal(
|
||||
X121MarketConditions &conditions, // Specified Conditions which Holds Signal also ...
|
||||
const XOHCLSupRes &supportAndResistances, // Specified Support and Resistances ...
|
||||
ENUM_POSITION_TYPE type, // Specified Which Signal Type must be Generated ...
|
||||
bool generateSupports = false // Specified Support Signals also Generated and Attached or not ...
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isLong = IsLong(type);
|
||||
|
||||
//
|
||||
// Retrieve Entry Price ...
|
||||
double entry = GetEntry(
|
||||
conditions.symbol,
|
||||
type);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
isLong
|
||||
? IsXTESTHasLongSignal(conditions)
|
||||
: IsXTESTHasShortSignal(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (result)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
ToString(XTEST),
|
||||
conditions.signal.providers);
|
||||
|
||||
//
|
||||
double sl =
|
||||
//
|
||||
isLong
|
||||
? CalculateXTESTLongStop(conditions)
|
||||
: CalculateXTESTShortStop(conditions)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
double r2r = 1.5;
|
||||
|
||||
//
|
||||
double tp =
|
||||
//
|
||||
isLong
|
||||
? CalculateXTESTLongTarget(conditions, sl, entry, r2r)
|
||||
: CalculateXTESTShortTarget(conditions, sl, entry, r2r)
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
double volume = 0.01;
|
||||
|
||||
//
|
||||
conditions.hasSignal = true;
|
||||
|
||||
//
|
||||
conditions.signal.type = type;
|
||||
conditions.signal.symbol = conditions.symbol;
|
||||
conditions.signal.period = conditions.period;
|
||||
conditions.signal.supportResistances = supportAndResistances;
|
||||
|
||||
//
|
||||
conditions.signal.sl = 0; // sl;
|
||||
conditions.signal.tp = tp;
|
||||
conditions.signal.r2r = r2r;
|
||||
conditions.signal.entry = entry;
|
||||
conditions.signal.volume = volume;
|
||||
conditions.signal.mode = X_ORDER_MODE_MARKET;
|
||||
|
||||
//
|
||||
if (generateSupports)
|
||||
{
|
||||
//
|
||||
// Generate Required Support Signals ...
|
||||
GenerateXTESTSignalSupports(conditions);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// SUPPORTS ...
|
||||
|
||||
//
|
||||
// Generate Required Support Signals and Attached Them into
|
||||
// Exists Signal of Conditions ...
|
||||
int GenerateXTESTSignalSupports(
|
||||
X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// GUARDS ...
|
||||
|
||||
//
|
||||
// Check Can Force Close All XTEST Long Signals or not ...
|
||||
bool CanXTESTForceCloseLongs(const X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
bool isTrendSwitchedToBearish = IsTrendSwitchedToBearish(conditions);
|
||||
|
||||
//
|
||||
result =
|
||||
//
|
||||
false
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for Trailing Long Positions Stops ...
|
||||
bool CanXTESTTrailLongsStop(
|
||||
const X121MarketConditions &conditions,
|
||||
double &newSL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Check For Trailing Short Positions Stops ...
|
||||
bool CanXTESTTrailShortsStop(
|
||||
const X121MarketConditions &conditions,
|
||||
double &newSL //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,459 @@
|
||||
//
|
||||
// EQUITYMANAGEMENT ...
|
||||
//
|
||||
|
||||
//
|
||||
// All available Equity Actions Implemented here ...
|
||||
void HandleEquityManagement()
|
||||
{
|
||||
//
|
||||
// TODO: Complete this ...
|
||||
|
||||
//
|
||||
// Here we Must first Check Number of Trades ...
|
||||
XPosition positions[];
|
||||
int positionsCount = GetPositions(positions);
|
||||
if (positionsCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
double profit = CalculatePositionsProfit(positions);
|
||||
double requiredProfit = CalculatePositionsProfit(positions);
|
||||
|
||||
//
|
||||
if (profit > 0 &&
|
||||
positionsCount >= mMaxAllowedPositions)
|
||||
{
|
||||
//
|
||||
// TODO:
|
||||
// Wait for Max Profit for Closing all Open Positions ...
|
||||
// Also Support Orders ...
|
||||
|
||||
//
|
||||
// here we have to Multiply requirement profit for hedging ...
|
||||
bool canHedge = profit >= (requiredProfit * 1.5);
|
||||
string comment = "EQM Hedge ...";
|
||||
int closed = mTrader.ClosePositions(
|
||||
positions,
|
||||
comment);
|
||||
if (closed > 0)
|
||||
{
|
||||
//
|
||||
// Cancel All Placed Support Orders ...
|
||||
CancelAllEQMOrders();
|
||||
|
||||
//
|
||||
string message = "EQM Closed (" + ToString(positionsCount) + ") due Hedge by: " + ToString(profit);
|
||||
|
||||
//
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
else if (profit > 0 && positionsCount > 1)
|
||||
{
|
||||
//
|
||||
// Here we can Hedge Positions in regular Senario ...
|
||||
bool canHedge = profit >= requiredProfit;
|
||||
string comment = "EQM Hedge ...";
|
||||
int closed = mTrader.ClosePositions(
|
||||
positions,
|
||||
comment);
|
||||
if (closed > 0)
|
||||
{
|
||||
//
|
||||
// Cancel All Placed Support Orders ...
|
||||
CancelAllEQMOrders();
|
||||
|
||||
//
|
||||
string message = "EQM Closed (" + ToString(positionsCount) + ") due Hedge by: " + ToString(profit);
|
||||
|
||||
//
|
||||
LogMessage(message);
|
||||
}
|
||||
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Add Longest Age in Props ...
|
||||
int longDetectionAgeForInDrawDownPositions = 26;
|
||||
int longDetectionAgeForUntriggeredSupports = 26;
|
||||
|
||||
//
|
||||
// Here we have to Place Support Signals if there is no Equity ...
|
||||
bool hasEquity = CheckEquityForTrade();
|
||||
if (profit < 0 && !hasEquity)
|
||||
{
|
||||
//
|
||||
// Retrieve and Placed EQM Support Orders ...
|
||||
HandleEQMSupportPlacement();
|
||||
}
|
||||
else if (profit < 0 && hasEquity)
|
||||
{
|
||||
//
|
||||
// Here there are some Open Positions and we have eQuity but
|
||||
// there isn't new Signals and exists positions in DrawDown ...
|
||||
|
||||
//
|
||||
// here we have to Generate EQM Support Signal ...
|
||||
|
||||
//
|
||||
// First try to Find Max In Draw down Position ...
|
||||
XPosition inDPositions[];
|
||||
int inDPositionsCount = GetInDrawdownPositions(
|
||||
inDPositions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
X_POSITION_SELECT_MAX);
|
||||
if (inDPositionsCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
XPosition maxInDPosition = inDPositions[0];
|
||||
int maxInDPositionAge = GetAge(maxInDPosition);
|
||||
|
||||
//
|
||||
bool isSupportable = maxInDPositionAge >= longDetectionAgeForInDrawDownPositions;
|
||||
if (!isSupportable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// now we are sure Max In DrawDown Position is Supportable ...
|
||||
HandleEQMSupportPlacement();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve All EQM Placed Support Orders ...
|
||||
int GetEQMOrders(
|
||||
XOrder &orders[] // Hold Result
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
XOrder allOrders[];
|
||||
int allOrdersCount = GetOrders(allOrders);
|
||||
if (allOrdersCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract EQM Orders ...
|
||||
result = GetEQMSupportOrders(
|
||||
orders,
|
||||
allOrders);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve All EQM Support Positions ...
|
||||
int GetEQMPositions(
|
||||
XPosition &positions[] // Hold Result
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
XPosition allPositions[];
|
||||
int allPositionsCount = GetPositions(allPositions);
|
||||
if (allPositionsCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Extract EQM Positions ...
|
||||
result = GetEQMSupportPositions(
|
||||
positions,
|
||||
allPositions);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Cancel all EQM Placed Support Orders ...
|
||||
bool CancelAllEQMOrders()
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
XOrder eqmOrders[];
|
||||
int eqmOrdersCount = GetEQMOrders(eqmOrders);
|
||||
if (eqmOrdersCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
result = mTrader.CancelOrders(eqmOrders);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate EQM Support Signals ...
|
||||
int GenerateEQMSupports(
|
||||
XSignal &supports[], // Holds Supports
|
||||
bool placeSL = true, // Place SL For EQM Supports
|
||||
bool placeTP = true // Place TP For EQM Supports
|
||||
)
|
||||
{
|
||||
//
|
||||
int result = 0;
|
||||
|
||||
//
|
||||
// Clean result Array ...
|
||||
Clean(supports);
|
||||
|
||||
//
|
||||
// Since we Generate Support Signals based on Max In Drawdown Positions ...
|
||||
// we hae to Find it and then find it's Related Provider ...
|
||||
// then recieve Market Conditions based on it's Signaller's Provider ...
|
||||
// then try to Generate Supports ...
|
||||
XPosition inDrawdownPositions[];
|
||||
int inDrawdownPositionsCount = GetInDrawdownPositions(
|
||||
inDrawdownPositions,
|
||||
NULL, // All Symbols ...
|
||||
NULL, // All TYpe Of Positions ...
|
||||
NULL, // All Periods ...
|
||||
NULL, // All Providers ...
|
||||
X_POSITION_SELECT_MAX // we need Max InDrawdown ...
|
||||
);
|
||||
if (inDrawdownPositionsCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Since We Select Max here ...
|
||||
// and also check count ...
|
||||
// just Recieve Max In DD Position ...
|
||||
XPosition maxInDDPosition = inDrawdownPositions[0];
|
||||
|
||||
//
|
||||
// Here we can Select Provider based on InDD Position ...
|
||||
int providerIDX = GetProviderIndex(
|
||||
maxInDDPosition.symbol,
|
||||
maxInDDPosition.period);
|
||||
|
||||
//
|
||||
// Validate Index ...
|
||||
if (providerIDX <= -1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
double entry = GetEntry(
|
||||
maxInDDPosition.symbol,
|
||||
maxInDDPosition.type);
|
||||
|
||||
//
|
||||
// Retrieve Market Conditions Based on Specific Provider ...
|
||||
X121MarketConditions conditions = mProviders[providerIDX]
|
||||
.provider
|
||||
.GetMarketConditions(0);
|
||||
|
||||
//
|
||||
// Retrieve Support and Resistance ...
|
||||
XOHCLSupRes supRes = mProviders[providerIDX]
|
||||
.provider
|
||||
.GenerateSupportAndResistance(
|
||||
entry,
|
||||
36 //
|
||||
);
|
||||
|
||||
//
|
||||
double volume = GetEQMSupportVolume();
|
||||
|
||||
//
|
||||
// Try to Find above peak and below vale Pivots ...
|
||||
double pivots[];
|
||||
mProviders[providerIDX]
|
||||
.provider
|
||||
.FillPivotPoints(pivots);
|
||||
|
||||
// //
|
||||
// GenerateFiboEQMSupports(
|
||||
// conditions,
|
||||
// maxInDDPosition,
|
||||
// supports,
|
||||
// pivots,
|
||||
// volume,
|
||||
// placeSL,
|
||||
// placeTP);
|
||||
|
||||
//
|
||||
// GenerateSupportAndResistanceEQMSupports(
|
||||
// conditions,
|
||||
// maxInDDPosition,
|
||||
// supRes,
|
||||
// supports,
|
||||
// volume,
|
||||
// placeSL,
|
||||
// placeTP);
|
||||
|
||||
//
|
||||
result = ArraySize(supports);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Count all open Positions Volume for supports ...
|
||||
double GetEQMSupportVolume(
|
||||
bool ignoreEQM = true // Ignore EQM Positions
|
||||
)
|
||||
{
|
||||
//
|
||||
double result = 0;
|
||||
|
||||
//
|
||||
// TODO:
|
||||
// add to Props ...
|
||||
double maxEQMSupportVolume = 0.3;
|
||||
|
||||
//
|
||||
// Retrieve Positions ...
|
||||
XPosition positions[];
|
||||
int positionsCount = GetPositions(positions);
|
||||
if (positionsCount <= 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve EQM Positions and Check ...
|
||||
// if it's count bigger than 0 means there are an Open
|
||||
// EQM Support Position and we do not have to do anything ...
|
||||
XPosition eqmPositions[];
|
||||
int eqmPositionsCount = GetEQMPositions(eqmPositions);
|
||||
if (!ignoreEQM && eqmPositionsCount > 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
for (int i = 0; i < positionsCount; i++)
|
||||
{
|
||||
//
|
||||
XPosition iPosition = positions[i];
|
||||
|
||||
//
|
||||
result += iPosition.volume;
|
||||
}
|
||||
|
||||
//
|
||||
// Multiply Volume Summary ...
|
||||
// TODO: Make it Configurable ...
|
||||
result *= 1;
|
||||
if (result > maxEQMSupportVolume)
|
||||
{
|
||||
result = maxEQMSupportVolume;
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
void HandleEQMSupportPlacement()
|
||||
{
|
||||
//
|
||||
// TODO: Add Longest Age in Props ...
|
||||
int longDetectionAgeForInDrawDownPositions = 26;
|
||||
int longDetectionAgeForUntriggeredSupports = 26;
|
||||
|
||||
//
|
||||
// Here we have to Place EQM Support Orders ...
|
||||
|
||||
//
|
||||
// First Check Exists Supports ...
|
||||
XOrder orders[];
|
||||
int ordersCount = GetEQMOrders(orders);
|
||||
if (ordersCount > 0)
|
||||
{
|
||||
//
|
||||
// When there are Exists Untriggered EQM Support Orders ...
|
||||
// first we have to check their Age ...
|
||||
// if it's longest as enough for replacing, cance all EQM Orders and regenerate new Ones ...
|
||||
// otherwise wait until they triggered or be long as enough ...
|
||||
|
||||
//
|
||||
int minEQMSupportAge = 0;
|
||||
for (int i = 0; i < ordersCount; i++)
|
||||
{
|
||||
//
|
||||
XOrder iOrder = orders[i];
|
||||
|
||||
//
|
||||
int iAge = GetAge(iOrder);
|
||||
minEQMSupportAge = minEQMSupportAge == 0 ||
|
||||
minEQMSupportAge > iAge
|
||||
? iAge
|
||||
: minEQMSupportAge;
|
||||
}
|
||||
|
||||
//
|
||||
// we have min support order's age ...
|
||||
// check it is long enough for cancelling or not ...
|
||||
bool isTooOld = minEQMSupportAge >= longDetectionAgeForUntriggeredSupports;
|
||||
if (!isTooOld)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// we are sre exists EQM Supports are To old ...
|
||||
bool isCancelled = CancelAllEQMOrders();
|
||||
if (!isCancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
XSignal signals[];
|
||||
int signalsCount = GenerateEQMSupports(signals);
|
||||
if (signalsCount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
string comment = GenerateXEQMSupportComment();
|
||||
int executed = mTrader.ExecuteSignals(
|
||||
signals,
|
||||
comment //
|
||||
);
|
||||
if (executed > 0)
|
||||
{
|
||||
//
|
||||
string message = "Execute (" + ToString(executed) + ") EQM Supports ...";
|
||||
|
||||
//
|
||||
LogMessage(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,976 @@
|
||||
//
|
||||
// XOHCL ...
|
||||
void DrawCandleAsLine(
|
||||
XOHCL &c, // the Candle Which required to Draw ...
|
||||
const datetime time, // Candle Time ...
|
||||
string tag = "", // Draw Tag ...
|
||||
//
|
||||
bool drawOpen = true, // Draw Open ...
|
||||
int openWidth = 1, // Open Width ...
|
||||
color clrOpen = clrLime, // Open Color ...
|
||||
ENUM_LINE_STYLE openStyle = STYLE_SOLID, // Open Style ...
|
||||
//
|
||||
bool drawHigh = true, // Draw High ...
|
||||
int highWidth = 1, // High Width ...
|
||||
color clrHigh = clrAqua, // High Color ...
|
||||
ENUM_LINE_STYLE highStyle = STYLE_SOLID, // High Style ...
|
||||
//
|
||||
bool drawClose = true, // Draw Close ...
|
||||
int closeWidth = 1, // Close Width ...
|
||||
color clrClose = clrRed, // Close Color ...
|
||||
ENUM_LINE_STYLE closeStyle = STYLE_SOLID, // Cose Style ...
|
||||
//
|
||||
bool drawLow = true, // Draw Low ...
|
||||
int lowWidth = 1, // Low Width ...
|
||||
color clrLow = clrMagenta, // Low Color ...
|
||||
ENUM_LINE_STYLE lowStyle = STYLE_SOLID // Low Style ...
|
||||
)
|
||||
{
|
||||
//
|
||||
int subWindow = 0;
|
||||
long chartId = ChartID();
|
||||
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
|
||||
//
|
||||
// Open ...
|
||||
if (drawOpen)
|
||||
{
|
||||
//
|
||||
string openTag = tag + "|O|" + ToString(c.open);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
openTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
|
||||
//
|
||||
if (isExists)
|
||||
{
|
||||
//
|
||||
// Move ...
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
openTag,
|
||||
subWindow,
|
||||
time,
|
||||
c.open,
|
||||
cTime,
|
||||
c.open,
|
||||
clrOpen,
|
||||
openStyle,
|
||||
openWidth //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// High ...
|
||||
if (drawHigh)
|
||||
{
|
||||
//
|
||||
string highTag = tag + "|H|" + ToString(c.high);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
highTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
|
||||
//
|
||||
if (isExists)
|
||||
{
|
||||
//
|
||||
// Move ...
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
highTag,
|
||||
subWindow,
|
||||
time,
|
||||
c.high,
|
||||
cTime,
|
||||
c.high,
|
||||
clrHigh,
|
||||
highStyle,
|
||||
highWidth //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close ...
|
||||
if (drawClose)
|
||||
{
|
||||
//
|
||||
string closeTag = tag + "|C|" + ToString(c.close);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
closeTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
|
||||
//
|
||||
if (isExists)
|
||||
{
|
||||
//
|
||||
// Move ...
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
closeTag,
|
||||
subWindow,
|
||||
time,
|
||||
c.close,
|
||||
cTime,
|
||||
c.close,
|
||||
clrClose,
|
||||
closeStyle,
|
||||
closeWidth //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Low ...
|
||||
if (drawLow)
|
||||
{
|
||||
//
|
||||
string lowTag = tag + "|L|" + ToString(c.low);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
lowTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
|
||||
//
|
||||
if (isExists)
|
||||
{
|
||||
//
|
||||
// Move ...
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
lowTag,
|
||||
subWindow,
|
||||
time,
|
||||
c.low,
|
||||
cTime,
|
||||
c.low,
|
||||
clrLow,
|
||||
lowStyle,
|
||||
lowWidth //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Define a Draw Specifications ...
|
||||
struct XDrawSpecifications
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
|
||||
//
|
||||
bool draw; // Draw or Not ...
|
||||
|
||||
//
|
||||
int width; // Draw Witdth ...
|
||||
color clr; // Draw Color ...
|
||||
ENUM_LINE_STYLE style; // Draw Style ...
|
||||
|
||||
//
|
||||
bool back; // in the background
|
||||
bool fill; // fill object if supported
|
||||
bool selection; // highlight to move
|
||||
bool rayRight; // line's continuation to the right
|
||||
bool hidden; // hidden in the object list
|
||||
long zOrder; // priority for mouse click
|
||||
|
||||
//
|
||||
// Constructor ...
|
||||
XDrawSpecifications()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Operator ...
|
||||
void operator=(const XDrawSpecifications &value)
|
||||
{
|
||||
//
|
||||
clr = value.clr;
|
||||
draw = value.draw;
|
||||
width = value.width;
|
||||
style = value.style;
|
||||
|
||||
//
|
||||
back = value.back;
|
||||
hidden = value.hidden;
|
||||
zOrder = value.zOrder;
|
||||
rayRight = value.rayRight;
|
||||
selection = value.selection;
|
||||
|
||||
//
|
||||
fill = value.fill;
|
||||
}
|
||||
|
||||
//
|
||||
// Functions ...
|
||||
|
||||
//
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
draw = false;
|
||||
width = 1;
|
||||
clr = CLR_NONE;
|
||||
style = STYLE_SOLID;
|
||||
|
||||
//
|
||||
back = false;
|
||||
hidden = false;
|
||||
rayRight = false;
|
||||
selection = false;
|
||||
fill = false;
|
||||
|
||||
//
|
||||
zOrder = 0;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Candle Draw Specifications ...
|
||||
struct XOHCLDrawSpecification
|
||||
{
|
||||
//
|
||||
// Props ...
|
||||
XDrawSpecifications openStyle;
|
||||
XDrawSpecifications highStyle;
|
||||
XDrawSpecifications closeStyle;
|
||||
XDrawSpecifications lowStyle;
|
||||
|
||||
//
|
||||
// Constructors ...
|
||||
XOHCLDrawSpecification()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//
|
||||
// Operators ...
|
||||
void operator=(const XOHCLDrawSpecification &value)
|
||||
{
|
||||
//
|
||||
lowStyle = value.lowStyle;
|
||||
openStyle = value.openStyle;
|
||||
highStyle = value.highStyle;
|
||||
closeStyle = value.closeStyle;
|
||||
}
|
||||
|
||||
//
|
||||
// Functions ...
|
||||
|
||||
//
|
||||
void Clean()
|
||||
{
|
||||
//
|
||||
lowStyle.Clean();
|
||||
openStyle.Clean();
|
||||
highStyle.Clean();
|
||||
closeStyle.Clean();
|
||||
}
|
||||
|
||||
//
|
||||
void Default()
|
||||
{
|
||||
//
|
||||
// Open ...
|
||||
openStyle.width = 1;
|
||||
openStyle.draw = true;
|
||||
openStyle.clr = clrLime;
|
||||
openStyle.style = STYLE_SOLID;
|
||||
|
||||
//
|
||||
// High ...
|
||||
highStyle.width = 1;
|
||||
highStyle.draw = true;
|
||||
highStyle.clr = clrAqua;
|
||||
highStyle.style = STYLE_SOLID;
|
||||
|
||||
//
|
||||
// Close ...
|
||||
closeStyle.width = 1;
|
||||
closeStyle.draw = true;
|
||||
closeStyle.clr = clrRed;
|
||||
closeStyle.style = STYLE_SOLID;
|
||||
|
||||
//
|
||||
// Low ...
|
||||
lowStyle.width = 1;
|
||||
lowStyle.draw = true;
|
||||
lowStyle.clr = clrMagenta;
|
||||
lowStyle.style = STYLE_SOLID;
|
||||
}
|
||||
|
||||
//
|
||||
void Width(int value)
|
||||
{
|
||||
//
|
||||
lowStyle.width = value;
|
||||
openStyle.width = value;
|
||||
highStyle.width = value;
|
||||
closeStyle.width = value;
|
||||
}
|
||||
|
||||
//
|
||||
void Style(ENUM_LINE_STYLE value)
|
||||
{
|
||||
//
|
||||
lowStyle.style = value;
|
||||
openStyle.style = value;
|
||||
highStyle.style = value;
|
||||
closeStyle.style = value;
|
||||
}
|
||||
|
||||
//
|
||||
void Color(color value)
|
||||
{
|
||||
//
|
||||
lowStyle.clr = value;
|
||||
openStyle.clr = value;
|
||||
highStyle.clr = value;
|
||||
closeStyle.clr = value;
|
||||
}
|
||||
|
||||
//
|
||||
void RayRight(bool value)
|
||||
{
|
||||
//
|
||||
lowStyle.rayRight = value;
|
||||
openStyle.rayRight = value;
|
||||
highStyle.rayRight = value;
|
||||
closeStyle.rayRight = value;
|
||||
}
|
||||
|
||||
//
|
||||
void Draw(bool value)
|
||||
{
|
||||
//
|
||||
lowStyle.draw = value;
|
||||
openStyle.draw = value;
|
||||
highStyle.draw = value;
|
||||
closeStyle.draw = value;
|
||||
}
|
||||
|
||||
//
|
||||
void Back(bool value)
|
||||
{
|
||||
//
|
||||
lowStyle.back = value;
|
||||
openStyle.back = value;
|
||||
highStyle.back = value;
|
||||
closeStyle.back = value;
|
||||
}
|
||||
|
||||
//
|
||||
void Fill(bool value)
|
||||
{
|
||||
//
|
||||
lowStyle.fill = value;
|
||||
openStyle.fill = value;
|
||||
highStyle.fill = value;
|
||||
closeStyle.fill = value;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
bool RemoveCandle(
|
||||
XOHCL &c,
|
||||
long chartId = 0,
|
||||
int subWindow = 0 //
|
||||
)
|
||||
{
|
||||
//
|
||||
bool result = false;
|
||||
|
||||
//
|
||||
string cTag = GenerateTag(c);
|
||||
|
||||
//
|
||||
result = IsDrawExists(
|
||||
cTag,
|
||||
chartId,
|
||||
subWindow);
|
||||
if (!result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
RemoveDraws(
|
||||
cTag,
|
||||
chartId,
|
||||
subWindow);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// XOHCL ...
|
||||
void DrawCandleAsLine(
|
||||
long chartId, // Chart ID ...
|
||||
int subWindow, // SubWindow ...
|
||||
XOHCL &c, // the Candle Which required to Draw ...
|
||||
const datetime time, // Candle Time ...
|
||||
XOHCLDrawSpecification &config, // Draw Specifications ...
|
||||
string tag = "", // Draw Tag ...
|
||||
bool update = true, // Update Draw if Exists ...
|
||||
bool drawMidLine = true // Draw Open Close Middle Line ...
|
||||
)
|
||||
{
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
XDrawSpecifications specs;
|
||||
|
||||
//
|
||||
string baseTag = tag + GenerateTag(c);
|
||||
|
||||
//
|
||||
// Open ...
|
||||
specs = config.openStyle;
|
||||
if (specs.draw)
|
||||
{
|
||||
//
|
||||
double value = c.open;
|
||||
string valueTag = "|O|";
|
||||
|
||||
//
|
||||
string mTag = baseTag + valueTag + ToString(value);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
mTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteTrendLine(
|
||||
chartId,
|
||||
mTag);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
mTag,
|
||||
subWindow,
|
||||
time,
|
||||
value,
|
||||
cTime,
|
||||
value,
|
||||
specs.clr,
|
||||
specs.style,
|
||||
specs.width,
|
||||
specs.back,
|
||||
specs.selection,
|
||||
specs.rayRight,
|
||||
specs.hidden,
|
||||
specs.zOrder //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// High ...
|
||||
specs = config.highStyle;
|
||||
if (specs.draw)
|
||||
{
|
||||
//
|
||||
double value = c.high;
|
||||
string valueTag = "|H|";
|
||||
|
||||
//
|
||||
string mTag = baseTag + valueTag + ToString(value);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
mTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteTrendLine(
|
||||
chartId,
|
||||
mTag);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
mTag,
|
||||
subWindow,
|
||||
time,
|
||||
value,
|
||||
cTime,
|
||||
value,
|
||||
specs.clr,
|
||||
specs.style,
|
||||
specs.width,
|
||||
specs.back,
|
||||
specs.selection,
|
||||
specs.rayRight,
|
||||
specs.hidden,
|
||||
specs.zOrder //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Close ...
|
||||
specs = config.closeStyle;
|
||||
if (specs.draw)
|
||||
{
|
||||
//
|
||||
double value = c.close;
|
||||
string valueTag = "|C|";
|
||||
|
||||
//
|
||||
string mTag = baseTag + valueTag + ToString(value);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
mTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteTrendLine(
|
||||
chartId,
|
||||
mTag);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
mTag,
|
||||
subWindow,
|
||||
time,
|
||||
value,
|
||||
cTime,
|
||||
value,
|
||||
specs.clr,
|
||||
specs.style,
|
||||
specs.width,
|
||||
specs.back,
|
||||
specs.selection,
|
||||
specs.rayRight,
|
||||
specs.hidden,
|
||||
specs.zOrder //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Low ...
|
||||
specs = config.lowStyle;
|
||||
if (specs.draw)
|
||||
{
|
||||
//
|
||||
double value = c.low;
|
||||
string valueTag = "|L|";
|
||||
|
||||
//
|
||||
string mTag = baseTag + valueTag + ToString(value);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
mTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteTrendLine(
|
||||
chartId,
|
||||
mTag);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
mTag,
|
||||
subWindow,
|
||||
time,
|
||||
value,
|
||||
cTime,
|
||||
value,
|
||||
specs.clr,
|
||||
specs.style,
|
||||
specs.width,
|
||||
specs.back,
|
||||
specs.selection,
|
||||
specs.rayRight,
|
||||
specs.hidden,
|
||||
specs.zOrder //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
double midle = MathAbs(c.open + c.close) / 2;
|
||||
string mTag = tag + GenerateTag(c);
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
mTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteTrendLine(
|
||||
chartId,
|
||||
mTag);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// Draw ...
|
||||
DrawTrendLine(
|
||||
chartId,
|
||||
mTag,
|
||||
subWindow,
|
||||
time,
|
||||
midle,
|
||||
cTime,
|
||||
midle,
|
||||
clrYellow,
|
||||
STYLE_SOLID,
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0 //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void DrawCandleAsBox(
|
||||
long chartId, // Chart ID ...
|
||||
int subWindow, // SubWindow ...
|
||||
XOHCL &c, // the Candle Which required to Draw ...
|
||||
const datetime time, // Candle Time ...
|
||||
XOHCLDrawSpecification &config, // Draw Specifications ...
|
||||
string tag = "", // Draw Tag ...
|
||||
bool drawBody = true, // Draw Body ...
|
||||
bool drawShadows = true, // Draw Shadows ...
|
||||
bool update = true // Update Draw if Exists ...
|
||||
)
|
||||
{
|
||||
//
|
||||
datetime cTime = TimeCurrent();
|
||||
|
||||
//
|
||||
// First Check all Styles Must Be Draw true ...
|
||||
bool canDraw =
|
||||
//
|
||||
config.openStyle.draw &&
|
||||
config.highStyle.draw &&
|
||||
config.closeStyle.draw &&
|
||||
config.lowStyle.draw
|
||||
//
|
||||
;
|
||||
|
||||
//
|
||||
if (!canDraw)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Next we have to determine Candle is Bullish or Bearish ...
|
||||
//
|
||||
bool isBullish =
|
||||
c.open < c.close;
|
||||
|
||||
//
|
||||
bool isBearish =
|
||||
c.open > c.close;
|
||||
|
||||
//
|
||||
XDrawSpecifications bodySpec;
|
||||
if (isBullish)
|
||||
{
|
||||
bodySpec = config.openStyle;
|
||||
}
|
||||
else if (isBearish)
|
||||
{
|
||||
bodySpec = config.closeStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
bodySpec.clr = clrGray;
|
||||
}
|
||||
|
||||
//
|
||||
// Now We have to Draw 3 Rectangle ...
|
||||
// 1- Up Shadow
|
||||
// 2- Candle Body
|
||||
// 3- Down Shadow
|
||||
|
||||
//
|
||||
double upPrice = MathMax(c.open, c.close);
|
||||
double downPrice = MathMin(c.open, c.close);
|
||||
double upShadowSize = c.high - upPrice;
|
||||
double downShadowSize = downPrice - c.low;
|
||||
|
||||
//
|
||||
string mTag = "OHCL|O" + ToString(c.open) + "|H" + ToString(c.high) + "|C" + ToString(c.close) + "|L" + ToString(c.low) + "|";
|
||||
|
||||
//
|
||||
// Draw Up Shadow ...
|
||||
if (drawShadows)
|
||||
{
|
||||
//
|
||||
string upShadowTag = mTag + "|US|";
|
||||
|
||||
XDrawSpecifications spec = config.highStyle;
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
upShadowTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
|
||||
//
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteRectangle(
|
||||
chartId,
|
||||
upShadowTag //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// New ...
|
||||
DrawRectangle(
|
||||
chartId,
|
||||
upShadowTag,
|
||||
subWindow,
|
||||
time,
|
||||
c.high,
|
||||
cTime,
|
||||
upPrice,
|
||||
spec.clr,
|
||||
spec.style,
|
||||
spec.width,
|
||||
spec.fill,
|
||||
spec.back,
|
||||
spec.selection,
|
||||
spec.hidden,
|
||||
spec.zOrder //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Body ...
|
||||
if (drawBody)
|
||||
{
|
||||
//
|
||||
string bodyTag = mTag + "|BDY|";
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
bodyTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
|
||||
//
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteRectangle(
|
||||
chartId,
|
||||
bodyTag //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// New ...
|
||||
DrawRectangle(
|
||||
chartId,
|
||||
bodyTag,
|
||||
subWindow,
|
||||
time,
|
||||
upPrice,
|
||||
cTime,
|
||||
downPrice,
|
||||
bodySpec.clr,
|
||||
bodySpec.style,
|
||||
bodySpec.width,
|
||||
bodySpec.fill,
|
||||
bodySpec.back,
|
||||
bodySpec.selection,
|
||||
bodySpec.hidden,
|
||||
bodySpec.zOrder //
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Down Shadow ...
|
||||
if (drawShadows)
|
||||
{
|
||||
//
|
||||
string downShadowTag = mTag + "|DS|";
|
||||
|
||||
XDrawSpecifications spec = config.lowStyle;
|
||||
|
||||
//
|
||||
// Check if Object Exists Delete it ...
|
||||
bool isExists = IsDrawExists(
|
||||
downShadowTag,
|
||||
chartId,
|
||||
subWindow //
|
||||
);
|
||||
|
||||
//
|
||||
bool canDraw = !isExists || (isExists && update);
|
||||
|
||||
//
|
||||
if (isExists && canDraw)
|
||||
{
|
||||
//
|
||||
DeleteRectangle(
|
||||
chartId,
|
||||
downShadowTag //
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
if (canDraw)
|
||||
{
|
||||
//
|
||||
// New ...
|
||||
DrawRectangle(
|
||||
chartId,
|
||||
downShadowTag,
|
||||
subWindow,
|
||||
time,
|
||||
downPrice,
|
||||
cTime,
|
||||
downPrice + downShadowSize,
|
||||
spec.clr,
|
||||
spec.style,
|
||||
spec.width,
|
||||
spec.fill,
|
||||
spec.back,
|
||||
spec.selection,
|
||||
spec.hidden,
|
||||
spec.zOrder //
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
|
||||
//
|
||||
// Prepare Signal ...
|
||||
void PrepareConditionsSignal(X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
if (!conditions.hasSignal)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
bool isLong = IsLong(conditions.signal.type);
|
||||
|
||||
//
|
||||
// Check Calculate TP ...
|
||||
if (
|
||||
conditions.signal.sl > 0 &&
|
||||
conditions.signal.tp <= 0 &&
|
||||
conditions.signal.r2r > 0 &&
|
||||
conditions.signal.entry > 0)
|
||||
{
|
||||
//
|
||||
double riskPrice = MathAbs(conditions.signal.entry - conditions.signal.sl);
|
||||
double riskPoint = PriceToPoint(
|
||||
conditions.signal.symbol,
|
||||
riskPrice);
|
||||
double rewardPoint = riskPoint * conditions.signal.r2r;
|
||||
double rewardPrice = PointToPrice(
|
||||
conditions.signal.symbol,
|
||||
rewardPoint);
|
||||
|
||||
//
|
||||
double tp =
|
||||
isLong
|
||||
? conditions.signal.entry + rewardPrice
|
||||
: conditions.signal.entry - rewardPrice;
|
||||
|
||||
//
|
||||
conditions.signal.tp = tp;
|
||||
}
|
||||
|
||||
//
|
||||
PrepareSignal(conditions.signal);
|
||||
|
||||
//
|
||||
conditions.signal.supportAndResistance = conditions.supportResistances;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Delete This ...
|
||||
void DrawConditionsSignalOnChart(X121MarketConditions &conditions)
|
||||
{
|
||||
//
|
||||
ulong mTicket = MathRand() * 100000;
|
||||
|
||||
//
|
||||
DrawSignal(
|
||||
mTicket,
|
||||
conditions.signal);
|
||||
|
||||
//
|
||||
DrawSupportResistance(
|
||||
0,
|
||||
conditions.supportResistances,
|
||||
conditions.signal.providers[0]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Catch Trend Changes ...
|
||||
if (ArraySize(trendStateBuffer) > 1)
|
||||
{
|
||||
//
|
||||
bool isChanged =
|
||||
trendStateBuffer[0] != trendStateBuffer[1] &&
|
||||
trendStateBuffer[0] != EMPTY_VALUE;
|
||||
if (isChanged)
|
||||
{
|
||||
//
|
||||
double to = trendBuffer[0];
|
||||
double from = trendBuffer[1];
|
||||
ENUM_XMAN_STATES state = (ENUM_XMAN_STATES)(int)trendStateBuffer[0];
|
||||
datetime at = iTime(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
barIndex);
|
||||
|
||||
//
|
||||
XValueChanged lastChange;
|
||||
bool hasLastChange = GetLastItem(
|
||||
lastChange,
|
||||
trendChanges);
|
||||
bool canAdd =
|
||||
!hasLastChange
|
||||
? true
|
||||
: lastChange.at < at;
|
||||
|
||||
//
|
||||
if (canAdd)
|
||||
{
|
||||
//
|
||||
// Here also we Free Trend Changes Sizes if
|
||||
// its More than 500 ...
|
||||
if (ArraySize(trendChanges) >= 500)
|
||||
{
|
||||
//
|
||||
// Retrieve Last Change model and add theme
|
||||
// again ...
|
||||
|
||||
//
|
||||
Clean(trendChanges);
|
||||
|
||||
//
|
||||
if (hasLastChange)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
lastChange,
|
||||
trendChanges);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
XValueChanged model;
|
||||
|
||||
//
|
||||
model.to = to;
|
||||
model.from = from;
|
||||
model.at = at;
|
||||
|
||||
//
|
||||
Add(
|
||||
model,
|
||||
trendChanges);
|
||||
|
||||
// //
|
||||
// LogMessage(
|
||||
// "Trend Changed On: " + ToString(trendChangeddOn) +
|
||||
// "\n state: " + EnumToString(state) +
|
||||
// "\n from: " + ToString(lastTrend) +
|
||||
// "\n to: " + ToString(trend) +
|
||||
// "\n"
|
||||
// //
|
||||
// );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
Copy(
|
||||
trendChanges,
|
||||
result.trendChanges);
|
||||
ArraySetAsSeries(
|
||||
result.trendChanges,
|
||||
true);
|
||||
|
||||
//
|
||||
// Catch Peaks Changes ...
|
||||
if (ArraySize(peaksBuffer) > 1)
|
||||
{
|
||||
//
|
||||
bool isPeakChanged =
|
||||
peaksBuffer[0] != peaksBuffer[1] &&
|
||||
peaksBuffer[0] != EMPTY_VALUE;
|
||||
if (isPeakChanged)
|
||||
{
|
||||
//
|
||||
double peak = peaksBuffer[0];
|
||||
double lastPeak = peaksBuffer[1];
|
||||
|
||||
//
|
||||
datetime at = iTime(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
barIndex);
|
||||
|
||||
//
|
||||
XValueChanged lastChange;
|
||||
bool hasLastChange = GetLastItem(
|
||||
lastChange,
|
||||
peakChanges);
|
||||
bool canAdd =
|
||||
!hasLastChange
|
||||
? true
|
||||
: lastChange.at < at;
|
||||
|
||||
//
|
||||
if (canAdd)
|
||||
{
|
||||
//
|
||||
// Here also we Free Trend Changes Sizes if
|
||||
// its More than 500 ...
|
||||
if (ArraySize(peakChanges) >= 500)
|
||||
{
|
||||
//
|
||||
// Retrieve Last Change model and add theme
|
||||
// again ...
|
||||
|
||||
//
|
||||
Clean(peakChanges);
|
||||
|
||||
//
|
||||
if (hasLastChange)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
lastChange,
|
||||
peakChanges);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
XValueChanged model;
|
||||
|
||||
//
|
||||
model.to = peak;
|
||||
model.from = lastPeak;
|
||||
model.at = at;
|
||||
|
||||
//
|
||||
Add(
|
||||
model,
|
||||
peakChanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
Copy(
|
||||
peakChanges,
|
||||
result.peakChanges);
|
||||
ArraySetAsSeries(
|
||||
result.peakChanges,
|
||||
true);
|
||||
|
||||
//
|
||||
// Catch Vales Changes ...
|
||||
if (ArraySize(valesBuffer) > 1)
|
||||
{
|
||||
//
|
||||
bool isChanged =
|
||||
valesBuffer[0] != valesBuffer[1] &&
|
||||
valesBuffer[0] != EMPTY_VALUE;
|
||||
if (isChanged)
|
||||
{
|
||||
//
|
||||
double peak = peaksBuffer[0];
|
||||
double lastPeak = peaksBuffer[1];
|
||||
|
||||
//
|
||||
datetime at = iTime(
|
||||
mSymbol,
|
||||
mPeriod,
|
||||
barIndex);
|
||||
|
||||
//
|
||||
XValueChanged lastChange;
|
||||
bool hasLastChange = GetLastItem(
|
||||
lastChange,
|
||||
peakChanges);
|
||||
bool canAdd =
|
||||
!hasLastChange
|
||||
? true
|
||||
: lastChange.at < at;
|
||||
|
||||
//
|
||||
if (canAdd)
|
||||
{
|
||||
//
|
||||
// Here also we Free Trend Changes Sizes if
|
||||
// its More than 500 ...
|
||||
if (ArraySize(peakChanges) >= 500)
|
||||
{
|
||||
//
|
||||
// Retrieve Last Change model and add theme
|
||||
// again ...
|
||||
|
||||
//
|
||||
Clean(peakChanges);
|
||||
|
||||
//
|
||||
if (hasLastChange)
|
||||
{
|
||||
//
|
||||
Add(
|
||||
lastChange,
|
||||
peakChanges);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
XValueChanged model;
|
||||
|
||||
//
|
||||
model.to = peak;
|
||||
model.from = lastPeak;
|
||||
model.at = at;
|
||||
|
||||
//
|
||||
Add(
|
||||
model,
|
||||
peakChanges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
Copy(
|
||||
peakChanges,
|
||||
result.peakChanges);
|
||||
ArraySetAsSeries(
|
||||
result.peakChanges,
|
||||
true);
|
||||
@@ -5085,3 +5085,104 @@ for (int i = 1; i < pivotsCount - 1; i++)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
double lastMax = 0;
|
||||
while (ArraySize(tmp) > 0)
|
||||
{
|
||||
//
|
||||
int maxIDX = ArrayMaximum(tmp);
|
||||
if (maxIDX <= -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
double max = tmp[maxIDX];
|
||||
double maxLesser = FindLesserThanValue(
|
||||
max,
|
||||
pivots,
|
||||
true);
|
||||
if (maxLesser == -1)
|
||||
{
|
||||
maxLesser = boundaryMin;
|
||||
}
|
||||
|
||||
//
|
||||
if (price < max && price > maxLesser)
|
||||
{
|
||||
//
|
||||
if (longSupport)
|
||||
{
|
||||
LogMessage("Create Long Max Breakeout Signal");
|
||||
}
|
||||
|
||||
//
|
||||
if (shortSupport) {
|
||||
LogMessage("Create Max Short Breakeout Signals");
|
||||
}
|
||||
}
|
||||
|
||||
// //
|
||||
// // Check Max ...
|
||||
// if (
|
||||
// price < max &&
|
||||
// (lastMax == 0 || (lastMax > 0 && price > lastMax)))
|
||||
// {
|
||||
// //
|
||||
// // Create Long for Aboves ...
|
||||
// if (longSupport)
|
||||
// {
|
||||
// //
|
||||
// type = POSITION_TYPE_BUY;
|
||||
// mode = X_ORDER_MODE_STOP;
|
||||
|
||||
// //
|
||||
// tp = tpValue == 0 && placeTP
|
||||
// ? lastMax
|
||||
// : tpValue;
|
||||
// entry = max;
|
||||
// sl = slValue == 0 && placeSL
|
||||
// ? maxLesser
|
||||
// : slValue;
|
||||
|
||||
// //
|
||||
// signal = CreateSignal(
|
||||
// symbol,
|
||||
// period,
|
||||
// type,
|
||||
// mode,
|
||||
// entry,
|
||||
// volume,
|
||||
// tp,
|
||||
// sl);
|
||||
|
||||
// //
|
||||
// Add(
|
||||
// signal,
|
||||
// signals);
|
||||
// }
|
||||
|
||||
//
|
||||
// Short for Belows ...
|
||||
|
||||
//
|
||||
// Long for Below Ups ...
|
||||
// }
|
||||
|
||||
//
|
||||
LogMessage("MAX: " + ToString(max));
|
||||
LogMessage("MAX Lesser: " + ToString(maxLesser));
|
||||
LogMessage("MAX Last: " + ToString(lastMax));
|
||||
|
||||
//
|
||||
Remove(
|
||||
max,
|
||||
tmp //
|
||||
);
|
||||
lastMax = max;
|
||||
}
|
||||
|
||||
//
|
||||
LogMessage("FFFF");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user